引言:网上最近太空人表盘很火,之前看到有个兄弟用svg写的,但是我也不会这个啊,我就琢磨着用canvas写了一个,效果感觉还不错,拿出来大家唠唠!
效果图:
思路
-
分两个画布来绘制,画布1用来放置不动的东西(背景、表盘、文字信息);
-
画布2用来绘制太空人的转动和时间的更新(经常要重新绘制);
-
太空人的转动的话就是用很多图片来切换,达到转动的效果。
绘制表盘
圆形构造函数
//构造函数
function Circle(o){
this.x=0,//圆心X坐标
this.y=0,//圆心Y坐标
this.r=0,//半径
this.startAngle=0,//开始角度
this.endAngle=0,//结束角度
this.anticlockwise=false;//顺时针,逆时针方向指定
this.stroke=false;//是否描边
this.fill=false;//是否填充
this.scaleX=1;//缩放X比例
this.scaleY=1;//缩放Y比例
this.rotate=0;
this.init(o);
}
//初始化
Circle.prototype.init=function(o){
for(var key in o){
this[key]=o[key];
}
}
//绘制
Circle.prototype.render=function(context){
var ctx=context;//获取上下文
ctx.save();
ctx.beginPath();
ctx.translate(this.x,this.y);
if(this.fill){
ctx.moveTo(0,0);
}
//ctx.moveTo(this.x,this.y);
ctx.scale(this.scaleX,this.scaleY);//设定缩放
ctx.arc(0,0,this.r,this.startAngle,this.endAngle);//画圆
if(this.lineWidth){//线宽
ctx.lineWidth=this.lineWidth;
}
if(this.fill){//是否填充
this.fillStyle?(ctx.fillStyle=this.fillStyle):null;
ctx.fill();
}
if(this.stroke){//是否描边
this.strokeStyle?(ctx.strokeStyle=this.strokeStyle):null;
ctx.stroke();
}
ctx.restore();
return this;
}
绘制代码
//绘制表盘
SpaceMan.prototype.drawClock=function(){
var x=y=0,cilcle;
x=this.w/2;y=this.h/2;
//绘制外面的大圆
cilcle = new Circle({
x:x,//圆心X坐标
y:y,//圆心X坐标
r:250,//半径
startAngle:0,//开始角度
endAngle:2*Math.PI,//结束角度
lineWidth:2,
fill:true,
fillStyle:'#444444'
});
this.renderArr.push(cilcle);
//绘制第2个圆
cilcle = new Circle({
x:x,//圆心X坐标
y:y,//圆心X坐标
r:220,//半径
startAngle:0,//开始角度
endAngle:2*Math.PI,//结束角度
lineWidth:2,
fill:true,
fillStyle:'#DFE6F0'
});
this.renderArr.push(cilcle);
}
此时页面的效果:
绘制分隔线
构造函数
//直线的构造
function Line(o){
this.x=0,//x坐标
this.y=0,//y坐标
this.startX=0,//开始点x位置
this.startY=0, //开始点y位置
this.endX=0,//结束点x位置
this.endY=0;//结束点y位置
this.thin=false;//设置变细系数
this.init(o);
}
Line.prototype.init=function(o){
for(var key in o){
this[key]=o[key];
}
}
Line.prototype.render=function(ctx){
innerRender(this);
function innerRender(obj){
ctx.save()
ctx.beginPath();
ctx.translate(obj.x,obj.y);
if(obj.thin){
ctx.translate(0.5,0.5);
}
if(obj.lineWidth){//设定线宽
ctx.lineWidth=obj.lineWidth;
}
if(obj.strokeStyle){
ctx.strokeStyle=obj.strokeStyle;
}
//划线
ctx.moveTo(obj.startX, obj.startY);
ctx.lineTo(obj.endX, obj.endY);
ctx.stroke();
ctx.restore();
}
return this;
}
绘制代码
//分隔线的 绘制
SpaceMan.prototype.drawClockLine=function(){
var x=y=0;
var line = new Line({
x:x,
y:y,
startX:70,
startY:120,
endX:430,
endY:120,
strokeStyle:'#030609',
lineWidth:3
})
this.renderArr.push(line);
line = new Line({
x:x,
y:y,
startX:220,
startY:30,
endX:220,
endY:120,
strokeStyle:'#030609',
lineWidth:3
})
this.renderArr.push(line);
line = new Line({
x:x,
y:y,
startX:58,
startY:360,
endX:442,
endY:360,
strokeStyle:'#030609',
lineWidth:3
})
this.renderArr.push(line);
line = new Line({
x:x,
y:y,
startX:180,
startY:410,
endX:180,
endY:460,
strokeStyle:'#030609',
lineWidth:3
})
this.renderArr.push(line);
line = new Line({
x:x,
y:y,
startX:178,
startY:410,
endX:342,
endY:410,
strokeStyle:'#030609',
lineWidth:3
})
this.renderArr.push(line);
line = new Line({
x:x,
y:y,
startX:340,
startY:410,
endX:340,
endY:360,
strokeStyle:'#030609',
lineWidth:3
})
this.renderArr.push(line);
}
此时效果
绘制文字
构造函数
//文字的构造函数
function Text(o){
this.x=0,//x坐标
this.y=0,//y坐标
this.disX=0,//x坐标偏移量
this.disY=0,//y坐标偏移量
this.text='',//内容
this.font=null;