91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

canvas如何實現弧形可拖動進度條效果

發布時間:2021-05-12 13:58:11 來源:億速云 閱讀:386 作者:小新 欄目:web開發

這篇文章給大家分享的是有關canvas如何實現弧形可拖動進度條效果的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

一、效果如下:

canvas如何實現弧形可拖動進度條效果

二、

本文是實現可拖動滑塊實現的基本思路,及一個簡單的dome,(https://github.com/pangyongsheng/canvas-arc-draw)

三、

1、首先在html中創建一個canvas標簽

<canvas id="canvas"  width="400" height="400"></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繪制下圖:

canvas如何實現弧形可拖動進度條效果

(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如何實現弧形可拖動進度條效果

編寫獲取當前光標位置點相對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方法繪圖時使用的是黑色的坐標系,在使用圓的路徑處理是我們使用紅色的坐標系

canvas如何實現弧形可拖動進度條效果

下面添加坐標轉化方法,

屏幕坐標(黑色坐標)->中心坐標(紅色坐標)

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)滑塊路徑及位置計算方法

canvas如何實現弧形可拖動進度條效果

 首先不考慮xy正負,

  計算光標位置點的正切值

  tanφ = ly/lx;

  可知φ

  φ=arctan(tanφ)

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

  x=rcosφ

  y=rsinφ

(4)根據上面思路編寫獲取坐標位置方法,這里添加了xy和弧度值正負處理方法和可拖動弧度范圍

getmoveto: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;
 },

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

check: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<rrr){
 return true;
 }
 return false;
 },

5、事件方法編寫

(1)鼠標按下執行方法OnMouseDown

這里使用了getx和gety獲取光標相對canvas坐標,并判斷鼠標是否移動到了滑塊上方位置內,(this.p是當前繪圖對象,p.x即滑塊橫坐標,p.x即當前縱坐標,p.r即滑塊最大半徑),如果光標在滑塊上方則設置isDown為TRUE,反正依然,后面我們會通過isDown來判斷是否執行移動滑塊的方法:

OnMouseDown: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<X && X<maxX && minY<Y && Y<maxY){ //判斷鼠標是否在滑塊上 
  this.p.isDown=true; 
 }else{
  this.p.isDown=false;
 }
}

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

OnMouseMove: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); //繪圖
  }
 }
 },

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

感謝各位的閱讀!關于“canvas如何實現弧形可拖動進度條效果”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

忻城县| 类乌齐县| 黑河市| 长葛市| 中西区| 兰州市| 寿阳县| 延安市| 都江堰市| 广丰县| 崇文区| 宁明县| 太谷县| 武陟县| 长治市| 宁陵县| 宣武区| 民县| 榕江县| 德惠市| 黔江区| 吉隆县| 汉沽区| 湾仔区| 中西区| 翁牛特旗| 漳平市| 南昌县| 仙居县| 沁水县| 时尚| 临沧市| 峡江县| 松阳县| 曲麻莱县| 都安| 南华县| 瑞昌市| 旬邑县| 公主岭市| 大兴区|