CoreThink&OpenCMF技術(shù)分享之:Canvas的應(yīng)用(一)

歡迎交流,互聯(lián)網(wǎng)產(chǎn)品開發(fā)解決方案CoreThink&OpenCMF:
http://www.corethink.cn

Canvas的應(yīng)用(一)
canvas是Html5中的一個新功能,它可以實現(xiàn)在一個矩形區(qū)域內(nèi)繪制一些簡單圖形的功能,最近很是熱衷于用它去實現(xiàn)一些交互動畫,要說如何應(yīng)用它,一言以蔽之,化繁為簡吧。不考慮時間的維度,在我們眼前定格的每一幀畫面,縱使再精美,也無外乎點(diǎn)線面的結(jié)合,所以能繪制基本的點(diǎn)、線、面也足以實現(xiàn)很多;要是考慮上時間這個維度,結(jié)合視覺暫留原理,就算沒有繪畫基礎(chǔ),也能實現(xiàn)簡單的動畫交互。
一、lineTo()的應(yīng)用——簽名
1.原理
原理其實很簡單,就是用極限的思想去看待鼠標(biāo)或者手指劃出的所有線條,當(dāng)線條無限短,我們就可以將它視為直線,短到什么程度呢,短到由兩個像素構(gòu)成,或水平或垂直或?qū)蔷€,所有的可能也無外乎如此,所以僅僅是lineTo()就能夠?qū)崿F(xiàn)簽名了,所以監(jiān)控鼠標(biāo)的mousemove事件,并獲取當(dāng)前事件對象坐標(biāo)即可。

canvas.addEventListener('mousemove',function(e) {

var x = e.clientX - this.offsetLeft;

var y = e.clientY - this.offsetTop;

Point.push([x,y]);

var len = Point.length;

if(flag) {

ct.beginPath();

ct.moveTo(Point[len-1][0],Point[len-1][1]);

ct.lineTo(Point[len-2][0],Point[len-2][1]);

ct.closePath();

ct.stroke();

}

});

將經(jīng)過的的所有點(diǎn)放在一個數(shù)組中,在當(dāng)前點(diǎn)和上一個點(diǎn)之間繪制路徑,簽名的基本功能就能夠?qū)崿F(xiàn)。
2.在手機(jī)上的實現(xiàn)
需要說明的一點(diǎn)是,在手機(jī)上event對象會有所不同,touches屬性是一個數(shù)組,會獨(dú)立記錄每個觸控點(diǎn)的信息,當(dāng)event.touches.length為1的時候,說明是一個觸控點(diǎn),event.touches.length為2的時候就是多點(diǎn)觸控,簽名自然是單點(diǎn)觸控,所以要獲取當(dāng)前坐標(biāo)就要從touches[0]取得。


canvas.addEventListener('touchmove',function(e) {

event.preventDefault();

if(e.touches.length == 1) {

var x = e.touches[0].clientX - this.offsetLeft;

var y = e.touches[0].clientY - this.offsetTop;

Point.push([x,y]);

var len = Point.length;

if(flag) {

ct.beginPath();

ct.moveTo(Point[len-1][0],Point[len-1][1]);

ct.lineTo(Point[len-2][0],Point[len-2][1]);

ct.closePath();

ct.stroke();

}

}

},false);

3.其他說明
如果僅僅是監(jiān)控move事件,那么在pc端只要鼠標(biāo)滑過就會繪制路徑,所以得設(shè)置一個開始繪制路徑的開關(guān),即將mousedown事件所謂開始繪制的標(biāo)志,mouseup則繪制結(jié)束。 當(dāng)簽名完成之后,調(diào)用canvas的toDataURL()可以獲取畫布內(nèi)的繪制信息,并以圖片的形式保存下來。
當(dāng)然這里其實存在一些遺留問題,如何對簽名進(jìn)行識別,如果需要識別,那是否應(yīng)該先對簽名做一些平滑處理,這一系列問題留待后續(xù)解決。
二、bezierCurveTo()的應(yīng)用1.貝塞爾曲線
關(guān)于貝塞爾曲線具體是什么,這里不做贅述,隨便一搜,各種百科說的很詳細(xì)。這邊主要要說的是貝塞爾曲線如何在canvas中加以應(yīng)用。這邊主要用到的是二次貝塞爾公式,即bezierCurveTo()的應(yīng)用,它有6個參數(shù),前兩個是起始點(diǎn)的坐標(biāo),中間兩個是控制點(diǎn)的坐標(biāo),最后兩個是終點(diǎn)的坐標(biāo),知道起點(diǎn)終點(diǎn)和一個控制點(diǎn),就能繪制我們想要的曲線了。
2.應(yīng)用
仔細(xì)觀察一些網(wǎng)站,很多地方都用到了直線變曲線、仿波浪形狀,或者一些不規(guī)則圖形,能夠?qū)崿F(xiàn)它們就是貝塞爾曲線的功勞,其中很著名的就是qq的消除氣泡。

effect:function(){

},

var canvas = this.canvas,

offset = this.offset,

ct = canvas.getContext("2d"),

ui = this.ui,

x1 = ui.originalPosition.left,

y1 = ui.originalPosition.top,

x = ui.offset.left,

y = ui.offset.top;

var base = Math.sqrt((x1-x)^2+(y1-y)^2),

sin = Math.abs(x1-x)/base,

cos = Math.abs(y1-y)/base;

ct.clearRect(0,0,400,200);

ct.beginPath();

ct.arc(x1,y1,10,0,2*Math.PI,false);

ct.fill();

ct.beginPath();

ct.moveTo(x1+cos,y1-sin);

ct.lineTo(x1-cos,y1+sin);

ct.bezierCurveTo(x1-cos,y1+sin,(x1+x)/2,(y1+y)/2,x-cos,y+sin);

ct.lineTo(x+cos,y-sin);

ct.bezierCurveTo(x+cos,y-sin,(x1+x)/2,(y1+y)/2,x1+cos,y1-sin);

ct.fill();

ct.beginPath();

ct.arc(x,y,10,0,2*Math.PI,false);

ct.fill();

這里貼出部分關(guān)鍵的代碼,就是拖拽那個氣泡出現(xiàn)的拉伸效果,如同拉扯一個有彈性的東西,被拉的越長就會越細(xì),在bezierCurveTo()通過設(shè)置合理的控制點(diǎn)就能很好的實現(xiàn)這個效果。其他更多的應(yīng)用,等有空把代碼寫出來再繼續(xù)咯。
CoreThink_張玥2016.7.4凌晨

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,063評論 25 709
  • 一:canvas簡介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,881評論 2 32
  • 書中代碼示例效果展示:Core HTML5 Canvas Examples 基礎(chǔ)知識 canvas元素 canva...
    szu_bee閱讀 3,049評論 2 28
  • 一、canvas簡介 1.1 什么是canvas?(了解) 是HTML5提供的一種新標(biāo)簽 Canvas是一個矩形區(qū)...
    Looog閱讀 4,041評論 3 40
  • 老話說,三搬當(dāng)一燒,這樣算來我們家被燒了好幾次了。 記憶里最早的搬家的印象,是我還不滿兩歲的時候。那時候,爸媽在一...
    Cathyinbetween閱讀 251評論 0 0

友情鏈接更多精彩內(nèi)容