1. 程式人生 > >HTML5 | Canvas中變量作用域與setInterval()方法的影響

HTML5 | Canvas中變量作用域與setInterval()方法的影響

通過 value utf 出現 close span arc shadow cli

Demo - 隨機繪制圓環

實現思路:

  • 將一個圓環的繪制分成100份,setInterval()方法定義每隔時間n繪制一段新的,每份的開始路徑都是上一次的結束路徑,實現步進繪制。
  • 通過Math.random(),隨機生成圓的坐標半徑顏色。

實現方法:

  1. 定義畫布和聯系
  2. 設置步進屬性
  3. 設置隨機圓屬性(5個參數:xy,半徑,開始,結束,方向)
  4. 循環執行繪畫

<<index.html>>

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <style type="text/css">
    #canvas {
        border: 1px black solid;
    }
    
</style> </head> <body> <canvas id="canvas" width="1000" height="400">您的瀏覽器不支持canvas</canvas> <input type="button" onclick="InitDraw()" value="draw"> <script type="text/javascript"> function InitDraw() { var canvas = document.getElementById(‘canvas‘);
var ctx = canvas.getContext(‘2d‘); var ctx2 = canvas.getContext(‘2d‘); var step; // var sAngle; // var eAngle; var x, y, r; var add, stepTime, counterClockwise; // 步進屬性 step = 0; add = Math.PI * 2 / 100; stepTime = 20; // 隨機圓屬性
sAngle = 0; eAngle = sAngle + add; counterClockwise = false; x = Math.random() * 800 + 100; y = Math.random() * 200 + 100; r = Math.random() * 50 + 50; ctx.strokeStyle = "#" + (Math.random() * 0x1000000 << 0).toString(16); ctx.shadowColor = "#" + (Math.random() * 0x1000000 << 0).toString(16); console.log(ctx.strokeStyle); console.log(ctx2.strokeStyle); ctx.lineWidth = 1.0; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowBlur = 10; // 畫圓 var drawID = setInterval(Draw, stepTime); function Draw() { if (step < 100) { // 繪制路徑並畫 ctx.beginPath(); ctx.arc(x, y, r, sAngle, eAngle, counterClockwise); ctx.stroke(); ctx.closePath(); // 步進 sAngle = eAngle; eAngle += add; // console.log("drawID:" + drawID + ",step:" + step); // console.log(ctx.strokeStyle); step++; } else { clearInterval(drawID); } } } </script> </body> </html>

在不同的變量環境下出現了不同的情況:

  1. 全局變量:step, sAngle, eAngle , x, y, r;

    技術分享

    在執行繪圖過程中持續變化的參數是step,sAngle,eAngle,再次調用時回到函數InitDraw();重新定義六個全局變量以及畫筆樣式,則重新開始繪圖。上一個step和畫筆樣式都停留在按下button的一刻

    技術分享

  2. 全局變量:sAngle, eAngle; 局部變量:var step, x, y, r;

    技術分享

    在控制臺輸出情況可以看到,當起始位置為全局變量時相互幹擾的非常厲害,但因為step是局部變量,調用的是不同的副本,最後兩個圈均執行到了99。並且可以看到控制臺中drawID是間隔出現的,對兩次setInterval方法輪流執行,也就造成了sAngle位置是跳躍的虛點。

    技術分享

  3. 局部變量:var step ,sAngle, eAngle, x, y, r;

    技術分享

    但要註意的是在該示例中共用同一個畫布和聯系(ctx),在這裏畫筆的顏色和樣式被刷新成為新的。那麽應該如何在同一畫布中同時繪畫不同樣式?

    技術分享

  4. 全局變量:step; 局部變量:var sAngle, eAngle, x, y, r;

    技術分享

    在第二次點擊出現的圈繪到約半圈時停止

    點擊button重新執行InitDraw();step=0; 從打印信息可以看到兩個不同的setInterval方法對step變量相互幹擾,直到step有機會到達99時停止繪圖。

    技術分享

  5. ...一共64種變化,謹慎定義Canvas中的變量作用域

關於Context的另一個測試:

在同一個畫布中調用獲取兩個Context,但通過輸出可以看到每個畫布只有一個對應的Context

技術分享

經過幾個Demo的分析得到以下結論:

  • 在調用同一個function時候,私有變量互不相幹,會像C一樣得到不同的副本各自存值
  • CanvasContext樣式(strokeStyle/shadowColor/...)是針對該Canvas(畫布)唯一的,即
  • 如果同時調用setInterval方法,則輪流執行,1,2,1,2,1,2...以此類推
  • 謹慎使用setInterval方法,同時運行多個會導致相互幹擾

遺留問題:

  • 如何同時繪畫不同樣式?

技術分享

HTML5 | Canvas中變量作用域與setInterval()方法的影響