canvas 圓弧形可拖動進度條

2022-03-30 19:50:13 字數 4543 閱讀 6400

import dragarc from 'drag-arc';
一、效果如下:

鏈結dome

二、本文是實現可拖動滑塊實現的基本思路,及乙個簡單的dome,(

三、1、首先在html中建立乙個canvas標籤

<

canvas

id="canvas"

width

="400"

height

="400"

>

canvas

>

2、建立乙個進度條物件,編寫初始化方法,獲取canvas物件及上下文環境;event方法是用來繫結事件(具體後面介紹);draw是用來繪圖的方法,這裡把draw物件的全部方法賦給draw方法;建立繪圖例項p,繪製初始圖形;

var draw= 

//...

}

3、在draw中編寫繪圖方法draw繪製下圖:

(1)建立繪圖方法,獲取引數

draw:function(x,y,r,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),

gety:

function(ev)

(2)為方便構建圓的方程,這裡建立乙個以canvas中心為原點的座標系,如下圖,在實際使用draw方法繪圖時使用的是黑色的座標系,在使用圓的路徑處理是我們使用紅色的座標系

下面新增座標轉化方法,

螢幕座標(黑色座標)->中心座標(紅色座標)

spotchange:function(a);

if(a.x<200 && a.y<200)

else

if(a.x>200 && a.y<200)

else

if(a.x>200 && a.y>200)

else

if(a.x<200 && a.y>200)

return

target;

},

中心座標(紅色座標)->螢幕座標(黑色座標)

respotchange:function(a);

if(a.x>0 && a.y>0)

else

if(a.x<0 && a.y>0)

else

if(a.x<0 && a.y<0)

else

if(a.x>0 && a.y<0)

return

target;

},

(3)滑塊路徑及位置計算方法

首先不考慮xy正負,

計算游標位置點的正切值

tanφ = ly/lx;

可知φ

φ=arctan(tanφ)

根據圓的引數方程,可獲得光標點對應藍色路徑位置座標為

x=rcosφ

y=rsinφ

(4)根據上面思路編寫獲取座標位置方法,這裡新增了xy和弧度值正負處理方法和可拖動弧度範圍

getmoveto:function

(lx,ly)

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)

if(lx>0)else

if(tem.z>7.06)

if(tem.z<2.4)

return

tem;

},

(5)以上方法在canvas內任意點均可作為滑塊拖動的目標點,這裡編寫cheack方法,將限制可拖動位置限制在乙個大概的環形裡

check:function(x,y)

return

false

; },

5、事件方法編寫

(1)滑鼠按下執行方法onmousedown

這裡使用了getx和gety獲取游標相對canvas座標,並判斷滑鼠是否移動到了滑塊上方位置內,(this.p是當前繪圖物件,p.x即滑塊橫座標,p.x即當前縱座標,p.r即滑塊最大半徑),如果游標在滑塊上方則設定isdown為true,反正依然,後面我們會通過isdown來判斷是否執行移動滑塊的方法:

onmousedown:function

(evt)

else

}

(2)滑鼠按下後移動時滑塊的方法:

onmousemove:function(evt);         //

存放當前滑鼠座標

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))}},

(3)滑鼠釋放方法

onmouseup:function(),
(4)最後將所有方法和事件繫結

event:function(),
至此可拖動滑塊基本方法編寫完成

使用canvas畫圓形(弧形)進度條

效果如下 可以展示整個圓 半圓以及任意角度弧形 左右對稱 的進度條。整體思路如下 完整 如下 關於動畫部分,可以使用requestanimationframe做優化,函式改寫如下 function draw percent,sr if sr math.pi 2 sr 3 2 math.pi var ...

ios弧形進度條 iOS 圓形進度條

釋放雙眼,帶上耳機,聽聽看 今天產品要弄乙個圓形的進度條 有很多開源的進度條不用,非要弄這種效果,就不吐槽了,還是想想怎麼實現 廢話就不多說了 直接上 import inte ce roundprogressview uiview 進度條顏色 property strong,nonatomic ui...

ios弧形進度條 ios 圓形進度條

今天產品要弄乙個圓形的進度條 有很多開源的進度條不用,非要弄這種效果,就不吐槽了,還是想想怎麼實現 廢話就不多說了 直接上 import inte ce roundprogressview uiview 進度條顏色 property strong,nonatomic uicolor progress...