標籤:

前端小項目:使用canvas繪畫哆啦A夢

最近在學canvas元素,<canvas>標籤只是圖形容器,必須使用js來繪製圖形。為了增強對canvas元素的理解,於是用canvas畫了一個哆啦A夢來

要實現的效果圖

在線預覽

要想繪畫出這個哆啦a夢首先要掌握以下一些函數:

  • arcTo()
  • canvas繪製圓形或弧線
  • bezierCurveTo()
  • quadraticCurveTo()

開始繪畫!!

首先我們需要創建一個400*600的畫布,代碼如下:

<canvas id="doraemon" width="400" height="600"></canvas>n

接著定義一個div,用來顯示坐標

<div id="put" style="width: 50px" height="20px"></div>n

接著我寫了一個顯示坐標的函數,可以用來看大概畫到哪個點:

function zuobiao(event) {n var x = event.clientX;n var y = event.clientY;n var out = document.getElementById("put");n out.innerHTML = "x:" + x + " y:" + y;n }n

然後getContext() 方法返回一個用於在畫布上繪圖的環境。

var cxt = document.getElementById(doraemon).getContext(2d);n

接著開始畫頭部:

cxt.beginPath();//起始路徑n cxt.lineWidth = 1;//線寬度為1n cxt.strokeStyle = #000;//筆觸的顏色n cxt.arc(200, 175, 175, 0.7 * Math.PI, 0.3 * Math.PI);//繪製弧,中心點(200,175),半徑175n cxt.fillStyle = #0bb0da;//設置填充時的顏色n cxt.fill();//填充顏色n cxt.stroke();//繪製路徑n

頭部如下:

接著繪畫出臉部:

cxt.beginPath();n cxt.fillStyle = #fff;n cxt.moveTo(110, 110);//將路徑移到點(110,110),不創建線條n cxt.quadraticCurveTo(-10, 200, 120, 315);//創建二次貝塞爾曲線,控制點(-10,200),結束點(120,315)n cxt.lineTo(280, 315);//添加一個新點,然後在畫布中創建從(110,110)到(280,315)的線條n cxt.quadraticCurveTo(410, 210, 290, 110);n cxt.lineTo(110, 110);n cxt.fill();n cxt.stroke();n

臉部如下:n

接著繪畫眼睛:

cxt.beginPath();n cxt.lineWidth = 1;n cxt.fillStyle = #fff;n cxt.moveTo(110, 110);n cxt.bezierCurveTo(110, 25, 200, 25, 200, 100);//創建三次貝塞爾曲線,控制點1(110,25),控制點2(200,25),結束點(200,100),也就是畫左上半橢圓n cxt.bezierCurveTo(200, 175, 110, 175, 110, 100);//畫左下半橢圓n cxt.moveTo(200, 100);n cxt.bezierCurveTo(200, 25, 290, 25, 290, 100);n cxt.bezierCurveTo(290, 175, 200, 175, 200, 100);n cxt.fill();n cxt.stroke();n

眼睛:

接著畫左右眼球:

/*右眼球*/n cxt.beginPath();n cxt.fillStyle = #000;n cxt.arc(230, 130, 12, 0, 2 * Math.PI);n cxt.fill();n cxt.stroke();n /*左眼球*/n cxt.beginPath();n cxt.fillStyle = #000;n cxt.arc(170, 130, 12, 0, 2 * Math.PI);n cxt.fill();n cxt.stroke();n

左右眼球:

接著畫鼻子:

cxt.beginPath();n cxt.arc(200, 165, 25, 0, 2 * Math.PI);n cxt.fillStyle = #d05823;n cxt.fill();n cxt.stroke();n

鼻子:

接著畫鬍鬚:

//左鬍鬚n cxt.beginPath();n cxt.moveTo(80, 175);n cxt.lineTo(150, 195);n cxt.moveTo(80, 200);n cxt.lineTo(150, 205);n cxt.moveTo(80, 225);n cxt.lineTo(150, 215);n //中部鬍鬚n cxt.moveTo(200, 195);n cxt.lineTo(200, 290);n //右鬍鬚n cxt.moveTo(250, 195);n cxt.lineTo(320, 175);n cxt.moveTo(250, 205);n cxt.lineTo(320, 200);n cxt.moveTo(250, 215);n cxt.lineTo(320, 225);n cxt.stroke();n

鬍鬚:

接著畫嘴:

cxt.moveTo(80, 240);n cxt.quadraticCurveTo(200, 350, 320, 240);n cxt.stroke();n

嘴:n

接下來畫圍巾:

cxt.beginPath();n cxt.moveTo(96, 316);n cxt.lineTo(305, 316);n cxt.lineTo(320, 316);n cxt.arcTo(330, 316, 330, 326, 10);//在畫布上創建介於兩個切線之間的弧,起點坐標為(330,316),終點坐標為(330,326),半徑為10n cxt.lineTo(330, 336);n cxt.arcTo(330, 346, 305, 346, 10);n cxt.lineTo(81, 346);n cxt.arcTo(71, 346, 71, 336, 10);n cxt.lineTo(71, 326);n cxt.arcTo(71, 316, 81, 316, 10);n cxt.lineTo(96, 316);n cxt.fillStyle = #b13209;n cxt.fill();n cxt.stroke();n

圍巾:

接著畫衣服:

cxt.beginPath();n cxt.fillStyle = #0bb0da;n cxt.moveTo(80, 346);n //左衣服n cxt.lineTo(26, 406);n cxt.lineTo(65, 440);n cxt.lineTo(85, 418);n cxt.lineTo(85, 528);n cxt.lineTo(185, 528);n //右衣服n cxt.lineTo(315, 528);n cxt.lineTo(315, 418);n cxt.lineTo(337, 440);n cxt.lineTo(374, 406);n cxt.lineTo(320, 346);n cxt.fill();n cxt.stroke();n

衣服:n

接著畫手:

//左手n cxt.beginPath();n cxt.fillStyle = #fff;n cxt.arc(37, 433, 30, 0, 2 * Math.PI);n cxt.fill();n cxt.stroke();n //右手n cxt.beginPath();n cxt.fillStyle = #fff;n cxt.arc(363, 433, 30, 0, 2 * Math.PI);n cxt.fill();n cxt.stroke();n

手:

接著畫肚:

cxt.beginPath();n cxt.fillStyle = #fff;n cxt.arc(200, 400, 91, 1.8 * Math.PI, 1.2 * Math.PI);n cxt.fill();n cxt.stroke();n

肚:n

接著畫小口袋

cxt.beginPath();n cxt.fillStyle = #fff;n cxt.moveTo(130, 394);n cxt.lineTo(270, 394);n cxt.moveTo(130, 394);n cxt.bezierCurveTo(130, 490, 270, 490, 270, 394);n cxt.fill();n cxt.stroke();n

小口袋:

最後畫兩隻腳以及兩隻腳的的空隙:

/*兩隻腳的空隙*/n cxt.beginPath();n cxt.fillStyle = #fff;n cxt.arc(200, 529, 20,Math.PI, 0);n cxt.fill();n cxt.stroke();n /*腳*/n //左腳n cxt.beginPath();n cxt.fillStyle=#fff;n cxt.moveTo(180,528);n cxt.lineTo(72,528);n cxt.bezierCurveTo(52,528,52,558,72,558);n cxt.lineTo(180,558);n cxt.moveTo(180,558);n cxt.bezierCurveTo(200,558,200,528,180,528);n cxt.fill();n cxt.stroke();n //右腳n cxt.beginPath();n cxt.fillStyle=#fff;n cxt.moveTo(220,528);n cxt.lineTo(328,528);n cxt.bezierCurveTo(348,528,348,558,328,558);n cxt.lineTo(220,558);n cxt.moveTo(220,558);n cxt.bezierCurveTo(200,558,200,528,220,528);n cxt.fill();n cxt.stroke();n

完成了︿( ̄︶ ̄)︿n

完整代碼請點擊:哆啦A夢

推薦閱讀:

如何評價耗子在segmentfault的《web 安全之 xss 漏洞攻擊》live?
[新課發布] 深入淺出 JPEG 壓縮原理(下)
十八相送一水黑,看上去就像黑社會。一條龍學習計劃,舒服
【 js 基礎 】【 源碼學習 】源碼設計 (更新了backbone分析)
前端開發的模塊化和組件化的定義,以及兩者的關係?

TAG:前端开发 |