<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # HTML5 畫布中的動畫 > 原文: [https://zetcode.com/gfx/html5canvas/animation/](https://zetcode.com/gfx/html5canvas/animation/) 在本章中,我們將在 HTML5 `canvas`中創建動畫。 動畫是連續的圖像,使人產生了運動的幻覺。 但是,動畫不僅限于運動。 隨時間改變對象的背景也被視為動畫。 在 HTML5 `canvas`中創建動畫的函數有以下三個: * `setInterval(function, delay)` * `setTimeut(function, delay)` * `requestAnimationFrame(callback)` `setInterval()`函數每隔延遲毫秒重復執行一次傳遞的函數。 `setTimeout()`以毫秒為單位執行指定的功能。 為了創建動畫,從執行的函數中調用`setTimeout()`。 `requestAnimationFrame()`函數允許瀏覽器在下一次重繪之前調用指定的函數來更新動畫。 瀏覽器進行了一些優化。 ## 沿曲線移動 在第一個動畫中,對象沿曲線移動。 `move_along_curve.html` ```js <!DOCTYPE html> <html> <head> <title>HTML5 canvas move along curve</title> <style> canvas { border: 1px solid #bbbbbb } </style> <script> var canvas; var ctx; var x = 20; var y = 80; const DELAY = 30; const RADIUS = 10; function init() { canvas = document.getElementById('myCanvas'); ctx = canvas.getContext('2d'); setInterval(move_ball, DELAY); } function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath(); ctx.fillStyle = "cadetblue"; ctx.arc(x, y, RADIUS, 0, 2*Math.PI); ctx.fill(); } function move_ball() { x += 1; if (x > canvas.width + RADIUS) { x = 0; } y = Math.sin(x/32)*30 + 80; draw(); } </script> </head> <body onload="init();"> <canvas id="myCanvas" width="350" height="150"> </canvas> </body> </html> ``` 該示例沿正弦曲線移動一個圓。 圓圈移過畫布的末端后,它再次出現在左側。 ```js setInterval(move_ball, DELAY); ``` `setInterval()`函數使`move_ball()`函數每`DELAY` ms 調用一次。 ```js function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath(); ctx.fillStyle = "cadetblue"; ctx.arc(x, y, RADIUS, 0, 2*Math.PI); ctx.fill(); } ``` `draw()`方法使用`clearRect()`方法清除畫布,并繪制具有更新的 x 和 y 坐標的新圓。 ```js function move_ball() { x += 1; if (x > canvas.width + RADIUS) { x = 0; } y = Math.sin(x/32)*30 + 80; draw(); } ``` 在`move_ball()`函數中,我們更新圓心的 x 和 y 坐標。 我們檢查球是否已通過畫布的右邊緣,然后調用`draw()`方法重繪畫布。 ## 淡出 淡出是改變對象狀態的動畫。 這是一種過渡動畫。 `fading_out.html` ```js <!DOCTYPE html> <html> <head> <style> canvas {border: 1px solid #bbbbbb} </style> <title>HTML5 canvas fading out</title> <script> var canvas; var ctx; var alpha = 1; var rx = 20; var ry = 20; var rw = 120; var rh = 80; const DELAY = 20; function init() { canvas = document.getElementById('myCanvas'); ctx = canvas.getContext('2d'); canvas.addEventListener("click", onClicked); ctx.fillRect(rx, ry, rw, rh) } function onClicked(e) { var cx = e.x; var cy = e.y; if (cx >= rx && cx <= rx + rw && cy >= ry && cy <= ry + rh) { fadeout(); } } function fadeout() { if (alpha < 0) { canvas.removeEventListener("click", onClicked); ctx.globalAlpha = 1; ctx.fillStyle = 'white'; ctx.fillRect(rx, ry, rw, rh); return; } ctx.clearRect(rx, ry, rw, rh); ctx.globalAlpha = alpha; ctx.fillRect(rx, ry, rw, rh) alpha -= 0.01; setTimeout(fadeout, DELAY); } </script> </head> <body onload="init();"> <canvas id="myCanvas" width="350" height="250"> </canvas> </body> </html> ``` 有一個矩形對象。 當我們單擊矩形時,它開始淡出。 ```js canvas.addEventListener("click", onClicked); ``` 通過`addEventListener()`方法將`click`監聽器添加到畫布。 再次單擊鼠標后,將調用`onClicked()`函數。 ```js ctx.fillRect(rx, ry, rw, rh) ``` 最初,在畫布上以默認的黑色填充繪制了一個矩形。 ```js function onClicked(e) { var cx = e.x; var cy = e.y; if (cx >= rx && cx <= rx + rw && cy >= ry && cy <= ry + rh) { fadeout(); } } ``` 在`onClicked()`函數內,我們可以計算出鼠標單擊的 x 和 y 坐標。 我們將鼠標坐標與矩形的外部邊界進行比較,如果鼠標坐標落在矩形的區域內,則將調用`fadeout()`方法。 ```js if (alpha < 0) { canvas.removeEventListener("click", onClicked); ctx.globalAlpha = 1; ctx.fillStyle = 'white'; ctx.fillRect(rx, ry, rw, rh); return; } ``` 當矩形完全透明時,我們將移走監聽器并以不透明的白色填充該區域。 `return`語句結束`fadeout()`函數的遞歸調用。 ```js ctx.clearRect(rx, ry, rw, rh); ctx.globalAlpha = alpha; ctx.fillRect(rx, ry, rw, rh) ``` 矩形的區域被清除并填充有更新的 alpha 狀態。 ```js alpha -= 0.01; ``` `alpha`值減小一小部分。 ```js setTimeout(fadeout, DELAY); ``` 在`DELAY` ms 之后,從其內部調用`fadeout()`方法。 這種做法稱為遞歸。 ## 泡泡 以下示例受到 Java 2D 演示示例的啟發。 `bubbles.html` ```js <!DOCTYPE html> <html> <head> <title>HTML5 canvas bubbles</title> <style> canvas { border: 1px solid #bbb; background: #000; } </style> <script> var cols = ["blue", "cadetblue", "green", "orange", "red", "yellow", "gray", "white"]; const NUMBER_OF_CIRCLES = 35; const DELAY = 30; var maxSize; var canvas; var ctx; var circles; function Circle(x, y, r, c) { this.x = x; this.y = y; this.r = r; this.c = c; } function init() { canvas = document.getElementById('myCanvas'); ctx = canvas.getContext('2d'); circles = new Array(NUMBER_OF_CIRCLES); initCircles(); doStep(); } function initCircles() { var w = canvas.width; var h = canvas.height; maxSize = w / 10; for (var i = 0; i < circles.length; i++) { var rc = getRandomCoordinates(); var r = Math.floor(maxSize * Math.random()); var c = cols[Math.floor(Math.random()*cols.length)] circles[i] = new Circle(rc[0], rc[1], r, c); } } function doStep() { for (var i = 0; i < circles.length; i++) { var c = circles[i]; c.r += 1; if (c.r > maxSize) { var rc = getRandomCoordinates(); c.x = rc[0]; c.y = rc[1]; c.r = 1; } } drawCircles(); setTimeout(doStep, DELAY); } function getRandomCoordinates() { var w = canvas.width; var h = canvas.height; var x = Math.floor(Math.random() * (w - (maxSize / 2))); var y = Math.floor(Math.random() * (h - (maxSize / 2))); return [x, y]; } function drawCircles() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < circles.length; i++) { ctx.beginPath(); ctx.lineWidth = 2.5; var c = circles[i]; ctx.strokeStyle = c.c; ctx.arc(c.x, c.y, c.r, 0, 2*Math.PI); ctx.stroke(); } } </script> </head> <body onload="init();"> <canvas id="myCanvas" width="350" height="250"> </canvas> </body> </html> ``` 在該示例中,有越來越多的彩色氣泡在屏幕上隨機出現和消失。 ```js var cols = ["blue", "cadetblue", "green", "orange", "red", "yellow", "gray", "white"]; ``` 這些顏色用于繪制氣泡。 ```js function Circle(x, y, r, c) { this.x = x; this.y = y; this.r = r; this.c = c; } ``` 這是`Circle`對象的構造器。 除了 x 和 y 坐標以及半徑之外,它還包含顏色值的屬性。 ```js circles = new Array(NUMBER_OF_CIRCLES); ``` `circles`數組用于容納圓形對象。 ```js for (var i = 0; i < circles.length; i++) { var rc = getRandomCoordinates(); var r = Math.floor(maxSize * Math.random()); var c = cols[Math.floor(Math.random()*cols.length)] circles[i] = new Circle(rc[0], rc[1], r, c); } ``` `circles`數組用圓圈填充。 我們計算隨機坐標,隨機初始半徑和隨機顏色值。 ```js function doStep() { ``` `doStep()`表示程序的動畫周期。 ```js for (var i = 0; i < circles.length; i++) { var c = circles[i]; c.r += 1; if (c.r > maxSize) { var rc = getRandomCoordinates(); c.x = rc[0]; c.y = rc[1]; c.r = 1; } } ``` 我們遍歷`circles`數組并增加每個圓的半徑。 當圓達到最大大小時,它會隨機重新定位并最小化。 ```js setTimeout(doStep, DELAY); ``` `setTimeout()`方法用于創建動畫。 您可能需要調整`DELAY`值以適合您的硬件。 ```js function drawCircles() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < circles.length; i++) { ctx.beginPath(); ctx.lineWidth = 2.5; var c = circles[i]; ctx.strokeStyle = c.c; ctx.arc(c.x, c.y, c.r, 0, 2*Math.PI); ctx.stroke(); } } ``` `drawCircles()`函數清除畫布并繪制數組中的所有圓圈。 ## 星空 下面的示例創建一個星空動畫。 `starfield.html` ```js <!DOCTYPE html> <html> <head> <title>HTML5 canvas star field</title> <script> var canvas_w; var canvas_h; var canvas; var ctx; var layer1; var layer2; var layer3; const DELAY = 20; const N_STARS = 60; const SPEED1 = 3; const SPEED2 = 2; const SPEED3 = 1; function init() { canvas = document.getElementById("myCanvas"); ctx = canvas.getContext("2d"); canvas_w = canvas.width; canvas_h = canvas.height; layer1 = new layer(N_STARS, SPEED1, "#ffffff"); layer2 = new layer(N_STARS, SPEED2, "#dddddd"); layer3 = new layer(N_STARS, SPEED3, "#999999"); setTimeout("drawLayers()", DELAY); } function star() { this.x = Math.floor(Math.random()*canvas_w); this.y = Math.floor(Math.random()*canvas_h); this.move = function(speed) { this.y = this.y + speed; if (this.y > canvas_h) { this.y = 0; this.x = Math.floor(Math.random()*canvas_w); } } this.draw = function(col) { ctx.fillStyle = col; ctx.fillRect(this.x, this.y , 1, 1); } } function layer(n, sp, col) { this.n = n; this.sp = sp; this.col = col; this.stars = new Array(this.n); for (var i=0; i < this.n; i++) { this.stars[i] = new star(); } this.moveLayer = function() { for (var i=0; i < this.n; i++) { this.stars[i].move(this.sp); } } this.drawLayer = function() { for (var i=0; i < this.n; i++) { this.stars[i].draw(this.col); } } } function drawLayers() { ctx.fillStyle = '#000000'; ctx.fillRect(0, 0, canvas_w, canvas_h); layer1.moveLayer(); layer2.moveLayer(); layer3.moveLayer(); layer1.drawLayer(); layer2.drawLayer(); layer3.drawLayer(); setTimeout("drawLayers()", DELAY); } </script> </head> <body onload="init();"> <canvas id="myCanvas" width="800" height="600"> </canvas> </body> </html> ``` 通過產生三個不同的圖層來創建星空動畫。 每層由具有不同速度和顏色陰影的星星(小點)組成。 前層的星星更亮,移動速度更快,背面的星星更暗,移動速度更慢。 ```js layer1 = new layer(N_STARS, SPEED1, "#ffffff"); layer2 = new layer(N_STARS, SPEED2, "#dddddd"); layer3 = new layer(N_STARS, SPEED3, "#999999"); ``` 創建了三層星星。 它們具有不同的速度和顏色陰影。 ```js function star() { this.x = Math.floor(Math.random()*canvas_w); this.y = Math.floor(Math.random()*canvas_h); ... ``` 創建星后,它會被賦予隨機坐標。 ```js this.move = function(speed) { this.y = this.y + speed; if (this.y > canvas_h) { this.y = 0; this.x = Math.floor(Math.random()*canvas_w); } } ``` `move()`方法移動星星; 它增加了它的 y 坐標。 ```js this.draw = function(col) { ctx.fillStyle = col; ctx.fillRect(this.x, this.y , 1, 1); } ``` `draw()`方法在畫布上繪制星星。 它使用`fillRect()`方法以給定的顏色繪制一個小矩形。 ```js function layer(n, sp, col) { this.n = n; this.sp = sp; this.col = col; this.stars = new Array(this.n); ... ``` 一層是具有給定速度和顏色陰影的`n`星的集合。 星星存儲在`stars`數組中。 ```js for (var i=0; i < this.n; i++) { this.stars[i] = new star(); } ``` 創建圖層后,`stars`數組將填充星形對象。 ```js this.moveLayer = function() { for (var i=0; i < this.n; i++) { this.stars[i].move(this.sp); } } ``` `moveLayer()`方法遍歷星星數組,并調用每個星星的`move()`方法。 ```js this.drawLayer = function() { for (var i=0; i < this.n; i++) { this.stars[i].draw(this.col); } } ``` 同樣,`drawLayer()`方法調用每個星星的`draw()`方法。 ```js function drawLayers() { ctx.fillStyle = '#000000'; ctx.fillRect(0, 0, canvas_w, canvas_h); layer1.moveLayer(); layer2.moveLayer(); layer3.moveLayer(); layer1.drawLayer(); layer2.drawLayer(); layer3.drawLayer(); setTimeout("drawLayers()", DELAY); } ``` `drawLayers()`函數可移動每一層的星星并將其繪制在畫布上。 它在`DELAY` ms 之后調用自己,從而創建動畫。 在 HTML5 畫布教程的這一章中,我們介紹了動畫。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看