c.moveto html,canvas圆形可拖动进度条

一、示例效果:

codepen.io/pangyongshe…

d400cf0111e18614eb98af33593cdf47.png

二、dome代码

本文是实现可拖动滑块实现的基本思路,及一个简单的dome,(github.com/pangyongshe…)

三、实现

1、首先在html中创建一个canvas标签

复制代码

2、创建一个进度条对象,编写初始化方法,获取canvas对象及上下文环境;event方法是用来绑定事件(具体后面介绍);draw是用来绘图的方法,这里把Draw对象的全部方法赋给draw方法;创建绘图实例p,绘制初始图形;

c0663a0610c5908c6cdb99f85b5b0764.pngvar 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

}

//...

}复制代码

13f60bec0295dd5d41e18d58b7fa84aa.png

3、在Draw中编写绘图方法draw绘制下图:

7e36ac000f146ab6dbb4746538c13ff1.png

(1)创建绘图方法,获取参数

1bc5eb7c9d88cd0a911fb51f6c26f341.pngdraw: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; //橙色圆弧结束弧度值

//...

}复制代码

fe3263684a8644c503405d67fef3e34c.png

(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)绘制外侧圆弧

2c63f900cedbe8de5b60029f10891f24.pngthis.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();复制代码

2013335a6d0b127a5656e3614be9311c.png

(4)绘制滑块

由于滑块是可以移动的这里滑块的位置使用了坐标参数xy,及滑块半径r作为可变参数

559943873273590cb2dcd921c1a54290.pngthis.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();复制代码

be91f9019a76d05c690c36db0d2853bf.png

(5)绘制长度可变弧(橙色部分):

由于长度可变,这里把闭合弧度作为可变参数

534c955f9e008cbfdb6e723d0bb33d54.pngthis.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();复制代码

18b73872dd3db2523792ad82c22d45c1.png

至此绘图方法完成,调用drow方法并传入参数滑块坐标、半径和拖动弧度(x,y,r,j)即可完成图片的绘制。

4、绘图方法分析

(1)这里首先建立以canvas左上角为原点屏幕坐标系,后面的绘图都将基于该坐标系,坐标图像如下:

4ad944aad630fc265594e9f217cb27ba.png

编写获取当前光标位置点相对canvas坐标系(lx,ly)的方法:即当前坐标点减去canvas偏移距离

86d43b581efdd42c243751090cd7af89.pnggetx:function(ev){ //获取鼠标在canvas内坐标x

return ev.clientX-this.obj.getBoundingClientRect().left;

},

gety:function(ev){ //获取鼠标在canvas内坐标y

return ev.clientY-this.obj.getBoundingClientRect().top;

}复制代码

65e2c367a6375f8e3193c1b8c91c793f.png

(2)为方便构建圆的方程,这里建立一个以canvas中心为原点的坐标系,如下图,在实际使用draw方法绘图时使用的是黑色的坐标系,在使用圆的路径处理是我们使用红色的坐标系

f5dd0e244036ce5122b5525f6c064463.png

下面添加坐标转化方法,

屏幕坐标(黑色坐标)->中心坐标(红色坐标)

283dbddedb8f63d49e19e6d1b017207b.pngspotchange: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;

},复制代码

c271be696f2876d56f7f3db98e044c3b.png

中心坐标(红色坐标)->屏幕坐标(黑色坐标)

1193f62263ce7341c3ff84c23c09f0d7.pngrespotchange: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;

},复制代码

faae3ecb5ecc5f5036f747d9d02aa504.png

(3)滑块路径及位置计算方法

10075f4b27223d742ce47d00c98a3c82.png

首先不考虑xy正负,

计算光标位置点的正切值

tanφ = ly/lx;

可知φ

φ=arctan(tanφ)

根据圆的参数方程,可获得光标点对应蓝色路径位置坐标为

x=rcosφ

y=rsinφ

(4)根据上面思路编写获取坐标位置方法,这里添加了xy和弧度值正负处理方法和可拖动弧度范围

68b3ef9dcbc61a61e82fa50306e4d8dd.pnggetmoveto:function(lx,ly){

if(!this.p.isDown){ //是否可移动

return false;

}

var tem={}; //存放目标坐标位置

tem.o=Math.atan(ly/lx); //鼠标移动点圆形角

tem.x=this.pathr*Math.cos(tem.o);

tem.y=this.pathr*Math.sin(tem.o);

if(lx<0){ //坐标点处理(正负)

tem.x=-tem.x;

tem.y=-tem.y;

}

if(lx>0){ //弧度值处理

tem.z=-Math.atan(tem.y/tem.x)+Math.PI*2;

}else{

tem.z=-Math.atan(tem.y/tem.x)+Math.PI;

}

if(tem.z>7.06){ //最大值

tem.z=7.06;

tem.x=this.pathr*Math.cos(Math.PI*2.25);

tem.y=-this.pathr*Math.sin(Math.PI*2.25);

}

if(tem.z<2.4){ //最小值

tem.z=2.4;

tem.x=this.pathr*Math.cos(Math.PI*0.75);

tem.y=-this.pathr*Math.sin(Math.PI*0.75);

}

return tem;

},复制代码

1602e59a561472fb889dd7c937247bb2.png

(5)以上方法在canvas内任意点均可作为滑块拖动的目标点,这里编写cheack方法,将限制可拖动位置限制在一个大概的环形里

dd150a842330e1c7a1bca58161a0d020.pngcheck:function(x,y){ //限制可拖动范围

var xx=x*x;

var yy=y*y;

var rr=114*114; //最小

var rrr=126*126; //最大

if(xx+yy>rr && xx+yy

return true;

}

return false;

},复制代码

719bb459c6cd4da62f47467c55cbebfa.png

5、事件方法编写

(1)鼠标按下执行方法OnMouseDown

这里使用了getx和gety获取光标相对canvas坐标,并判断鼠标是否移动到了滑块上方位置内,(this.p是当前绘图对象,p.x即滑块横坐标,p.x即当前纵坐标,p.r即滑块最大半径),如果光标在滑块上方则设置isDown为TRUE,反正依然,后面我们会通过isDown来判断是否执行移动滑块的方法:

6225d4607c0e5b79adc2cc92bdee6a4d.pngOnMouseDown:function(evt){

var X=this.getx(evt); //获取当前鼠标位置横坐标

var Y=this.gety(evt); //获取当前鼠标位置纵坐标

var minX=this.p.x-this.p.r;

var maxX=this.p.x+this.p.r;

var minY=this.p.y-this.p.r;

var maxY=this.p.y+this.p.r;

if(minX

this.p.isDown=true;

}else{

this.p.isDown=false;

}

}复制代码

99b5d91a383544023475d7af6198cd3a.png

(2)鼠标按下后移动时滑块的方法:

b3a1ec8297cfd932a324da3b0c39deec.pngOnMouseMove:function(evt){ //

if(this.p.isDown){ //是否在滑块上按下鼠标

var a={}; //存放当前鼠标坐标

a.x=this.getx(evt); //坐标转化

a.y=this.gety(evt);

var b=this.spotchange(a); //坐标转化

var co=this.getmoveto(b.x,b.y); //获取要移动到的坐标点

if(this.check(b.x,b.y)){ //判断移动目标点是否在可拖动范围

var co=this.getmoveto(b.x,b.y); //获取到移动的目标位置坐标()

var tar=this.respotchange(co); //坐标转化

var o=co.z;

this.p.draw(tar.x,tar.y,this.p.r,o); //绘图

}

}

},复制代码

0b02105f1250e20b5574f8559691adb3.png

(3)鼠标释放方法

OnMouseUp:function(){ //鼠标释放

this.p.isDown=false

},复制代码

(4)最后将所有方法和事件绑定

event:function(){ //事件绑定

this.obj.addEventListener("mousedown",this.OnMouseDown.bind(this),false);

this.obj.addEventListener("mousemove",this.OnMouseMove.bind(this),false);

this.obj.addEventListener("mouseup",this.OnMouseUp.bind(this),false);

},复制代码

至此可拖动滑块基本方法编写完成

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[canvas圆形可拖动进度条]http://www.zyiz.net/tech/detail-138325.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值