canvas實現簡單的Amaziograph效果畫對稱圖

標題很難引人入勝,先放個效果圖好了

strip

如果圖片吸引不了你,那我覺得也就沒啥看的了。

demo鏈接:https://win7killer.github.io/can_demo/demo/draw_roll_2.html

*************************************************

上次“雷達圖效果”文章很榮幸,被“某天頭條”抓數據抓去了,不開心的是demo鏈接等所有鏈接都幹掉了~~~  blabla,連個名字都木有。

想看的再看下:http://www.cnblogs.com/ufex/p/6655336.html

*************************************************

創意來源

之前看到的gif效果,爲了這個文章又去找了一下。貌似是ipad的app “Amaziograph”。看起來真的很爽,很美

配上我自己畫的圖先:

1240

手殘不會畫畫,各位見笑。(手機上瀏覽器畫的哦)

DEMO講解

1.效果分析

a.參考線座標軸 -- 爲了簡單控制參考線顯示隱藏,單獨一個canvas來搞,也不用每次重繪

b.繪畫主體 -- 繪畫效果(canvas畫線);對稱效果(canvas旋轉)

c.配置區 -- 簡單dom

簡單來看,很容易實現嘛

2.開搞

1> 座標系統

其實就是畫幾條線,但是要均分角度。一種方法是,計算出各個點,然後從中心點發散去畫線;另一種是,一邊旋轉canvas,一邊畫圓心到統一座標的線。由於繪畫是需用到canvas旋轉,所以這裏統一使用旋轉來處理。

那麼,就需要先來處理canvas旋轉

strip

1functiondrawRotate(deg, fn, _ctx) {2_ctx = _ctx ||ctx3_ctx.save();4_ctx.translate(_ctx.canvas.width / 2, _ctx.canvas.height / 2);5_ctx.rotate(deg);6fn &&fn(_ctx);7_ctx.restore();8}

strip

當然,這個是我嘗試多次之後寫好的方法。

1、存儲ctx狀態到棧,

2、移動旋轉點(canvas座標原點)到canvas中心,

3、旋轉指定角度,

4、執行繪製函數fn,

5、從棧裏邊取回ctx的狀態(包含但不僅包含 fillStyle、strokenStyle、translate等等),這裏主要處理的是translate,因爲我們下次用到座標會受影響,所以要讓canva座標原點回到原來的位置。

其實這裏translate還是比較抽象比較繞的。。。可能我比較遲緩

然後,是繪製參考線座標

strip

1functionbaseLine() {2ctx_role.clearRect(0, 0, ctx_role.canvas.width, ctx_role.canvas.height);3vardeg = 360 /pieace;4console.log(deg);5ctx_role.lineWidth = 1;6ctx_role.strokeStyle = 'rgba(0,0,0,.5)';7for(vari = 0, l = pieace; i < l; i++) {8drawRotate(i * deg / 180 * Math.PI,function(ctx_role) {9draw({10bx: can_role.width / 2,11by: can_role.width / 2,12ex: can_role.width / 2 +can_role.width,13ey: can_role.width / 214}, ctx_role);15}, ctx_role);16}17}

strip

strip

1functiondraw(option, _ctx) {2_ctx = _ctx ||ctx;3_ctx.beginPath();4_ctx.moveTo(option.bx - _ctx.canvas.width / 2, option.by - _ctx.canvas.height / 2);5_ctx.lineTo(option.ex - _ctx.canvas.width / 2, option.ey - _ctx.canvas.height / 2);6_ctx.stroke();7}

strip

這樣,就繪製完成參考線。

2>繪畫主體

首先處理一般的畫線。跟拖拽效果類似,在move過沖中一直畫線鏈接兩個點。對拖拽不瞭解的可以去了解下,直接上代碼

strip

1functionbindPc() {2can. =function(e) {3if(e.button != 0) {4returnfalse;5}67varop ={};8op.ex = op.bx = e.clientX - can.parentElement.offsetLeft +window.scrollX;9op.ey = op.by = e.clientY - can.parentElement.offsetTop +window.scrollY;10drawFn(op);11document. =function(e) {12document.body.style.cursor = 'pointer';13op.bx =op.ex;14op.by =op.ey;15op.ex = e.clientX - can.parentElement.offsetLeft +window.scrollX;16op.ey = e.clientY - can.parentElement.offsetTop +window.scrollY;17drawFn(op);18};19document. =function() {20document.body.style.cursor = 'default';21document. = document. =null;22};23};24}

strip

strip

1functiondrawFn(op) {2vardeg = Math.floor(360 /pieace);3for(vari = 0, l = 360; i < l; i +=deg) {4drawRotate(i / 180 * Math.PI,function(ctx) {5draw(op);6});7}8}

strip

需要注意,e.button 用來判斷是鼠標哪個鍵,0是左鍵

這裏又用到了前邊的drawRotate 和 draw。

************************************

至此,應該可以畫出對稱的線條了。

以下就是錦上添花的事情了

************************************

增加移動端的繪製支持(慚愧,沒怎麼寫過移動端,歡迎多指教)

strip

1functionbindWp() {2can.addEventListener('touchstart',function(e) {3op = can.op ={};4op.ex = op.bx = e.touches[0].clientX - can.parentElement.offsetLeft +window.scrollX;5op.ey = op.by = e.touches[0].clientY - can.parentElement.offsetTop +window.scrollY;6drawFn(op);7can.addEventListener('touchmove', touchMoveFn);8can.addEventListener('touchend', touchEndFn);9});1011functiontouchEndFn() {12document.body.style.cursor = 'default';13can.removeEventListener('touchmove', touchMoveFn);14can.removeEventListener('touchend', touchEndFn);15}1617functiontouchMoveFn(e) {18op =can.op;19document.body.style.cursor = 'pointer';20op.bx =op.ex;21op.by =op.ey;22op.ex = e.touches[0].clientX - can.parentElement.offsetLeft +window.scrollX;23op.ey = e.touches[0].clientY - can.parentElement.offsetTop +window.scrollY;24drawFn(op);25returnfalse;26}27}

strip

3>設置等

這裏dom比較簡單,就略過了。只說一項,下載canvas圖片到本地

最簡單的,右鍵保存圖片到本地,但是你肯定會罵我傻,誰不知道這操作啊;那麼就來稍微裝X一下吧

線上代碼

strip

1functiondownload() {2vardata = can.toDataURL('p_w_picpath/png', 0.8);3var$a = document.createElement('a');4$a.download = imgName.value || 'default.png';5$a.target = '_blank';6$a.href =data;7$a.click();8}

strip

(寫這個博客的時候,返現自己把這個方法寫麻煩了,繞遠了。/手動尷尬,這裏直接改了)

關鍵點在於a.download屬性,這個是把文件下載到本地的關鍵哦,然後要把canvas轉成base64(canvas.toDataUrl方法,不清楚的可以去去了解下,這裏不再贅述)

******************************************************

最後,附上完整代碼(可能會和上邊的有點出如,還在調整)

+ View Code

**************偷偷留個名字,防抓  博客園-fe-bean***************

涉及姿勢點總結

1.canvas_translate

2.canvas_rotate

3.canvas_toDataUrl

4.a.download  &&  base64

其餘的想起來再添加吧

最後,歡迎大家多提意見、交流,點贊轉載那就更棒了。

再丟一張圖

strip

下期再見咯~~~

****************   少俠留步,能看到這裏的,我要給你們一個獎勵   ***************

這個demo是可以在移動端玩的,意味着有電容筆的親,可以爽啊~(個別瀏覽器腦殘會左右來回跑~~)

沒有電容筆的親,肯定是大多數,我們一樣能玩啊!!!

叫你們快速做一款電容筆(當然沒那麼好用)

1.找一隻木質鉛筆

2.削出鉛筆頭

3.把鉛筆頭斜着磨平,如圖

1240

4.用磨平這一側去電容屏上畫(開始吧)

我上邊那張圖就是拿鉛筆畫的~~~

歡迎加入技術qq羣:364595326


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章