6.2.1_描边与填充绘制器
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>描边与填充绘制器-使用精灵</title>
<style>
body{
background: #ddd;
}
#canvas{
background: #fff;
cursor: pointer;
margin: 10px;
-webkit-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
-moz-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
</body>
<script>
var Sprite = function(name,painter,behaviors){
if(name !== undefined){ this.name = name; }
if(painter !== undefined){ this.painter = painter; }
this.top = 0;
this.left = 0;
this.width = 10;
this.height = 10;
this.velocityX = 0;
this.velocityY = 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 clock_radius = canvas.width/2 - 15;
var hour_hand_truncation = 35;
var ballPainter = {
paint:function(sprite,context){
var x = sprite.left+sprite.width/2;
var y = sprite.top + sprite.height/2;
var width = sprite.width;
var height = sprite.height;
var radius = sprite.width/2;
context.save();
context.beginPath();
context.arc(x,y,radius,0,Math.PI*2,false);
context.clip();
context.shadowColor = 'rgb(0,0,0)';
context.shadowOffsetX = -4;
context.shadowOffsetY = -4;
context.shadowBlur = 8;
context.fillStyle ='rgba(218,165,32,0.1)';
context.fill();
context.lineWidth = 2;
context.strokeStyle = 'rgb(100,100,195)';
context.stroke();
context.restore();
}
}
var ball = new Sprite('ball',ballPainter);
context.lineWidth = 0.5;
context.strokeStyle = 'rgba(0,0,0,0.2)';
context.shadowColor = 'rgba(0,0,0,0.5)';
context.shadowOffsetX = 2;
context.shadowOffsetY = 2;
context.shadowBlur = 4;
drawGrid('lightgray',10,10);
window.requestAnimationFrame(animate);
function animate(){
context.clearRect(0,0,canvas.width,canvas.height);
drawGrid('lightgray',10,10);
drawClock();
window.requestAnimationFrame(animate);
}
function drawClock(){
drawClockFace();
drawHands();
}
function drawHands(){
var date = new Date();
var hour = date.getHours();
ball.width = 20;
ball.height =20;
drawHand(date.getSeconds(),false);
context.save();
context.lineWidth =1;
ball.width = 30;
ball.height = 30;
drawHand(date.getMinutes(),false);
context.restore();
context.save();
context.lineWidth =2;
hour = hour>12? hour-12:hour;
ball.width = 40;
ball.height = 40;
drawHand(hour*5 + (date.getMinutes()/60)*5,true);
context.restore();
ball.width = 10;
ball.height = 10;
ball.left = canvas.width/2 - ball.width/2;
ball.top = canvas.height/2 - ball.height/2;
ballPainter.paint(ball,context);
}
function drawHand(time,isHour){
var angle = (Math.PI*2)*time/60 - Math.PI/2;
var handRudius = isHour? clock_radius - hour_hand_truncation:clock_radius;
lineEnd = {
x:canvas.width/2+Math.cos(angle)*(handRudius - ball.width/2),
y:canvas.height/2+Math.sin(angle)*(handRudius - ball.width/2)
};
context.beginPath();
context.moveTo(canvas.width/2,canvas.height/2);
context.lineTo(lineEnd.x,lineEnd.y);
context.stroke();
ball.left = canvas.width/2 + Math.cos(angle)*handRudius - ball.width/2;
ball.top = canvas.height/2 +Math.sin(angle)*handRudius - ball.height/2;
ball.paint(context);
}
function drawClockFace(){
context.beginPath();
context.arc(canvas.width/2,canvas.height/2,clock_radius,0,Math.PI*2,false);
context.save();
context.strokeStyle = 'rgba(0,0,0,0.2)';
context.stroke();
context.restore();
}
function drawGrid(color, stepX, stepY) {
context.save();
context.shadowColor = undefined;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 0;
context.strokeStyle = color;
context.lineWidth = 0.5;
context.fillStyle = '#fff';
context.fillRect(0, 0, canvas.width, canvas.height);
for(var i = stepX + 0.5; i < context.canvas.width; i += stepX) {
context.beginPath();
context.moveTo(i, 0);
context.lineTo(i, context.canvas.height);
context.stroke();
}
for(var i = stepY + 0.5; i < context.canvas.height; i += stepY) {
context.beginPath();
context.moveTo(0, i);
context.lineTo(context.canvas.width, i);
context.stroke();
}
context.restore();
}
</script>
</html>