HTML5画布齿轮

很有意思的一个代码。


<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
  <body>
    <canvas id="myCanvas" width="578" height="250"></canvas>
    <script>
      window.requestAnimFrame = (function(callback) {
        return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
        function(callback) {
          window.setTimeout(callback, 1000 / 60);
        };
      })();

      /*
       * Gear constructor
       */
      function Gear(config) {
        this.x = config.x;
        this.y = config.y;
        this.outerRadius = config.outerRadius;
        this.innerRadius = config.innerRadius;
        this.midRadius = config.midRadius;
        this.holeRadius = config.holeRadius;
        this.numTeeth = config.numTeeth;
        this.theta = config.theta;
        this.thetaSpeed = config.thetaSpeed / 1000;
        this.lightColor = config.lightColor;
        this.darkColor = config.darkColor;
        this.clockwise = config.clockwise;
      }
      /*
       * Gear draw method
       */
      Gear.prototype.draw = function() {
        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');

        context.save();
        var numPoints = this.numTeeth * 2;
        // draw gear teeth
        context.beginPath();
        context.lineJoin = 'bevel';
        for(var n = 0; n < numPoints; n++) {

          var radius = null;

          if(n % 2 == 0) {
            radius = this.outerRadius;
          }
          else {
            radius = this.innerRadius;
          }

          var theta = this.theta;
          theta += ((Math.PI * 2) / numPoints) * (n + 1);

          var x = (radius * Math.sin(theta)) + this.x;
          var y = (radius * Math.cos(theta)) + this.y;

          if(n == 0) {
            context.moveTo(x, y);
          }
          else {
            context.lineTo(x, y);
          }
        }

        context.closePath();
        context.lineWidth = 5;
        context.strokeStyle = this.darkColor;
        context.stroke();

        // draw gear body
        context.beginPath();
        context.arc(this.x, this.y, this.midRadius, 0, 2 * Math.PI, false);

        var grd = context.createLinearGradient(this.x - 100, this.y - 100, this.x + 100, this.y + 100);
        grd.addColorStop(0, this.lightColor);
        grd.addColorStop(1, this.darkColor);
        context.fillStyle = grd;
        context.fill();
        context.lineWidth = 5;
        context.strokeStyle = this.darkColor;
        context.stroke();

        // draw gear hole
        context.beginPath();
        context.arc(this.x, this.y, this.holeRadius, 0, 2 * Math.PI, false);
        context.fillStyle = 'white';
        context.fill();
        context.strokeStyle = this.darkColor;
        context.stroke();
        context.restore();
      };
      function animate(gears, lastTime) {
        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');

        // update
        var time = (new Date()).getTime();
        var timeDiff = time - lastTime;

        for(var i = 0; i < gears.length; i++) {
          var gear = gears[i];

          if(gears[i].clockwise) {
            gears[i].theta -= (gear.thetaSpeed * timeDiff);
          }
          else {
            gears[i].theta += (gear.thetaSpeed * timeDiff);
          }
        }

        // clear
        context.clearRect(0, 0, canvas.width, canvas.height);

        // draw
        for(var i = 0; i < gears.length; i++) {
          gears[i].draw();
        }

        // request new frame
        requestAnimFrame(function() {
          animate(gears, time);
        });
      }
      var gears = [];

      // blue gear
      gears.push(new Gear({
        x: 120,
        y: 105,
        outerRadius: 90,
        innerRadius: 50,
        midRadius: 80,
        holeRadius: 10,
        numTeeth: 24,
        theta: 0,
        thetaSpeed: 1,
        lightColor: '#B1CCFF',
        darkColor: '#3959CC',
        clockwise: false
      }));

      // red gear
      gears.push(new Gear({
        x: 222,
        y: 190,
        outerRadius: 50,
        innerRadius: 15,
        midRadius: 40,
        holeRadius: 10,
        numTeeth: 12,
        theta: 0.14,
        thetaSpeed: 2,
        lightColor: '#FF9E9D',
        darkColor: '#AD0825',
        clockwise: true
      }));

      // orage gear
      gears.push(new Gear({
        x: 272,
        y: 142,
        outerRadius: 28,
        innerRadius: 5,
        midRadius: 18,
        holeRadius: 7,
        numTeeth: 6,
        theta: 0.14,
        thetaSpeed: 4,
        lightColor: '#FFDD87',
        darkColor: '#D25D00',
        clockwise: false
      }));

      // green gear
      gears.push(new Gear({
        x: 463,
        y: 144,
        outerRadius: 170,
        innerRadius: 100,
        midRadius: 160,
        holeRadius: 10,
        numTeeth: 48,
        theta: 0,
        thetaSpeed: 0.5,
        lightColor: '#8AFF99',
        darkColor: '#005C06',
        clockwise: true
      }));

      var time = (new Date()).getTime();
      animate(gears, time);

    </script>
  </body>
</html>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值