html - Scratch off reveal with HTML5 canvas -- 添加淡

我按照本教程在我的网站上创建了一个“绘制显示”效果:http://thenewcode.com/1120/Scratch-Off-Reveal-with-HTML5-Canvas .我希望“正面”图像是这个 video asset ,而且我还希望“显示”路径(或绘制的每个点)在绘制后的设定时间后淡出(就像鼠标后面的淡出轨迹),但不知道该怎么做。我尝试在每次 drawDot() 调用后重新绘制 img,但这似乎只是绘制了整个“显示”图像。谢谢!

编辑:添加视频在“前面”的请求

最佳答案

最后,这是我的解决方案:

每绘制一个点,设置一个clearDot:

setClearDot(brushPos.x, brushPos.y, CLEARDOT_DELAY_MILLISECONDS)

将在设定的延迟后绘制:

function setClearDot(x, y, delay) {
  setTimeout(() => {
    drawClearDot(x, y)
  }, delay);
}

画一个空心点:

function drawClearDot(x, y) {
  const squareX = x - brushRadius
  const squareY = y - brushRadius
  const squareSize = brushRadius * 2
  bridgeCanvas.globalCompositeOperation = "source-over";
  bridgeCanvas.drawImage(img, squareX, squareY, squareSize, squareSize, squareX, squareY, squareSize, squareSize);
}

希望正方形足够好,首先两个变量获取点的坐标并将它们变成正方形的左上角。 Composite operation必须改回正常(这花了我很多时间才弄明白……相信我,这很痛苦)。那我们draw part of the coloured image回来。

这是我的解决方案的工作片段:

CLEARDOT_DELAY_MILLISECONDS = 1500;

var bridge = document.getElementById("bridge"),
  bridgeCanvas = bridge.getContext('2d'),
  brushRadius = (bridge.width / 100) * 5,
  img = new Image();

if (brushRadius < 50) {
  brushRadius = 50
}

img.onload = function() {
  bridgeCanvas.drawImage(img, 0, 0, bridge.width, bridge.height);
}
img.loc = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/';
img.filename = 'calgary-bridge-2013.jpg';
if (window.devicePixelRatio >= 2) {
  var nameParts = img.filename.split('.');
  img.src = img.loc + nameParts[0] + "-2x" + "." + nameParts[1];
} else {
  img.src = img.loc + img.filename;
}

function detectLeftButton(event) {
  if ('buttons' in event) {
    return event.buttons === 1;
  } else if ('which' in event) {
    return event.which === 1;
  } else {
    return event.button === 1;
  }
}

function getBrushPos(xRef, yRef) {
  var bridgeRect = bridge.getBoundingClientRect();
  return {
    x: Math.floor((xRef - bridgeRect.left) / (bridgeRect.right - bridgeRect.left) * bridge.width),
    y: Math.floor((yRef - bridgeRect.top) / (bridgeRect.bottom - bridgeRect.top) * bridge.height)
  };
}

function drawDot(mouseX, mouseY) {
  bridgeCanvas.beginPath();
  bridgeCanvas.arc(mouseX, mouseY, brushRadius, 0, 2 * Math.PI, true);
  bridgeCanvas.fillStyle = '#000';
  bridgeCanvas.globalCompositeOperation = "destination-out";
  bridgeCanvas.fill();
}

function drawClearDot(x, y) {
  const squareX = x - brushRadius
  const squareY = y - brushRadius
  const squareSize = brushRadius * 2
  bridgeCanvas.globalCompositeOperation = "source-over";
  bridgeCanvas.drawImage(img, squareX, squareY, squareSize, squareSize, squareX, squareY, squareSize, squareSize);
}

bridge.addEventListener("mousemove", function(e) {
  var brushPos = getBrushPos(e.clientX, e.clientY);
  var leftBut = detectLeftButton(e);
  if (leftBut) {
    drawDot(brushPos.x, brushPos.y);
    setClearDot(brushPos.x, brushPos.y, CLEARDOT_DELAY_MILLISECONDS)
  }
}, false);

bridge.addEventListener("touchmove", function(e) {
  e.preventDefault();
  var touch = e.targetTouches[0];
  if (touch) {
    var brushPos = getBrushPos(touch.pageX, touch.pageY);
    drawDot(brushPos.x, brushPos.y);
    setClearDot(brushPos.x, brushPos.y, CLEARDOT_DELAY_MILLISECONDS)
  }
}, false);

function setClearDot(x, y, delay) {
  setTimeout(() => {
    drawClearDot(x, y)
  }, delay);
}
body {
  margin: 0;
}

#bridge {
  display: block;
  margin: 0 auto;
  background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/calgary-bridge-1943.jpg');
  background-image: -webkit-image-set(url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/calgary-bridge-1943.jpg') 1x, url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/calgary-bridge-1943-2x.jpg') 2x);
  background-size: cover;
  width: 100%;
  max-width: 750px;
  height: auto;
  cursor: crosshair;
  cursor: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/circular-cursor.png) 53 53, crosshair;
}

#bridgeContainer {
  text-align: center;
  font-family: Avenir, sans-serif;
}

#bridgeContainer figcaption {
  margin-top: 2rem;
}
<figure id="bridgeContainer">
  <canvas id="bridge" width="750" height="465"></canvas>
  <figcaption>Downtown Calgary in 2013 and 1943; mouse down or touch on photo to reveal</figcaption>
</figure>

这比我愿意承认的时间要长

关于html - Scratch off reveal with HTML5 canvas -- 添加淡出元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71669273/

相关文章:

python - 等于运算符与元组 : 'a' , 'b' == ('a' , 'b' )

javascript - react : Difference between side effec

f# - F# 的 C# 公共(public)成员初始值设定项是否有任何替代方案?

aws-lambda - SQS 到 ECS (Fargate) 或 SQS 到 Lambda 到

google-forms - 您可以向 google forms api 提交 Restful 请求

ethereum - 扁平化智能联系人是否会降低部署成本?

sql - 如何删除 SQL 中的重复行(Clickhouse)?

中的特">c# - 我怎样才能得到所有字符串 "greater"的列表而不是 List 中的特

python - 连接到与登录到 google colab 的不同的 google 驱动器

reactjs - 在函数或类中使用 `useDispatch` 可以吗?