是否可以告诉我如何在HTML Canvas中为上下文的fill
不透明度添加动画效果(或添加淡入淡出效果)?
例如,在以下示例中,ctx.fillStyle
填充不透明度设置为0
,如何将其设置为1
?
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.fillStyle = 'rgba(255, 165, 0, 0)';
ctx.rect(20, 20, 150, 100);
ctx.fill();

<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
&#13;
答案 0 :(得分:1)
您可以使用window.requestAnimationFrame
:
var
/* Save the canvas' context. */
ctx = document.getElementById("myCanvas").getContext("2d"),
/* The starting opacity. */
opacity = 0,
/* The duration of the animation in milliseconds. */
duration = 500,
/* Cache the starting time in milliseconds since page load. */
past = performance.now();
/* The animation function. */
function animate(present) {
/* Find the difference between the previous and current times. */
var step = present - past;
/* Set the present time to past. */
past = present;
/* Increment the opacity by a linear step. */
opacity += step / duration;
/* Create the shape. */
ctx.beginPath();
ctx.fillStyle = "rgba(255, 165, 0, " + opacity + ")";
ctx.clearRect(20, 20, 150, 100);
ctx.rect(20, 20, 150, 100);
ctx.fill();
/* Continue the animation until the opacity is 1. */
if (opacity < 1) window.requestAnimationFrame(animate);
}
/* Start the animation. */
window.requestAnimationFrame(animate);
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
备注:强>
您可以通过将持续时间更改为最适合您的时间来调整动画的速度。该值以毫秒为单位。
在animate
的每次调用中,我们使用clearRect
清除画布,以避免在另一个上面创建一个形状,以便不透明度按预期增加。
不同的浏览器以不同的方式处理requestAnimationFrame
,因此要实现一致的跨浏览器结果,您必须使用一个解决浏览器之间差异的polyfill。我在下面提供了一个。
继续动画的另一种方法是使用setInterval
,但我相信这已成为过去。有关详情,请参阅this article。
<强>填充工具:强>
(此polyfill是this one的修改版本,由Paul Irish创建)
;(function (prefices, lastTime) {
/* Iterate over every browser-engine-specific prefix. */
for (var i = 0; i < prefices.length && !window.requestAnimationFrame; i++) {
/* Normalise requestAnimationFrame and cancelAnimationFrame. */
window.requestAnimationFrame = window[prefices[i] + "RequestAnimationFrame"];
window.cancelAnimationFrame =
window[prefices[i] + "CancelAnimationFrame"] ||
window[prefices[i] + "CancelRequestAnimationFrame"];
}
/* If requestAnimationFrame is not defined use a custom function. */
window.requestAnimationFrame = window.requestAnimationFrame
|| function (callback, element) {
var
/* Save the present time and the time between it and the last time. */
now = Date.now() || new Date().getTime(),
timeToCall = Math.max(0, 16 - (now - lastTime)),
/* Save the id of the timeout. */
id = window.setTimeout(function () {
/* Call the callback function passing the time passed & the element. */
callback(now + timeToCall, element);
}, timeToCall);
/* Update the last time with the present time plus the time in between. */
lastTime = now + timeToCall;
/* Return the id of the timeout. */
return id;
};
/* If cancelAnimationFrame is not defined set it to clear the timeout. */
window.cancelAnimationFrame = window.cancelAnimationFrame || function (id) {
clearTimeout(id);
}
})(["webkit", "moz", "ms", "o"], 0);
答案 1 :(得分:1)
你不能像使用CSS一样“动画”。使用画布,你会画出灵感,所以你必须自己做数学和计时。
这是从一个值到另一个值的简单线性过程。
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
const duration = 1000; // ms
const step = 10; // ms
let opacity = 0;
function draw() {
if (opacity == 1) return;
opacity += (step / duration);
ctx.clearRect(20, 20, 150, 100);
ctx.beginPath();
ctx.fillStyle = `rgba(255, 165, 0, ${opacity})`;
ctx.rect(20, 20, 150, 100);
ctx.fill();
setTimeout(draw, step);
}
draw();
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
基本上,您可以跟踪当前的不透明度,您希望它的持续时间以及您希望它触发的频率。然后,按照step
到duration
的百分比增加不透明度并重新绘制。
另外,既然你正在处理不透明度,你必须记住每一步都要清除它,否则它会很快变暗。
你也可以使用window.requestAnimationFrame
,但是(如果你想控制速度),你需要跟踪时间而不是步骤:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
const duration = 1000; // ms
let lastTime = performance.now();
let opacity = 0;
function draw(now) {
if (opacity >= 1) return;
opacity += ((now - lastTime) / duration);
lastTime = now;
ctx.clearRect(20, 20, 150, 100);
ctx.beginPath();
ctx.fillStyle = `rgba(255, 165, 0, ${opacity})`;
ctx.rect(20, 20, 150, 100);
ctx.fill();
window.requestAnimationFrame(draw);
}
draw(lastTime);
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
现在注意而不是opacity += step / duration
,我们使用自上次更新opacity += (now - lastTime) / duration
以来的毫秒数。
如果你想进行不同的过渡(如步入式输出),你需要调整不透明度增加量作为时间因素。