HTML5 Canvas实战
5.7 动画机械齿轮
阅读(

路径和文本

图形及组合

处理图像和视频

画布变换

动画给画布带来生机

创建Animation类

创建直线运动

创建加速度

创建振荡运动

摆动的气泡

摆钟

动画机械齿轮

如果你是机械工程师,本节就专为你量身定做。本节,我们将创建一个相互连接的旋转齿轮系。

创建旋转的齿轮
图5-7 创建旋转的齿轮

操作步骤

按照以下步骤,创建一个相互连接的旋转齿轮系:

1. 链接到Animation类:

<head>
<script src="animation.js"> </script>

2. 定义Gear类的构造函数:

<script>
function Gear(config){
  this.x  = config.x;
  this.y  = config.y;
  this.outerRadius  = config.outerRadius;
  this.innerRadius  = config.innerRadius; 
  this.holeRadius  = config.holeRadius; 
  this.numTeeth  = config.numTeeth;
  this.theta  = config.theta;
  this.thetaSpeed  = config.thetaSpeed;
  this.lightColor  = config.lightColor;
  this.darkColor  = config.darkColor;
  this.clockwise  = config.clockwise;
  this.midRadius  = config.outerRadius  -  10;
}

3. 定义Gear类的draw()方法,该方法绘制一个gear对象:

Gear.prototype.draw  = function(context){
    context.save();
    context.translate(this.x, this.y); 
    context.rotate(this.theta);
    //绘制轮齿
    context.beginPath();
    // 我们可以把lineJoin属性设置为bevel,以便轮齿的齿尖是扁平的,并且不会形成锐利的尖
    context.lineJoin  = "bevel";
    // 循环创建齿轮图形
    var numPoints  = this.numTeeth  *  2;
    for  (var n  =  0; n  < numPoints; n++)  {
      var radius  = null;
      //在偶数迭代绘制齿尖
      if  (n  %  2  ==  0)  {
        radius  = this.outerRadius;
      }      
      // 绘制齿轮中心和齿轮半径间的齿牙连接线
      else  {
        radius  = this.innerRadius;
      }
      var theta  =  ((Math.PI  *  2)  / numPoints)  *  (n  +  1);
      var x  =  (radius  * Math.sin(theta));
      var y  =  (radius  * Math.cos(theta));
      // 如果是首次迭代,使用moveTo()方法定位绘制光标
      if  (n  ==  0)  {
        context.moveTo(x, y);
      }
      // 如果是其他迭代,使用lineTo()方法连接子路径
      else  {
        context.lineTo(x, y);
      }
    }
    context.closePath();
    // 定义线条宽度和描边颜色
    context.lineWidth  =  5;
    context.strokeStyle  = this.darkColor; 
    context.stroke();
    //绘制齿轮体
    context.beginPath();
    context.arc(0,  0, this.midRadius,  0,  2  * Math.PI, false);
    //创建线性渐变
    var grd  = context.createLinearGradient(-1  * this.outerRadius  /  2,  
                                            -1  * this.outerRadius  /  2, 
                                            this.outerRadius  /  2, 
                                            this.outerRadius  /  2);
    grd.addColorStop(0, this.lightColor); 
    grd.addColorStop(1, this.darkColor); 
    context.fillStyle  = grd;
    context.fill();
    context.lineWidth  =  5;
    context.strokeStyle  = this.darkColor; 
    context.stroke();
    //绘制齿轮孔
    context.beginPath();
    context.arc(0,  0, this.holeRadius,  0,  2  * Math.PI,    false);
    context.fillStyle  = "white"; 
    context.fill();
    context.strokeStyle  = this.darkColor; 
    context.stroke();
    context.restore();
  };

4. 实例化一个Animation对象,并获取画布上下文对象:

window.onload = function(){
  var anim    = new Animation("myCanvas"); 
  var canvas  = anim.getCanvas();
  var context = anim.getContext();

5. 创建gear对象的数组:

  var gears  =  [];
  //添加蓝色齿轮
  gears.push(new Gear({
    x:  270,
    y:  105,
    outerRadius:  90,
    innerRadius:  50,
    holeRadius:  10,
    numTeeth:  24, 
    theta:  0,
    thetaSpeed:  1  /  1000, 
    lightColor: "#B1CCFF",
    darkColor: "#3959CC",
    clockwise: false
  }));
  //添加红色齿轮
  gears.push(new Gear({
    x:  372,
    y:  190,
    outerRadius:  50,
    innerRadius:  15,
    holeRadius:  10,
    numTeeth:  12,
    theta:  0.14,
    thetaSpeed:  2  /  1000, 
    lightColor: "#FF9E9D",
    darkColor: "#AD0825",
    clockwise: true
  }));
  // 添加橙色齿轮
  gears.push(new Gear({
    x:  422,
    y:  142,
    outerRadius:  28,
    innerRadius:  5,
    holeRadius:  7, 
    numTeeth:  6, 
    theta:  0.35,
    thetaSpeed:  4  /  1000, 
    lightColor: "#FFDD87",
    darkColor: "#D25D00",
    clockwise: false
  }));

6. 设置stage()函数,该函数更新每个齿轮的旋转,清除画布,再绘制齿轮:

anim.setStage(function(){
  // update
  for  (var i  =  0; i  < gears.length; i++)  {
    var gear  = gears[i];
    var thetaIncrement  = gear.thetaSpeed  * this.getTimeInterval();
    gear.theta  += gear.clockwise  ? thetaIncrement:  -1  * thetaIncrement;
  }
  // clear
  this.clear();
  // draw
  for  (var i  =  0; i  < gears.length; i++)  {
     gears[i].draw(context);
  }
});

7. 启动动画:

  anim.start();
};
</script>
</head>

8. 在HTML文档的body部分嵌入canvas标签:

<body>
<canvas id="myCanvas" width="600" height="250" style="border:1px solid black;">
</canvas>
</body>

工作原理

要创建一个旋转的齿轮系,我们可以重用第2章的绘制过程,并创建一个Gear类,该类有一些属性,如齿牙数目、颜色、角度、角速度。theta定义齿轮的角位置,thetaSpeed定义齿轮的角速度。我们也可以给Gear类增加一个clockwise属性,来定义齿轮的旋转方向。

页面加载完成后,我们可以实例化一个Animation对象,并得到画布及其上下文对象。接下来,我们可以实例化多个Gear对象,来初始化多个齿轮,并把它们放到齿轮数组中。现在,我们的舞台已经初始化完成,我们可以设置stage()函数,用于更新每个齿轮的角度,清除画布,再使用Gear类的draw()方法绘制每个齿轮。

现在,stage()函数已经设置完成,我们可以调用start()方法启动动画了。

相关参考

  • 第2章 绘制圆
  • 第2章 使用循环创建图案:绘制齿轮

如果本教程对您帮助很大,请随意打赏。您的支持,将鼓励我们提供更好的教程!

← 键盘方向键翻页 →
返回顶部 手机访问 关注微信 返回底部

扫码访问歪脖网

随时随地,想看就看

关注歪脖网微信

分享 web 知识、交流 web 经验