這篇文章給大家分享的是有關(guān)canvas如何實(shí)現(xiàn)弧形可拖動(dòng)進(jìn)度條效果的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比華亭網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式華亭網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋華亭地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。一、效果如下:
二、
本文是實(shí)現(xiàn)可拖動(dòng)滑塊實(shí)現(xiàn)的基本思路,及一個(gè)簡(jiǎn)單的dome,(https://github.com/pangyongsheng/canvas-arc-draw)
三、
1、首先在html中創(chuàng)建一個(gè)canvas標(biāo)簽
<canvas id="canvas" width="400" height="400"></canvas>
2、創(chuàng)建一個(gè)進(jìn)度條對(duì)象,編寫初始化方法,獲取canvas對(duì)象及上下文環(huán)境;event方法是用來(lái)綁定事件(具體后面介紹);draw是用來(lái)繪圖的方法,這里把Draw對(duì)象的全部方法賦給draw方法;創(chuàng)建繪圖實(shí)例p,繪制初始圖形;
var Draw={ init:function(){ this.obj=document.getElementById("canvas"); //獲取canvas對(duì)象 this.cObj=document.getElementById("canvas").getContext("2d");//獲取canvas對(duì)象上下文環(huán)境 this.event(); //初始化事件 this.pathr=120; //滑動(dòng)路徑半徑 this.draw.prototype=this; //draw繼承Draw方法 this.p=new this.draw(112,284,18); //創(chuàng)建實(shí)例p } //... }
3、在Draw中編寫繪圖方法draw繪制下圖:
(1)創(chuàng)建繪圖方法,獲取參數(shù)
draw:function(x,y,r,j){ //繪圖 this.cObj.clearRect(0,0,400,400); //清空畫布 this.x=x; //滑塊坐標(biāo)x this.y=y; //滑塊坐標(biāo)y this.r=r; //滑塊移動(dòng)路徑半徑 this.j=j; //橙色圓弧結(jié)束弧度值 //... }
(2)繪制內(nèi)側(cè)圓弧
this.cObj.beginPath(); this.cObj.lineWidth = 1; this.cObj.arc(200,200,100,Math.PI*0.75,Math.PI*2.25,false); // 繪制內(nèi)層圓弧 this.cObj.strokeStyle = '#0078b4'; this.cObj.stroke();
(3)繪制外側(cè)圓弧
this.cObj.beginPath(); this.cObj.arc(200,200,120,Math.PI*0.75,Math.PI*2.25,false); // 繪制外側(cè)圓弧 this.cObj.strokeStyle = '#c0c0c0'; this.cObj.lineCap = "round"; this.cObj.lineWidth = 20; this.cObj.stroke();
(4)繪制滑塊
由于滑塊是可以移動(dòng)的這里滑塊的位置使用了坐標(biāo)參數(shù)xy,及滑塊半徑r作為可變參數(shù)
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); // 繪制滑塊內(nèi)側(cè)白色區(qū)域 this.cObj.fillStyle='#ffffff'; this.cObj.fill();
(5)繪制長(zhǎng)度可變?。ǔ壬糠郑?/strong>
由于長(zhǎng)度可變,這里把閉合弧度作為可變參數(shù)
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();
至此繪圖方法完成,調(diào)用drow方法并傳入?yún)?shù)滑塊坐標(biāo)、半徑和拖動(dòng)弧度(x,y,r,j)即可完成圖片的繪制。
4、繪圖方法分析
(1)這里首先建立以canvas左上角為原點(diǎn)屏幕坐標(biāo)系,后面的繪圖都將基于該坐標(biāo)系,坐標(biāo)圖像如下:
編寫獲取當(dāng)前光標(biāo)位置點(diǎn)相對(duì)canvas坐標(biāo)系(lx,ly)的方法:即當(dāng)前坐標(biāo)點(diǎn)減去canvas偏移距離
getx:function(ev){ //獲取鼠標(biāo)在canvas內(nèi)坐標(biāo)x return ev.clientX-this.obj.getBoundingClientRect().left; }, gety:function(ev){ //獲取鼠標(biāo)在canvas內(nèi)坐標(biāo)y return ev.clientY-this.obj.getBoundingClientRect().top; }
(2)為方便構(gòu)建圓的方程,這里建立一個(gè)以canvas中心為原點(diǎn)的坐標(biāo)系,如下圖,在實(shí)際使用draw方法繪圖時(shí)使用的是黑色的坐標(biāo)系,在使用圓的路徑處理是我們使用紅色的坐標(biāo)系
下面添加坐標(biāo)轉(zhuǎn)化方法,
屏幕坐標(biāo)(黑色坐標(biāo))->中心坐標(biāo)(紅色坐標(biāo))
spotchange:function(a){ //屏幕坐標(biāo)轉(zhuǎn)化為中心坐標(biāo) 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; },
中心坐標(biāo)(紅色坐標(biāo))->屏幕坐標(biāo)(黑色坐標(biāo))
respotchange:function(a){ //中心坐標(biāo)轉(zhuǎn)化為屏幕坐標(biāo) 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)滑塊路徑及位置計(jì)算方法
首先不考慮xy正負(fù),
計(jì)算光標(biāo)位置點(diǎn)的正切值
tanφ = ly/lx;
可知φ
φ=arctan(tanφ)
根據(jù)圓的參數(shù)方程,可獲得光標(biāo)點(diǎn)對(duì)應(yīng)藍(lán)色路徑位置坐標(biāo)為
x=rcosφ
y=rsinφ
(4)根據(jù)上面思路編寫獲取坐標(biāo)位置方法,這里添加了xy和弧度值正負(fù)處理方法和可拖動(dòng)弧度范圍
getmoveto:function(lx,ly){ if(!this.p.isDown){ //是否可移動(dòng) return false; } var tem={}; //存放目標(biāo)坐標(biāo)位置 tem.o=Math.atan(ly/lx); //鼠標(biāo)移動(dòng)點(diǎn)圓形角 tem.x=this.pathr*Math.cos(tem.o); tem.y=this.pathr*Math.sin(tem.o); if(lx<0){ //坐標(biāo)點(diǎn)處理(正負(fù)) 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; },
(5)以上方法在canvas內(nèi)任意點(diǎn)均可作為滑塊拖動(dòng)的目標(biāo)點(diǎn),這里編寫cheack方法,將限制可拖動(dòng)位置限制在一個(gè)大概的環(huán)形里
check:function(x,y){ //限制可拖動(dòng)范圍 var xx=x*x; var yy=y*y; var rr=114*114; //最小 var rrr=126*126; //大 if(xx+yy>rr && xx+yy<rrr){ return true; } return false; },
5、事件方法編寫
(1)鼠標(biāo)按下執(zhí)行方法OnMouseDown
這里使用了getx和gety獲取光標(biāo)相對(duì)canvas坐標(biāo),并判斷鼠標(biāo)是否移動(dòng)到了滑塊上方位置內(nèi),(this.p是當(dāng)前繪圖對(duì)象,p.x即滑塊橫坐標(biāo),p.x即當(dāng)前縱坐標(biāo),p.r即滑塊大半徑),如果光標(biāo)在滑塊上方則設(shè)置isDown為TRUE,反正依然,后面我們會(huì)通過(guò)isDown來(lái)判斷是否執(zhí)行移動(dòng)滑塊的方法:
OnMouseDown:function(evt){ var X=this.getx(evt); //獲取當(dāng)前鼠標(biāo)位置橫坐標(biāo) var Y=this.gety(evt); //獲取當(dāng)前鼠標(biāo)位置縱坐標(biāo) 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<X && X<maxX && minY<Y && Y<maxY){ //判斷鼠標(biāo)是否在滑塊上 this.p.isDown=true; }else{ this.p.isDown=false; } }
(2)鼠標(biāo)按下后移動(dòng)時(shí)滑塊的方法:
OnMouseMove:function(evt){ // if(this.p.isDown){ //是否在滑塊上按下鼠標(biāo) var a={}; //存放當(dāng)前鼠標(biāo)坐標(biāo) a.x=this.getx(evt); //坐標(biāo)轉(zhuǎn)化 a.y=this.gety(evt); var b=this.spotchange(a); //坐標(biāo)轉(zhuǎn)化 var co=this.getmoveto(b.x,b.y); //獲取要移動(dòng)到的坐標(biāo)點(diǎn) if(this.check(b.x,b.y)){ //判斷移動(dòng)目標(biāo)點(diǎn)是否在可拖動(dòng)范圍 var co=this.getmoveto(b.x,b.y); //獲取到移動(dòng)的目標(biāo)位置坐標(biāo)() var tar=this.respotchange(co); //坐標(biāo)轉(zhuǎn)化 var o=co.z; this.p.draw(tar.x,tar.y,this.p.r,o); //繪圖 } } },
(3)鼠標(biāo)釋放方法
OnMouseUp:function(){ //鼠標(biāo)釋放 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); },
感謝各位的閱讀!關(guān)于“canvas如何實(shí)現(xiàn)弧形可拖動(dòng)進(jìn)度條效果”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站aaarwkj.com,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
標(biāo)題名稱:canvas如何實(shí)現(xiàn)弧形可拖動(dòng)進(jìn)度條效果-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)于:http://aaarwkj.com/article18/cocigp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、移動(dòng)網(wǎng)站建設(shè)、企業(yè)建站、小程序開(kāi)發(fā)、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容