7.1.3_钟摆运动
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>钟摆运动</title>
<style>
#canvas{
background: white;
box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
-moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
-webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
cursor: pointer;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
</body>
<script>
var Sprite = function(name,painter,behaviors){
if(name !== undefined){ this.name = name; }
if(painter !== undefined){ this.painter = painter; }
this.x = 0;
this.y = 0;
this.pivotRadius = 7;
this.weightX = 0;
this.weightY = 0;
this.weightRadius = 0;
this.rodLength = 100;
this.initialAngle = 0;
this.angle = 0;
this.visible = true;
this.animating = false;
this.behaviors = behaviors || [];
}
Sprite.prototype = {
paint:function(context){
if(this.painter !== undefined && this.visible){
this.painter.paint(this,context);
}
},
update:function(context,time){
for(var i=0;i<this.behaviors.length;i++){
this.behaviors[i].execute(this,context,time);
}
}
}
</script>
<script>
var canvas =document.getElementById('canvas');
var context = canvas.getContext('2d');
var elapsed = undefined;
var startTime = undefined;
var pivot_y = 20;
var pivot_x = canvas.width/2;
var pivot_radius = 7;
var rod_length_in_pixels = 300;
var weight_radius = 25;
var weight_x = canvas.width/2;
var weight_y = pivot_y+pivot_radius+rod_length_in_pixels+weight_radius;
var initial_angle = Math.PI/5;
var pendulumPainter = {
pivot_fill_style : 'rgba(0,0,0,0.2)',
weight_shadow_color : 'rgb(0,0,0,)',
pivot_shadow_color : 'rgb(255,255,0)',
stroke_color : 'rgb(100,100,195)',
paint:function(pendulum,context){
this.drawPivot(pendulum,context);
this.drawRod(pendulum,context);
this.drawWeight(pendulum,context);
},
drawWeight : function(pendulum,context){
context.save();
context.beginPath();
context.arc(pendulum.weightX,pendulum.weightY,pendulum.weightRadius,0,2*Math.PI,false);
context.clip();
context.shadowColor = this.weight_shadow_color;
context.shadowOffsetX = -4;
context.shadowOffsetY = -4;
context.shadowBlur = 8;
context.lineWidth = 2;
context.strokeStyle = this.stroke_color;
context.stroke();
context.beginPath();
context.arc(pendulum.weightX,pendulum.weightY,pendulum.weightRadius/2,0,2*Math.PI,false);
context.clip();
context.shadowColor = this.pivot_fill_style;
context.shadowOffsetX = -4;
context.shadowOffsetY = -4;
context.shadowBlur = 8;
context.stroke();
context.restore();
},
drawPivot : function(pendulum,context){
context.save();
context.beginPath();
context.shadowColor = undefined;
context.fillStyle = 'white';
context.arc(pendulum.x,pendulum.y,pendulum.pivotRadius/2,0,2*Math.PI,false);
context.fill();
context.stroke();
context.beginPath();
context.fillStyle = this.pivot_fill_style;
context.arc(pendulum.x,pendulum.y,pendulum.pivotRadius,0,2*Math.PI,false);
context.fill();
context.stroke();
context.restore();
},
drawRod : function(pendulum,context){
context.save();
context.beginPath();
context.moveTo(pendulum.x + pendulum.pivotRadius*Math.sin(pendulum.angle),
pendulum.y + pendulum.pivotRadius*Math.cos(pendulum.angle)
);
context.lineTo(pendulum.weightX - pendulum.weightRadius*Math.sin(pendulum.angle),
pendulum.weightY - pendulum.weightRadius*Math.cos(pendulum.angle)
);
context.stroke();
context.restore();
}
};
var swing = {
gravity_force : 32,
rod_length:0.8,
execute : function(pendulum,context,time){
pendulum.angle = pendulum.initialAngle*Math.cos(
Math.sqrt(this.gravity_force/this.rod_length)*elapsed
);
pendulum.weightX = pendulum.x+Math.sin(pendulum.angle)*pendulum.rodLength;
pendulum.weightY = pendulum.y+Math.cos(pendulum.angle)*pendulum.rodLength;
}
};
var pendulum = new Sprite('pendulum',pendulumPainter,[swing]);
pendulum.x = pivot_x;
pendulum.y = pivot_y;
pendulum.pivotRadius = pivot_radius;
pendulum.weightX = weight_x;
pendulum.weightY = weight_y;
pendulum.weightRadius = weight_radius;
pendulum.initialAngle = initial_angle;
pendulum.angle = initial_angle;
pendulum.rodLength = rod_length_in_pixels;
context.lineWidth = 0.5;
context.strokeStyle = 'rgba(0,0,0,0.5)';
context.shadowColor = 'rgba(0,0,0,0.5)';
context.shadowOffsetX = 2;
context.shadowOffsetY = 2;
context.shadowBlur = 4;
context.stroke();
startTime = +new Date();
animate();
function animate(time){
time = +new Date();
elapsed = (time - startTime)/1000;
context.clearRect(0,0,canvas.width,canvas.height);
pendulum.update(context,time);
pendulum.paint(context);
window.requestAnimationFrame(animate);
}
</script>
</html>