H5 Canvas | 畫布中變量做用域與setInterval方法同步執行探究

Demo - 隨機繪製圓環

實現思路:

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

實現方法:

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

<<index.html>>javascript

<!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的一刻 css

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

    在控制檯輸出狀況能夠看到,當起始位置爲全局變量時相互干擾的很是厲害,但由於step是局部變量,調用的是不一樣的副本,最後兩個圈均執行到了99。而且能夠看到控制檯中drawID是間隔出現的,對兩次setInterval方法輪流執行,也就形成了sAngle位置是跳躍的虛點。 html

       

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

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

       

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

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

    點擊button從新執行InitDraw();step=0; 從打印信息能夠看到兩個不一樣的setInterval方法對step變量相互干擾,直到step有機會到達99時中止繪圖。 瀏覽器

       

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

關於Context的另外一個測試:

在同一個畫布中調用獲取兩個Context,但經過輸出能夠看到每一個畫布只有一個對應的Contextdom

   

通過幾個Demo的分析獲得如下結論: 函數

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

遺留問題: 測試

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

相關文章
相關標籤/搜索