HTML5 canvas制作童年的回憶大風車


  今天看到一篇CSS3寫的大風車http://www.cnblogs.com/yaojaa/archive/2013/01/30/2882521.html,感覺CSS3太神奇了,這在以前用CSS是想都不敢想的。記得去年自己用canvas也寫過這樣的大風車,今天我打算用canvas制作一個一模一樣的,連速度都一致的大風車。

  大家請看下面兩張圖,你們看得出這兩張圖有什么區別嗎?哪張是CSS3寫的哪張是canvas寫的?

  下面就來介紹制作風車的過程。先上代碼吧:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <canvas id = "canvas" width="300" height="300"></canvas>

    <script>
        (function () {
            var Pinwheel = function (canvas, options) {
                this.canvas = document.getElementById(canvas);
                this.options = options;
            };
            Pinwheel.prototype = {
                constructor: Pinwheel,
                show: function () {
                    var canvas = this.canvas,//取得canvas元素
                            width = canvas.width,//canvas元素的寬度
                            height = canvas.height,//canvas元素的高度
                            color = this.options.color,//風車葉子的顏色
                            radius = this.options.radius,//整個風車的半徑
                            wheelRadius = this.options.wheelRadius,//風車葉子的半徑
                            part = this.options.part,//PI/2分成幾份
                            ctx = canvas.getContext("2d"),//獲取上下文
                            num = this.options.num,//葉子數量
                            center = {x: width / 2, y: height / 2},//繪圖區域的中心
                            point, //葉子圓心位置
                            start = 0,//繪制葉子的開始角
                            angle = 0,//start = angle
                            end = Math.PI,//繪制葉子的結束角
                            offset = Math.PI * (360 / num) / 180,//兩個相鄰葉子之間的角度
                            rotateAngle = offset / part;//每次旋轉的角度
//                    window.timer = setInterval(function () {
                        ctx.clearRect(0, 0, width, height);
                        for (var i = 0; i < num; i += 1) {
                            ctx.beginPath();//開始繪制葉子
                            var wheelGradient = ctx.createRadialGradient(center.x, center.y, 100, center.x, center.y, 0);//創建徑向漸變
                            wheelGradient.addColorStop(0, color[i]);//起始顏色
                            wheelGradient.addColorStop(1, "#000");//結束顏色
                            ctx.fillStyle = wheelGradient;//填充漸變樣式
                            point = {x: center.x + Math.cos(offset * i + angle) * radius, y: center.y + Math.sin(offset * i + angle) * radius};//葉子圓心位置
                            var x = start + offset * i;//繪制葉子的開始角
                            var y = end + offset * i;//繪制葉子的結束角
                            ctx.arc(point.x, point.y, wheelRadius, x, y, false);//繪制
                            ctx.fill();//填充
                            ctx.closePath();//結束繪制
                        }
                        ctx.beginPath();
                        var dotGradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, 40);
                        dotGradient.addColorStop(0, "#fff");
                        dotGradient.addColorStop(1, "#666");
                        ctx.fillStyle = dotGradient;
                        ctx.arc(center.x, center.y, 25, 0, 2 * Math.PI, false);
                        ctx.fill();
                        ctx.closePath();
                        angle += rotateAngle;
                        start = angle;
                        end = Math.PI + angle;
//                    }, 20)
                },
                hide: function () {
                    clearInterval(window.timer);
                }
            };

            var options = {
                num: 4,
                color: ["red", "yellow", "blue", "green"],
                radius: 50,
                wheelRadius: 50,
                part: 50
            };

            var a = new Pinwheel("canvas", options);
            a.show();
        }());
    </script>
</body>
</html>
View Code

首先,確定需要的各項參數:

var canvas = this.canvas,//取得canvas元素
width = canvas.width,//canvas元素的寬度
height = canvas.height,//canvas元素的高度
color = this.options.color,//風車葉子的顏色
radius = this.options.radius,//整個風車的半徑
wheelRadius = this.options.wheelRadius,//風車葉子的半徑
part = this.options.part,//PI/2分成幾份
ctx = canvas.getContext("2d"),//獲取上下文
num = this.options.num,//葉子數量
center = {x: width / 2, y: height / 2},//繪圖區域的中心
point, //葉子圓心位置
start = 0,//繪制葉子的開始角
angle = 0,//start = angle
end = Math.PI,//繪制葉子的結束角
offset = Math.PI * (360 / num) / 180,//兩個相鄰葉子之間的角度
rotateAngle = offset / part;//每次旋轉的角度

循環繪制每個葉子:

for (var i = 0; i < num; i += 1) {
  ctx.beginPath();//開始繪制葉子
  var wheelGradient = ctx.createRadialGradient(center.x, center.y, 100, center.x, center.y, 0);//創建徑向漸變
  wheelGradient.addColorStop(0, color[i]);//起始顏色
  wheelGradient.addColorStop(1, "#000");//結束顏色
  ctx.fillStyle = wheelGradient;//填充漸變樣式
  point = {x: center.x + Math.cos(offset * i + angle) * radius, y: center.y + Math.sin(offset * i + angle) * radius};//葉子圓心位置
  var x = start + offset * i;//繪制葉子的開始角
  var y = end + offset * i;//繪制葉子的結束角
  ctx.arc(point.x, point.y, wheelRadius, x, y, false);//繪制
  ctx.fill();//填充
  ctx.closePath();//結束繪制
}

繪制中間的大圓點:

ctx.beginPath();
var dotGradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, 40);
dotGradient.addColorStop(0, "#fff");
dotGradient.addColorStop(1, "#666");
ctx.fillStyle = dotGradient;
ctx.arc(center.x, center.y, 25, 0, 2 * Math.PI, false);
ctx.fill();
ctx.closePath();

  上面的代碼已經可以制作靜態的風車了,但是我們要做的是動態的,於是我們需要一個計時器。下面是計時器代碼:

  window.timer = setInterval(function () {
    ctx.clearRect(0, 0, width, height);//每次調用計時器需要重繪
    for (var i = 0; i < num; i += 1) {
      ctx.beginPath();//開始繪制葉子
      var wheelGradient = ctx.createRadialGradient(center.x, center.y, 100, center.x, center.y, 0);//創建徑向漸變
      wheelGradient.addColorStop(0, color[i]);//起始顏色
      wheelGradient.addColorStop(1, "#000");//結束顏色
      ctx.fillStyle = wheelGradient;//填充漸變樣式
      point = {x: center.x + Math.cos(offset * i + angle) * radius, y: center.y + Math.sin(offset * i + angle) * radius};//葉子圓心位置
      var x = start + offset * i;//繪制葉子的開始角
      var y = end + offset * i;//繪制葉子的結束角
      ctx.arc(point.x, point.y, wheelRadius, x, y, false);//繪制
      ctx.fill();//填充
      ctx.closePath();//結束繪制
    }
    ctx.beginPath();
    var dotGradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, 40);
    dotGradient.addColorStop(0, "#fff");
    dotGradient.addColorStop(1, "#666");
    ctx.fillStyle = dotGradient;
    ctx.arc(center.x, center.y, 25, 0, 2 * Math.PI, false);
    ctx.fill();
    ctx.closePath();
    angle += rotateAngle;
    start = angle;
    end = Math.PI + angle;
  },
20)

  動態的風車基本上就做完了,這是運行大風車代碼:

var options = {
  num: 4,
  color: ["red", "yellow", "blue", "green"],
  radius: 50,
  wheelRadius: 50,
  part: 50
  };
var a = new Pinwheel("canvas", options);
a.show();

修改options對象的屬性就會改變風車的狀態。  

  需要停止風車運轉調用這個函數:

hide: function () {
  clearInterval(window.timer);
}

  下面是展示結果的時候了:

  以前寫這些代碼是沒有注釋的,今天花了好大功夫加上注釋,然后在原有基礎上做了一些修改,做成了和CSS3寫的一模一樣的風車。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM