[英]How to animate fill opacity of a context in HTML5 canvas?
我怎樣才能動畫fill
上下文的不透明性(或添加淡入效果)的HTML畫布?
例如,在下面的示例中, 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>
您可以使用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
,但是我相信這已經成為過去。 有關更多信息,請參見本文 。
Polyfill:
(這是填充工具的改良版這一個 ,由保羅·愛爾蘭創建)
;(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);
您不能像使用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
以來的毫秒數。
如果要進行不同的過渡(例如,移出),則需要調整不透明度的增加量作為時間的因素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.