簡體   English   中英

如何為HTML5 canvas中的上下文填充不透明度動畫?

[英]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> 


筆記:

  1. 您可以通過將持續時間更改為最適合自己的時間來調整動畫的速度。 該值以毫秒為單位。

  2. 每次調用animate ,我們都使用clearRect清除畫布,以避免在另一個形狀上創建一個形狀,從而使不透明度按預期增加。

  3. 不同的瀏覽器對requestAnimationFrame處理方式不同,因此,要獲得一致的跨瀏覽器結果,您必須使用考慮到瀏覽器之間差異的polyfill。 我在下面提供了一個。

  4. 進行動畫處理的另一種方法是使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM