日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Canvas從入門到小豬頭

通過本文你將了解canvas簡介及其比較常用的方法,并利用canvas實現(xiàn)一個小豬頭。

10年積累的做網(wǎng)站、成都做網(wǎng)站經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有平山免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

一、Canvas簡介

1.1 什么是canvas

Canvas(畫布)是在HTML5中新增的標(biāo)簽用于在網(wǎng)頁實時生成圖像,可以操作圖像內(nèi)容,是一個可以用JavaScript操作的位圖(bitmap)。

1.2 canvas的坐標(biāo)系統(tǒng)

canvas的坐標(biāo)系統(tǒng)如下圖所示,其具有如下特點:

  • x軸正方向向右、y軸正方向向下
  • 畫布的原點在左上角
  • 橫縱坐標(biāo)單位為像素
  • 每個軸的最小單元為一個像素(柵格)

1.3 canvas的繪制流程

  1. 創(chuàng)建一個標(biāo)簽
  2. 獲取canvas元素對應(yīng)的DOM對象,這是一個Canvas對象
  3. 調(diào)用Canvas對象的getContext()方法,該方法返回一個CanvasRenderingContext2D對象,該對象即可繪制圖形
  4. 調(diào)用CanvasRenderingContext2D對象的方法繪圖

1.4 canvas的應(yīng)用領(lǐng)域

canvas這個神奇的東西有很多領(lǐng)域可以得到應(yīng)用,下面我們一起嘮一嘮。

  1. 游戲:canvas 在基于 Web 的圖像顯示方面比 Flash 更加立體、更加精巧,canvas 游戲在流暢度和跨平臺方面更優(yōu)秀,例如這25款canvas游戲
  2. 可視化的庫:Echart
  3. banner廣告:Canvas 實現(xiàn)動態(tài)的廣告效果非常合適
  4. 圖形編輯器:后續(xù)Photoshop能夠100%基于Web實現(xiàn)
  5. 微信讀書、騰訊文檔均是通過canvas實現(xiàn)

二、基礎(chǔ)功能

通過第一章對canvas有了初步的認(rèn)識,本章就按照一個人繪制一幅畫的思路進(jìn)行演化,逐步了解canvas的基本功能,從而更好的使用它實現(xiàn)一些酷炫的效果。

2.1 坐標(biāo)系選擇

當(dāng)要繪制一幅畫時首先要確定坐標(biāo)系,只有選擇好了坐標(biāo)系之后才好動筆,在canvas中默認(rèn)坐標(biāo)系在左上角(X軸正方向向右、Y軸正方向向下),可是有的時候需要變換坐標(biāo)系才能更方便的實現(xiàn)所需的效果,此時需要變換坐標(biāo)系,canvas提供了以下幾種變換坐標(biāo)系的方式:

  1. translate(dx,dy):平移坐標(biāo)系。相當(dāng)于把原來位于(0,0)位置的坐標(biāo)原點平移到(dx、dy)點。
  2. rotate(angle):旋轉(zhuǎn)坐標(biāo)系。該方法控制坐標(biāo)系統(tǒng)順時針旋轉(zhuǎn)angle弧度。
  3. scale(sx,sy):縮放坐標(biāo)系。該方法控制坐標(biāo)系統(tǒng)水平方向上縮放sx,垂直方向上縮放sy。
  4. transform(a,b,c,d,e,f):允許縮放、旋轉(zhuǎn)、移動并傾斜當(dāng)前的環(huán)境坐標(biāo)系,其中a表示水平縮放、b表示水平切斜、c表示垂直切斜、d表示垂直縮放、e表示水平移動、f表示垂直移動。

 
 
 
 
  1. function main() {
  2.     const canvas = document.getElementById('canvasId');
  3.     const ctx = canvas.getContext('2d');
  4.     ctx.lineWidth = 4;
  5.     // 默認(rèn)
  6.     ctx.save();
  7.     ctx.strokeStyle = '#F00';
  8.     drawCoordiante(ctx);
  9.     ctx.restore();
  10.     // 平移
  11.     ctx.save();
  12.     ctx.translate(150, 150);
  13.     ctx.strokeStyle = '#0F0';
  14.     drawCoordiante(ctx);
  15.     ctx.restore();
  16.     // 旋轉(zhuǎn)
  17.     ctx.save();
  18.     ctx.translate(300, 300);
  19.     ctx.rotate(-Math.PI / 2);
  20.     ctx.strokeStyle = '#00F';
  21.     drawCoordiante(ctx);
  22.     ctx.restore();
  23.     // 縮放
  24.     ctx.save();
  25.     ctx.translate(400, 400);
  26.     ctx.rotate(-Math.PI / 2);
  27.     ctx.scale(0.5, 0.5);
  28.     ctx.strokeStyle = '#000';
  29.     drawCoordiante(ctx);
  30.     ctx.restore();
  31. }
  32. function drawCoordiante(ctx) {
  33.     ctx.beginPath();
  34.     ctx.moveTo(0, 0);
  35.     ctx.lineTo(120, 0);
  36.     ctx.moveTo(0, 0);
  37.     ctx.lineTo(0, 80);
  38.     ctx.closePath();
  39.     ctx.stroke();
  40. }
  41. main();

2.2 圖形繪制

坐標(biāo)系選擇好了之后,就要開始動筆創(chuàng)作大作了,那么canvas到底允許繪制哪些內(nèi)容呢?

直線

 
 
 
 
  1. function drawLine(ctx, startX, startY, endX, endY) {
  2.     ctx.moveTo(startX, startY);
  3.     ctx.lineTo(endX, endY);
  4.     ctx.stroke();
  5. }

圓弧

 
 
 
 
  1. function drawCircle(ctx, x, y, R, startAngle, endAngle) {
  2.     ctx.arc(x, y, R, startAngle, endAngle);
  3.     ctx.stroke();
  4. }

曲線

 
 
 
 
  1. // 貝濟(jì)埃曲線
  2. function drawBezierCurve(ctx, cpX1, cpY1, cpX, cpY2, endX, endY) {
  3.     ctx.bezierCurveTo(cpX1, cpY1, cpX, cpY2, endX, endY);
  4.     ctx.stroke();
  5. }
  6. // 二次曲線
  7. function drawQuadraticCurve(ctx, cpX, cpY, endX, endY) {
  8.     ctx.quadraticCurveTo(cpX, cpY, endX, endY);
  9.     ctx.stroke();
  10. }

矩形

 
 
 
 
  1. // 填充矩形
  2. function drawFillRect(ctx, x, y, width, height) {
  3.     ctx.fillRect(x, y, width, height);
  4. }
  5. // 邊框矩形
  6. function drawStrokeRect(ctx, x, y, width, height) {
  7.     ctx.strokeRect( x, y, width, height);
  8. }

字符串

 
 
 
 
  1. // 填充字符串
  2. function drawFillText(ctx, text, x, y) {
  3.     ctx.fillText(text, x, y);
  4. }
  5. // 邊框字符串
  6. function drawStrokeText(ctx, text, x, y) {
  7.     ctx.strokeText(text, x, y);
  8. }

復(fù)雜圖形繪制——路徑

 
 
 
 
  1. // 利用路徑繪制
  2. function drawFigureByPath(ctx) {
  3.     ctx.beginPath();
  4.     ctx.moveTo(100, 400);
  5.     ctx.lineTo(200, 450);
  6.     ctx.lineTo(150, 480);
  7.     ctx.closePath();
  8.     ctx.fill();
  9. }
 
 
 
 
  1. function main() {
  2.     const canvas = document.getElementById('canvasId');
  3.     const ctx = canvas.getContext('2d');
  4.     ctx.lineWidth = 2;
  5.     ctx.strokeStyle = '#F00';
  6.     ctx.fillStyle = '#F00';
  7.     ctx.font = 'normal 50px 宋體';
  8.     drawLine(ctx, 50, 10, 150, 10);
  9.     ctx.moveTo(150, 100);
  10.     drawCircle(ctx, 100, 100, 50, 0, Math.PI);
  11.     ctx.moveTo(300, 100);
  12.     drawCircle(ctx, 250, 100, 50, 0, Math.PI * 2);
  13.     ctx.moveTo(350, 150);
  14.     drawBezierCurve(ctx, 200, 200, 450, 250, 300, 300);
  15.     ctx.moveTo(50, 250);
  16.     drawQuadraticCurve(ctx, 50, 400, 80, 400);
  17.     drawFillRect(ctx, 100, 300, 100, 50);
  18.     drawStrokeRect(ctx, 300, 300, 100, 50);
  19.     drawFillText(ctx, 'I', 100, 400);
  20.     drawStrokeText(ctx, 'I', 300, 400);
  21.     drawFigureByPath(ctx);
  22. }

2.3 填充風(fēng)格

利用canvas繪制圖形時勢必要上點顏料,通過設(shè)置fillStyle屬性即可設(shè)置對應(yīng)的顏料,對于顏料值主要有以下四種:純顏色、線性漸變顏色、徑向漸變顏色、位圖。

純顏色

 
 
 
 
  1. function useColorFill(ctx) {
  2.     ctx.save();
  3.     ctx.fillStyle = '#F00';
  4.     ctx.fillRect(10, 10, 100, 100);
  5.     ctx.restore();
  6. }

線性漸變顏色

 
 
 
 
  1. function useLinearGradientFill(ctx) {
  2.     ctx.save();
  3.     const lg = ctx.createLinearGradient(110, 10, 210, 10);
  4.     lg.addColorStop(0.2, '#F00');
  5.     lg.addColorStop(0.5, '#0F0');
  6.     lg.addColorStop(0.9, '#00F');
  7.     ctx.fillStyle = lg;
  8.     ctx.fillRect(120, 10, 100, 100);
  9.     ctx.restore();
  10. }

徑向漸變顏色

 
 
 
 
  1. function useRadialGradientFill(ctx) {
  2.     ctx.save();
  3.     const lg = ctx.createRadialGradient(260, 60, 10, 260, 60, 60);
  4.     lg.addColorStop(0.2, '#F00');
  5.     lg.addColorStop(0.5, '#0F0');
  6.     lg.addColorStop(0.9, '#00F');
  7.     ctx.fillStyle = lg;
  8.     ctx.fillRect(230, 10, 100, 100);
  9.     ctx.restore();
  10. }

位圖填充

 
 
 
 
  1. function useImageFill(ctx) {
  2.     ctx.save();
  3.     const image = new Image();
  4.     image.src = 'https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=442547030,98631113&fm=58';
  5.     image.onload = function () {
  6.         // 創(chuàng)建位圖填充
  7.         const imgPattern = ctx.createPattern(image, 'repeat');
  8.         ctx.fillStyle = imgPattern;
  9.         ctx.fillRect(340, 10, 100, 100);
  10.         ctx.restore();
  11.     }
  12. }

2.4 臨時保存

用一只畫筆在畫某個美女時,忽然來了靈感需要畫另一個帥哥,這個時候又不想放棄這個美女,則就需要將當(dāng)前畫美女的顏料、坐標(biāo)等狀態(tài)進(jìn)行暫存,等到畫完帥哥后恢復(fù)狀態(tài)進(jìn)行美女的繪制。在canvas中可以通過save()和restore()方法實現(xiàn),調(diào)用save()方法后將這一時刻的設(shè)置放到一個暫存棧中,然后可以放心的修改上下文,在需要繪制之前的上下文時,可以調(diào)用restore()方法。

 
 
 
 
  1. // 從左往右是依次繪制(中間為用新的樣式填充,最后一個是恢復(fù)到原來樣式填充)
  2. function main() {
  3.     const canvas = document.getElementById('canvasId');
  4.     const ctx = canvas.getContext('2d');
  5.     ctx.fillStyle = '#F00';
  6.     ctx.fillRect(10, 10, 100, 100);
  7.     ctx.save();
  8.     ctx.fillStyle = '#0F0';
  9.     ctx.fillRect(150, 10, 100, 100);
  10.     ctx.restore();
  11.     ctx.fillRect(290, 10, 100, 100);
  12. }

2.5 引入外部圖像

有的時候需要引入外部圖片,然后對外部圖片進(jìn)行像素級別的處理,最后進(jìn)行保存。

  1. 繪制圖像:drawImage
  2. 取得圖像數(shù)據(jù):getIamgeData
  3. 將修改后的數(shù)據(jù)重新填充到Canvas中:putImageData
  4. 輸出位圖:toDataURL

 
 
 
 
  1. function main() {
  2.     const canvas = document.getElementById('canvasId');
  3.     const ctx = canvas.getContext('2d');
  4.     const image = document.getElementById('image');
  5.     // 繪制圖像
  6.     ctx.drawImage(image, 0, 0);
  7.     // 獲取圖像數(shù)據(jù)
  8.     const imageData = ctx.getImageData(0, 0, image.width, image.height);
  9.     const data = imageData.data;
  10.     for (let i = 0, len = data.length; i < len; i += 4) {
  11.         const red = data[i];
  12.         const green = data[i + 1];
  13.         const blue = data[i + 2];
  14.         const average = Math.floor((red + green + blue) / 3);
  15.         data[i] = average;
  16.         data[i + 1] = average;
  17.         data[i + 2] = average;
  18.     }
  19.     imageData.data = data;
  20.     ctx.putImageData(imageData, 0, 0);
  21.     document.getElementById('result').src = canvas.toDataURL('image/png');
  22. }

三、豬頭實戰(zhàn)

學(xué)習(xí)了這么多,就利用canvas繪制一個豬頭吧,畢竟每個程序員身邊肯定有一個陪伴自己的小胖豬,嘿嘿。

 
 
 
 
  1. function main() {
  2.     const canvas = document.getElementById('canvasId');
  3.     const ctx = canvas.getContext('2d');
  4.     ctx.lineWidth = 4;
  5.     ctx.strokeStyle = '#000';
  6.     ctx.fillStyle = '#ffd8e1';
  7.     ctx.translate(260, 20);
  8.     drawPigEar(ctx);
  9.     ctx.save();
  10.     ctx.rotate(Math.PI / 2);
  11.     drawPigEar(ctx);
  12.     ctx.restore();
  13.     drawPigFace(ctx);
  14.     ctx.save();
  15.     ctx.translate(-100, -100);
  16.     drawPigEye(ctx);
  17.     ctx.restore();
  18.     ctx.save();
  19.     ctx.translate(100, -100);
  20.     drawPigEye(ctx);
  21.     ctx.restore();
  22.     ctx.save();
  23.     ctx.translate(0, 60);
  24.     drawPigNose(ctx);
  25.     ctx.restore();
  26. }
  27. function drawPigEar(ctx) {
  28.     ctx.save();
  29.     ctx.beginPath();
  30.     ctx.arc(-250, 0, 250, 0, -Math.PI / 2, true);
  31.     ctx.arc(0, -250, 250, -Math.PI, Math.PI / 2, true);
  32.     ctx.closePath();
  33.     ctx.fill();
  34.     ctx.stroke();
  35.     ctx.restore();
  36. }
  37. function drawPigFace(ctx) {
  38.     ctx.save();
  39.     ctx.beginPath();
  40.     ctx.arc(0, 0, 250, 0, Math.PI * 2);
  41.     ctx.fill();
  42.     ctx.stroke();
  43.     ctx.closePath();
  44.     ctx.restore();
  45. }
  46. function drawPigEye(ctx) {
  47.     ctx.save();
  48.     ctx.fillStyle = '#000';
  49.     ctx.beginPath();
  50.     ctx.arc(0, 0, 20, 0, Math.PI * 2);
  51.     ctx.closePath();
  52.     ctx.fill();
  53.     ctx.restore();
  54. }
  55. function drawPigNose(ctx) {
  56.     ctx.save();
  57.     ctx.fillStyle = '#fca7aa';
  58.     ctx.beginPath();
  59.     ctx.ellipse(0, 0, 150, 100, 0, 0, Math.PI * 2);
  60.     ctx.closePath();
  61.     ctx.fill();
  62.     ctx.stroke();
  63.     ctx.save();
  64.     ctx.translate(-60, 0);
  65.     drawPigNostrils(ctx);
  66.     ctx.restore();
  67.     ctx.save();
  68.     ctx.translate(60, 0);
  69.     drawPigNostrils(ctx);
  70.     ctx.restore();
  71.     ctx.restore();
  72. }
  73. function drawPigNostrils(ctx) {
  74.     ctx.save();
  75.     ctx.fillStyle = '#b55151';
  76.     ctx.beginPath();
  77.     ctx.ellipse(0, 0, 40, 60, 0, 0, Math.PI * 2);
  78.     ctx.closePath();
  79.     ctx.fill();
  80.     ctx.stroke();
  81.     ctx.restore();
  82. }
  83. main();

本文轉(zhuǎn)載自微信公眾號「執(zhí)鳶者」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系執(zhí)鳶者公眾號。


網(wǎng)頁標(biāo)題:Canvas從入門到小豬頭
地址分享:http://www.dlmjj.cn/article/dhohihd.html