5.7 动画机械齿轮
优质
小牛编辑
136浏览
2023-12-01
如果你是机械工程师,本节就专为你量身定做。本节,我们将创建一个相互连接的旋转齿轮系。
操作步骤
按照以下步骤,创建一个相互连接的旋转齿轮系:
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章 使用循环创建图案:绘制齿轮