1、首先在html中创建一个canvas标签
<canvas ></canvas>
2、创建一个进度条对象,编写初始化方法,获取canvas对象及上下文环境;event方法是用来绑定事件(具体后面介绍);draw是用来绘图的方法,这里把Draw对象的全部方法赋给draw方法;创建绘图实例p,绘制初始图形;
var Draw={ init:function(){ this.obj=document.getElementById("canvas"); //获取canvas对象 this.cObj=document.getElementById("canvas").getContext("2d");//获取canvas对象上下文环境 this.event(); //初始化事件 this.pathr=120; //滑动路径半径 this.draw.prototype=this; //draw继承Draw方法 this.p=new this.draw(112,284,18); //创建实例p } //... }
3、在Draw中编写绘图方法draw绘制下图:
(1)创建绘图方法,获取参数
draw:function(x,y,r,j){ //绘图 this.cObj.clearRect(0,0,400,400); //清空画布 this.x=x; //滑块坐标x this.y=y; //滑块坐标y this.r=r; //滑块移动路径半径 this.j=j; //橙色圆弧结束弧度值 //... }
(2)绘制内侧圆弧
this.cObj.beginPath(); this.cObj.lineWidth = 1; this.cObj.arc(200,200,100,Math.PI*0.75,Math.PI*2.25,false); // 绘制内层圆弧 this.cObj.strokeStyle = '#0078b4'; this.cObj.stroke();
(3)绘制外侧圆弧
this.cObj.beginPath(); this.cObj.arc(200,200,120,Math.PI*0.75,Math.PI*2.25,false); // 绘制外侧圆弧 this.cObj.strokeStyle = '#c0c0c0'; this.cObj.lineCap = "round"; this.cObj.lineWidth = 20; this.cObj.stroke();
(4)绘制滑块
由于滑块是可以移动的这里滑块的位置使用了坐标参数xy,及滑块半径r作为可变参数
this.cObj.beginPath(); this.cObj.moveTo(200,200); this.cObj.arc(x,y,r,0,Math.PI*2,false); // 绘制滑块 this.cObj.fillStyle='#f15a4a'; this.cObj.fill(); this.cObj.beginPath(); this.cObj.moveTo(200,200); this.cObj.arc(x,y,11,0,Math.PI*2,false); // 绘制滑块内侧白色区域 this.cObj.fillStyle='#ffffff'; this.cObj.fill();
(5)绘制长度可变弧(橙色部分):
由于长度可变,这里把闭合弧度作为可变参数
this.cObj.beginPath(); this.cObj.arc(200,200,120,Math.PI*0.75,this.j,false); // 可变圆弧 this.cObj.strokeStyle = '#f15a4a'; this.cObj.lineCap = "round"; this.cObj.lineWidth = 20; this.cObj.stroke();
至此绘图方法完成,调用drow方法并传入参数滑块坐标、半径和拖动弧度(x,y,r,j)即可完成图片的绘制。
4、绘图方法分析
(1)这里首先建立以canvas左上角为原点屏幕坐标系,后面的绘图都将基于该坐标系,坐标图像如下:
编写获取当前光标位置点相对canvas坐标系(lx,ly)的方法:即当前坐标点减去canvas偏移距离
getx:function(ev){ //获取鼠标在canvas内坐标x return ev.clientX-this.obj.getBoundingClientRect().left; }, gety:function(ev){ //获取鼠标在canvas内坐标y return ev.clientY-this.obj.getBoundingClientRect().top; }
(2)为方便构建圆的方程,这里建立一个以canvas中心为原点的坐标系,如下图,在实际使用draw方法绘图时使用的是黑色的坐标系,在使用圆的路径处理是我们使用红色的坐标系
下面添加坐标转化方法,
屏幕坐标(黑色坐标)->中心坐标(红色坐标)
spotchange:function(a){ //屏幕坐标转化为中心坐标 var target={}; if(a.x<200 && a.y<200){ //二象限 target.x=-(200-a.x); target.y=200-a.y; }else if(a.x>200 && a.y<200){ //一象限 target.x=a.x-200; target.y=200-a.y; }else if(a.x>200 && a.y>200){ //四象限 target.x=a.x-200; target.y=-(a.y-200) }else if(a.x<200 && a.y>200){ //三象限 target.x=-(200-a.x); target.y=-(a.y-200); } return target; },
中心坐标(红色坐标)->屏幕坐标(黑色坐标)
respotchange:function(a){ //中心坐标转化为屏幕坐标 var target={}; if(a.x>0 && a.y>0){ target.x=200+a.x; target.y=(200-a.y); }else if(a.x<0 && a.y>0){ target.x=200+a.x; target.y=200-a.y; }else if(a.x<0 && a.y<0){ target.x=200+a.x; target.y=-(a.y-200) }else if(a.x>0 && a.y<0){ target.x=200+a.x; target.y=-(a.y-200); } return target; },
(3)滑块路径及位置计算方法
首先不考虑xy正负,
计算光标位置点的正切值
tanφ = ly/lx;
可知φ
φ=arctan(tanφ)
根据圆的参数方程,可获得光标点对应蓝色路径位置坐标为
x=rcosφ
y=rsinφ
(4)根据上面思路编写获取坐标位置方法,这里添加了xy和弧度值正负处理方法和可拖动弧度范围