用JavaScript实现网红太空人表盘(绝对详细、绝对原创),附源码下载

==

  1. 分两个画布来绘制,画布1用来放置不动的东西(背景、表盘、文字信息);

  2. 画布2用来绘制太空人的转动和时间的更新(经常要重新绘制);

  3. 太空人的转动的话就是用很多图片来切换,达到转动的效果。

绘制表盘


圆形构造函数

//构造函数

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;//字体

this.textAlign=null;//对齐方式

this.init(o);

}

Text.prototype.init=function(o){

for(var key in o){

this[key]=o[key];

}

}

Text.prototype.render=function(context){

this.ctx=context;

innerRender(this);

function innerRender(obj){

var ctx=obj.ctx;

ctx.save()

ctx.beginPath();

ctx.translate(obj.x,obj.y);

if(obj.angle){//根据旋转角度来执行旋转

ctx.rotate(-obj.angle*Math.PI/180);

}

if(obj.font){

ctx.font=obj.font;

}

if(obj.textAlign){

ctx.textAlign=obj.textAlign;

}

if(obj.fill){//是否填充

obj.fillStyle?(ctx.fillStyle=obj.fillStyle):null;

ctx.fillText(obj.text,obj.disX,obj.disY);

}

if(obj.stroke){//是否描边

obj.strokeStyle?(ctx.strokeStyle=obj.strokeStyle):null;

ctx.strokeText(obj.text,obj.disX,obj.disY);

}

ctx.restore();

}

return this;

}

绘制

//组装文字信息

SpaceMan.prototype.drawText=function(){

var content=“”,x=y=0;

//天气

x=230;y=60,content=“空气良好”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘bold 20px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

x=230;y=85,content=“晴天”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘20px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//气温

x=230;y=110,content=“23°C”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘18px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//绘制最小温度

x=285;y=110,content=“18°”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘18px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//绘制最大温度

x=285;y=85,content=“26°”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘18px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//电量

x=120;y=115,content=“70%”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘bold 35px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//心率

x=65;y=305,content=“80~128”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘20px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

x=130;y=345,content=“92”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘bold 30px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//步数

x=370;y=345,content=“7032”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘bold 26px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//睡眠

x=110;y=395,content=“睡眠”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘30px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

x=190;y=400,content=“8h30m”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘BOLD 34px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

//距离

x=350;y=395,content=“距离”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘30px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

x=210;y=445,content=“9.22km”;

var text = new Text({

x:x,

y:y,

text:content,

font:‘BOLD 32px ans-serif’,

textAlign:‘left’,

fill:true,

fillStyle:‘#44444’

});

this.renderArr.push(text);

}

效果如下:

绘制修饰图片


图片构造函数

//图片对象ImageDraw构造函数

function ImageDraw(o,obj){

this.id=‘’,

this.image=0,//图片对象(必填)

this.sx=0,//图片切片开始x位置(显示整个图片的时候不需要填)

this.sy=0,//图片切片开始y位置(显示整个图片的时候不需要填)

this.sWidth=0, //图片切片开始宽度(显示整个图片的时候不需要填)

this.sHeight=0,//图片切片开始高度(显示整个图片的时候不需要填)

this.dx=0, //图片目标x位置(必填)

this.dy=0, //图片目标y位置(必填)

this.dWidth=0,//图片目标显示宽度(宽度不缩放时不必填)

this.dHeight=0//图片目标高度高度(高度不缩放时不必填)

this.init(o,obj);

}

ImageDraw.prototype.init=function(o,obj){

this.lol=obj;

for(var key in o){

this[key]=o[key];

}

return this;

}

ImageDraw.prototype.render=function(context){

draw(context,this);

function draw(context,obj) {

var ctx=context;

ctx.save();

if(!obj.image || getType(obj.dx)‘undefined’ || getType(obj.dy)‘undefined’){

throw new Error(“绘制图片缺失参数”);

return;

}

ctx.translate(obj.dx,obj.dy);

if(getType(obj.sx)!=‘undefined’ && getType(obj.sy)!=‘undefined’ && obj.sWidth && obj.sHeight && obj.dWidth && obj.dHeight){

//裁剪图片,显示时候有缩放

ctx.drawImage(obj.image, obj.sx, obj.sy, obj.sWidth, obj.sHeight, 0, 0, obj.dWidth, obj.dHeight);

}else if(obj.dWidth && obj.dHeight){

ctx.drawImage(obj.image, 0, 0, obj.dWidth, obj.dHeight);//原始图片,显示时候有缩放

}else{

ctx.drawImage(obj.image,0, 0);//原始图片,显示时候无缩放

}

ctx.restore();

}

}

ImageDraw.prototype.isPoint=function(pos){

//鼠标位置的x、y要分别大于dx、dy 且x、y要分别小于 dx+dWidth、dy+dHeight

if(pos.x>this.dx && pos.y>this.dy && pos.x<this.dx+this.dWidth && pos.y<this.dy+this.dHeight ){//表示处于当前图片对象范围内

return true;

}

return false;

}

绘制

//组装图片对象信息

SpaceMan.prototype.drawOtherImg=function(){

//绘制电量

var image = this.imgObj[66];

var img,x=y=0,sWidth=200,sHeight=200,dx=170,dy=45,dWidth=50,dHeight=50;

img = new ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight},this);

this.renderArr.push(img);

//绘制太阳

image = this.imgObj[62];

sWidth=200,sHeight=200,dx=340,dy=70,dWidth=50,dHeight=50;

img = new ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight},this);

this.renderArr.push(img);

//绘制最大温度

image = this.imgObj[65];

var img,x=y=0,sWidth=200,sHeight=200,dx=315,dy=70,dWidth=20,dHeight=20;

img = new ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight},this);

this.renderArr.push(img);

//绘制最小温度

image = this.imgObj[64];

var img,x=y=0,sWidth=200,sHeight=200,dx=315,dy=90,dWidth=20,dHeight=20;

img = new ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight},this);

this.renderArr.push(img);

//绘制心率

image = this.imgObj[61];

sWidth=200,sHeight=200,dx=70,dy=305,dWidth=60,dHeight=60;

img = new ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight},this);

this.renderArr.push(img);

//绘制步数

image = this.imgObj[63];

sWidth=200,sHeight=200,dx=320,dy=310,dWidth=50,dHeight=50;

img = new ImageDraw({image:image,sx:x,sy:y,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight},this);

this.renderArr.push(img);

}

此时的效果

绘制太空人

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值