標(biāo)題很難引人入勝申眼,先放個(gè)效果圖好了
如果圖片吸引不了你娄柳,那我覺得也就沒啥看的了零蓉。
demo鏈接:https://win7killer.github.io/can_demo/demo/draw_roll_2.html
*************************************************
上次“雷達(dá)圖效果”文章很榮幸糜工,被“某天頭條”抓數(shù)據(jù)抓去了捕传,不開心的是demo鏈接等所有鏈接都干掉了~~~ ?blabla筐骇,連個(gè)名字都木有债鸡。
想看的再看下:http://www.cnblogs.com/ufex/p/6655336.html
*************************************************
創(chuàng)意來源
之前看到的gif效果,為了這個(gè)文章又去找了一下铛纬。貌似是ipad的app “Amaziograph”厌均。看起來真的很爽告唆,很美
配上我自己畫的圖先:
手殘不會(huì)畫畫棺弊,各位見笑。(手機(jī)上瀏覽器畫的哦)
DEMO講解
1.效果分析
a.參考線坐標(biāo)軸 -- 為了簡(jiǎn)單控制參考線顯示隱藏擒悬,單獨(dú)一個(gè)canvas來搞模她,也不用每次重繪
b.繪畫主體 -- 繪畫效果(canvas畫線);對(duì)稱效果(canvas旋轉(zhuǎn))
c.配置區(qū) -- 簡(jiǎn)單dom
簡(jiǎn)單來看懂牧,很容易實(shí)現(xiàn)嘛
2.開搞
1> 坐標(biāo)系統(tǒng)
其實(shí)就是畫幾條線侈净,但是要均分角度。一種方法是僧凤,計(jì)算出各個(gè)點(diǎn)畜侦,然后從中心點(diǎn)發(fā)散去畫線;另一種是躯保,一邊旋轉(zhuǎn)canvas旋膳,一邊畫圓心到統(tǒng)一坐標(biāo)的線。由于繪畫是需用到canvas旋轉(zhuǎn)途事,所以這里統(tǒng)一使用旋轉(zhuǎn)來處理验懊。
那么,就需要先來處理canvas旋轉(zhuǎn)
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}
當(dāng)然尸变,這個(gè)是我嘗試多次之后寫好的方法鲁森。
1、存儲(chǔ)ctx狀態(tài)到棧振惰,
2、移動(dòng)旋轉(zhuǎn)點(diǎn)(canvas坐標(biāo)原點(diǎn))到canvas中心垄懂,
3骑晶、旋轉(zhuǎn)指定角度痛垛,
4、執(zhí)行繪制函數(shù)fn桶蛔,
5匙头、從棧里邊取回ctx的狀態(tài)(包含但不僅包含 fillStyle、strokenStyle仔雷、translate等等),這里主要處理的是translate蹂析,因?yàn)槲覀兿麓斡玫阶鴺?biāo)會(huì)受影響,所以要讓canva坐標(biāo)原點(diǎn)回到原來的位置碟婆。
其實(shí)這里translate還是比較抽象比較繞的电抚。。竖共◎眩可能我比較遲緩
然后,是繪制參考線坐標(biāo)
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}
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}
這樣公给,就繪制完成參考線借帘。
2>繪畫主體
首先處理一般的畫線。跟拖拽效果類似淌铐,在move過沖中一直畫線鏈接兩個(gè)點(diǎn)肺然。對(duì)拖拽不了解的可以去了解下,直接上代碼
1functionbindPc() {2can.onmousedown =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.onmousemove =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.onmouseup =function() {20document.body.style.cursor = 'default';21document.onmouseup = document.onmousemove =null;22};23};24}
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}
需要注意腿准,e.button 用來判斷是鼠標(biāo)哪個(gè)鍵际起,0是左鍵
這里又用到了前邊的drawRotate 和?draw。
************************************
至此释涛,應(yīng)該可以畫出對(duì)稱的線條了加叁。
以下就是錦上添花的事情了
************************************
增加移動(dòng)端的繪制支持(慚愧,沒怎么寫過移動(dòng)端唇撬,歡迎多指教)
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}
3>設(shè)置等
這里dom比較簡(jiǎn)單它匕,就略過了。只說一項(xiàng)窖认,下載canvas圖片到本地
最簡(jiǎn)單的豫柬,右鍵保存圖片到本地,但是你肯定會(huì)罵我傻扑浸,誰(shuí)不知道這操作吧崭;那么就來稍微裝X一下吧
線上代碼
1functiondownload() {2vardata = can.toDataURL('image/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}
(寫這個(gè)博客的時(shí)候喝噪,返現(xiàn)自己把這個(gè)方法寫麻煩了础嫡,繞遠(yuǎn)了。/手動(dòng)尷尬,這里直接改了)
關(guān)鍵點(diǎn)在于a.download屬性榴鼎,這個(gè)是把文件下載到本地的關(guān)鍵哦伯诬,然后要把canvas轉(zhuǎn)成base64(canvas.toDataUrl方法,不清楚的可以去去了解下巫财,這里不再贅述)
******************************************************
最后盗似,附上完整代碼(可能會(huì)和上邊的有點(diǎn)出如,還在調(diào)整)
**************偷偷留個(gè)名字平项,防抓 ?博客園-fe-bean***************
涉及姿勢(shì)點(diǎn)總結(jié)
1.canvas_translate
2.canvas_rotate
3.canvas_toDataUrl
4.a.download ?&& ?base64
其余的想起來再添加吧
最后赫舒,歡迎大家多提意見、交流闽瓢,點(diǎn)贊轉(zhuǎn)載那就更棒了接癌。
再丟一張圖
下期再見咯~~~
**************** ? 少俠留步,能看到這里的鸳粉,我要給你們一個(gè)獎(jiǎng)勵(lì) ? ***************
這個(gè)demo是可以在移動(dòng)端玩的扔涧,意味著有電容筆的親,可以爽啊~(個(gè)別瀏覽器腦殘會(huì)左右來回跑~~)
沒有電容筆的親届谈,肯定是大多數(shù)枯夜,我們一樣能玩啊<枭健:ⅰ!
叫你們快速做一款電容筆(當(dāng)然沒那么好用)
1.找一只木質(zhì)鉛筆
2.削出鉛筆頭
3.把鉛筆頭斜著磨平曙搬,如圖
4.用磨平這一側(cè)去電容屏上畫(開始吧)
我上邊那張圖就是拿鉛筆畫的~~~
歡迎加入技術(shù)qq群:364595326