欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

canvas實(shí)現(xiàn)弧形可拖動(dòng)進(jìn)度條效果

 更新時(shí)間:2017年05月11日 08:46:38   作者:龐永勝  
本篇文章主要介紹了canvas實(shí)現(xiàn)弧形可拖動(dòng)進(jìn)度條的實(shí)例方法,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧

一、效果如下:

二、

本文是實(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ì)通過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);
 },

至此可拖動(dòng)滑塊基本方法編寫完成

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • JavaScript實(shí)現(xiàn)向setTimeout執(zhí)行代碼傳遞參數(shù)的方法

    JavaScript實(shí)現(xiàn)向setTimeout執(zhí)行代碼傳遞參數(shù)的方法

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)向setTimeout執(zhí)行代碼傳遞參數(shù)的方法,分析了向setTimeout傳遞參數(shù)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Eclipse編輯jsp、js文件時(shí)卡死現(xiàn)象的解決辦法匯總

    Eclipse編輯jsp、js文件時(shí)卡死現(xiàn)象的解決辦法匯總

    使用Eclipse編輯jsp、js文件時(shí),經(jīng)常出現(xiàn)卡死現(xiàn)象,在網(wǎng)上百度了N次,經(jīng)過N次優(yōu)化調(diào)整后,卡死現(xiàn)象逐步好轉(zhuǎn),下面通過腳本之家平臺(tái)給大家分享幾種解決辦法,需要的朋友參考下
    2016-02-02
  • 微信小程序如何實(shí)現(xiàn)精確的日期時(shí)間選擇器

    微信小程序如何實(shí)現(xiàn)精確的日期時(shí)間選擇器

    這篇文章主要介紹了微信小程序如何實(shí)現(xiàn)精確的日期時(shí)間選擇器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 自定義require函數(shù)讓瀏覽器按需加載Js文件

    自定義require函數(shù)讓瀏覽器按需加載Js文件

    可能很多人看到這個(gè)題目就會(huì)想到LABjs、RequireJS、SeaJS... 這些庫(kù),但無(wú)奈小編沒用過這些庫(kù),什么 AMD 、CMD 哪來(lái)那么多術(shù)語(yǔ)... 前端的庫(kù)太多了,要看各種亂七八糟的文檔,好難啊,還不如自己寫一個(gè)庫(kù)呢。于是就有了這文章,有需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • JavaScript實(shí)現(xiàn)經(jīng)典貪吃蛇游戲

    JavaScript實(shí)現(xiàn)經(jīng)典貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)經(jīng)典貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JavaScript判斷文件是否存在的實(shí)例代碼

    JavaScript判斷文件是否存在的實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于JavaScript判斷文件是否存在的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 關(guān)于JS中的全等和不全等、等于和不等于問題

    關(guān)于JS中的全等和不全等、等于和不等于問題

    等號(hào)和非等號(hào)的同類運(yùn)算符是全等號(hào)和非全等號(hào)。這兩個(gè)運(yùn)算符所做的與等號(hào)和非等號(hào)相同,只是它們?cè)跈z查相等性前,不執(zhí)行類型轉(zhuǎn)換。接下來(lái)通過本文給大家介紹JS中的全等和不全等、等于和不等于,一起看看吧
    2021-09-09
  • document.all與getElementById、getElementsByName、getElementsByTagName用法區(qū)別-getElementById

    document.all與getElementById、getElementsByName、getElementsByT

    HTML DOM 定義了多種查找元素的方法,除了 getElementById() 之外,還有 getElementsByName() 和 getElementsByTagName()。
    2008-12-12
  • 深入理解JS addLoadEvent函數(shù)

    深入理解JS addLoadEvent函數(shù)

    下面小編就為大家?guī)?lái)一篇深入理解JS addLoadEvent函數(shù)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2016-05-05
  • Javascript中的Prototype到底是什么

    Javascript中的Prototype到底是什么

    Javascript也是面向?qū)ο蟮恼Z(yǔ)言,但它是一種基于原型Prototype的語(yǔ)言,而不是基于類的語(yǔ)言。接下來(lái)通過本文給大家介紹Javascript中的Prototype到底是啥的相關(guān)知識(shí),感興趣的朋友參考下
    2016-02-02

最新評(píng)論