搜尋
首頁web前端html教學HTML5中canvas的使用總結

1.概述

Canvas API(畫布)用於在網頁實時生成圖像,並且可以操作圖像內容,基本上它是一個可以用JavaScript操作的點陣圖(bitmap)。使用前,首先需要新建一個網頁元素。

<canvas id="myCanvas" width="400" height="200">
  您的浏览器不支持canvas!</canvas>

上面程式碼中,如果瀏覽器不支援這個API,就會顯示標籤中間的文字-「您的瀏覽器不支援canvas!」。

每個canvas節點都有一個對應的context物件(上下文物件),Canvas API定義在這個context物件上面,所以需要取得這個對象,方法是使用getContext方法。

var canvas = document.getElementById(&#39;myCanvas&#39;);
if (canvas.getContext) {
  var ctx = canvas.getContext(&#39;2d&#39;);
}

上面程式碼中,getContext方法指定參數2d,表示該canvas節點用於產生2D圖案(即平面圖案)。如果參數是webgl,就表示用於產生3D影像(即立體圖案),這部分其實單獨叫做WebGL API。

2.繪圖方法

canvas畫布提供了一個用來作圖的平面空間,該空間的每個點都有自己的座標,x表示橫座標,y表示垂直座標。原點(0, 0)位於影像左上角,x軸的正向是原點向右,y軸的正向是原點向下。

(1)繪製路徑

beginPath方法表示開始繪製路徑,moveTo(x, y)方法設定線段的起點,lineTo(x, y)方法設定線段的終點,stroke方法用來為透明的線段著色。

ctx.beginPath(); // 开始路径绘制
ctx.moveTo(20, 20); // 设置路径起点,坐标为(20,20)
ctx.lineTo(200, 20); // 绘制一条到(200,20)的直线
ctx.lineWidth = 1.0; // 设置线宽
ctx.strokeStyle = &#39;#CC0000&#39;; // 设置线的颜色
ctx.stroke(); // 进行线的着色,这时整条线才变得可见

moveto和lineto方法可以多次使用。最後,也可以使用closePath方法,自動繪製一條當前點到起點的直線,形成一個封閉圖形,省卻使用一次lineto方法。

(2)繪製矩形

fillRect(x, y, width, height)方法用來繪製矩形,它的四個參數分別為矩形左上角頂點的x座標、y座標,以及矩形的寬和高。 fillStyle屬性用來設定矩形的填滿色。

ctx.fillStyle = &#39;yellow&#39;;
ctx.fillRect(50, 50, 200, 100);

strokeRect方法與fillRect類似,用來繪製空心矩形。

ctx.strokeRect(10,10,200,100);

clearRect方法用來清除某個矩形區域的內容。

ctx.clearRect(100,50,50,50);

(3)繪製文本

fillText(string, x, y) 用來繪製文本,它的三個參數分別為文本內容、起點的x座標、y座標。使用前,需先用font設定字體、大小、樣式(寫法類似與CSS的font屬性)。與此類似的還有strokeText方法,用來加入空心字。

ctx.font = "Bold 20px Arial"; // 设置字体
ctx.textAlign = "left";// 设置对齐方式
ctx.fillStyle = "#008600"; // 设置填充颜色
ctx.fillText("Hello!", 10, 50); // 设置字体内容,以及在画布上的位置
ctx.strokeText("Hello!", 10, 100); // 绘制空心字

fillText方法不支援文字斷行,即所有文字出現在一行內。所以,如果要產生多行文本,只有呼叫多次fillText方法。

(4)繪製圓形和扇形

arc方法用來繪製扇形。

ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

arc方法的x和y參數是圓心座標,radius是半徑,startAngle和endAngle則是扇形的起始角度和終止角度(以弧度表示),anticlockwise表示做圖時應該逆時針畫(true)還是順時針畫(false)。

下面是如何繪製實心的圓形:

ctx.beginPath(); 
ctx.arc(60, 60, 50, 0, Math.PI*2, true); 
ctx.fillStyle = "#000000"; 
ctx.fill();

繪製空心圓形的例子:

ctx.beginPath(); 
ctx.arc(60, 60, 50, 0, Math.PI*2, true); 
ctx.lineWidth = 1.0; 
ctx.strokeStyle = "#000"; 
ctx.stroke();

(5)設定漸變色

createLinearGradient方法用來設定漸變色。

var myGradient = ctx.createLinearGradient(0, 0, 0, 160); 
myGradient.addColorStop(0, "#BABABA"); 
myGradient.addColorStop(1, "#636363");

createLinearGradient方法的參數是(x1, y1, x2, y2),其中x1和y1是起點座標,x2和y2是終點座標。透過不同的座標值,可以產生從上至下、從左到右的漸層等等。使用方法如下:

ctx.fillStyle = myGradient;
ctx.fillRect(10,10,200,100);

(6)設定陰影

一系列與陰影相關的方法,可以用來設定陰影。

ctx.shadowOffsetX = 10; // 设置水平位移
ctx.shadowOffsetY = 10; // 设置垂直位移
ctx.shadowBlur = 5; // 设置模糊度
ctx.shadowColor = "rgba(0,0,0,0.5)"; // 设置阴影颜色
ctx.fillStyle = "#CC0000"; 
ctx.fillRect(10,10,200,100);

3.影像處理方法

drawImage方法

Canvas API 允許將影像檔案插入畫布,做法是讀取圖片後,使用drawImage方法在畫布內進行重繪。

var img = new Image();
img.src = &#39;image.png&#39;;
ctx.drawImage(img, 0, 0); // 设置对应的图像对象,以及它在画布上的位置

上面程式碼將一個PNG圖像載入畫布。 drawImage()方法接受三個參數,第一個參數是影像檔案的DOM元素(即HTML5中canvas的使用總結節點),第二個和第三個參數是影像左上角在畫布中的座標,上例中的( 0, 0)就表示將影像左上角放置在畫布的左上角。

由於映像的載入需要時間,drawImage方法只能在映像完全載入後才能調用,因此上面的程式碼需要改寫。

var image = new Image();
image.onload = function() {
    var canvas = document.createElement(&#39;canvas&#39;);
    canvas.width = image.width;
    canvas.height = image.height;
    canvas.getContext(&#39;2d&#39;).drawImage(image, 0, 0);
    // 插入页面底部
    document.body.appendChild(image);
    return canvas;
}
image.src = &#39;image.png&#39;;

getImageData方法,putImageData方法

getImageData方法可以用來讀取Canvas的內容,傳回一個對象,包含了每個像素的資訊。

var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

imageData物件有一個data屬性,它的值是一個一維數組。此數組的值,依序為每個像素的紅、綠、藍、alpha通道值,因此該數組的長度等於 影像的像素寬度 x 影像的像素高度 x 4,每個值的範圍為0–255。這個數組不僅可讀,而且可寫,因此透過操作這個數組的值,就可以達到操作圖像的目的。修改這個陣列以後,使用putImageData方法將陣列內容重新繪製在Canvas上。

context.putImageData(imageData, 0, 0);

toDataURL方法

對影像資料做出修改以後,可以使用toDataURL方法,將Canvas資料重新轉換成一般的影像檔案形式。

function convertCanvasToImage(canvas) {
    var image = new Image();
    image.src = canvas.toDataURL(&#39;image/png&#39;);
    return image;
}

上面的程式碼將Canvas數據,轉換成PNG data URI。

save方法,restore方法

save方法用於保存上下文環境,restore方法用於恢復到上一次保存的上下文環境

ctx.save();
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 5;
ctx.shadowColor = &#39;rgba(0,0,0,0.5)&#39;;
ctx.fillStyle = &#39;#CC0000&#39;;
ctx.fillRect(10,10,150,100);
ctx.restore();
ctx.fillStyle = &#39;#000000&#39;;
ctx.fillRect(180,10,150,100);

上面代码先用save方法,保存了当前设置,然后绘制了一个有阴影的矩形。接着,使用restore方法,恢复了保存前的设置,绘制了一个没有阴影的矩形。

4.动画

利用JavaScript,可以在canvas元素上很容易地产生动画效果。

var posX = 20,
    posY = 100;
setInterval(function() {
    context.fillStyle = "black";
    context.fillRect(0,0,canvas.width, canvas.height);

    posX += 1;
    posY += 0.25;

    context.beginPath();
    context.fillStyle = "white";

    context.arc(posX, posY, 10, 0, Math.PI*2, true); 
    context.closePath();
    context.fill();
}, 30);

上面代码会产生一个小圆点,每隔30毫秒就向右下方移动的效果。setInterval函数的一开始,之所以要将画布重新渲染黑色底色,是为了抹去上一步的小圆点。
通过设置圆心坐标,可以产生各种运动轨迹。
先上升后下降。

var vx = 10,
    vy = -10,
    gravity = 1;
setInterval(function() {
    posX += vx;
    posY += vy;
    vy += gravity;
    // ...
});

上面代码中,x坐标始终增大,表示持续向右运动。y坐标先变小,然后在重力作用下,不断增大,表示先上升后下降。小球不断反弹后,逐步趋于静止。

var vx = 10,
    vy = -10,
    gravity = 1;
setInterval(function() {
    posX += vx;
    posY += vy;
    if (posY > canvas.height * 0.75) {
          vy *= -0.6;
          vx *= 0.75;
          posY = canvas.height * 0.75;
    }
    vy += gravity;
    // ...
});

上面代码表示,一旦小球的y坐标处于屏幕下方75%的位置,向x轴移动的速度变为原来的75%,而向y轴反弹上一次反弹高度的40%。

5.像素处理

通过getImageData方法和putImageData方法,可以处理每个像素,进而操作图像内容。假定filter是一个处理像素的函数,那么整个对Canvas的处理流程,可以用下面的代码表示。

if (canvas.width > 0 && canvas.height > 0) {
    var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
    filter(imageData);
    context.putImageData(imageData, 0, 0);
}

以下是几种常见的处理方法:

灰度效果

灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值,这实际上将图像转成了黑白形式。假定d[i]是像素数组中一个象素的红色值,则d[i+1]为绿色值,d[i+2]为蓝色值,d[i+3]就是alpha通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以3,再将结果写回数组。

grayscale = function (pixels) {
    var d = pixels.data;
    for (var i = 0; i < d.length; i += 4) {
      var r = d[i];
      var g = d[i + 1];
      var b = d[i + 2];
      d[i] = d[i + 1] = d[i + 2] = (r+g+b)/3;
    }
    return pixels;
};

复古效果

复古效果(sepia)则是将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。

sepia = function (pixels) {
    var d = pixels.data;
    for (var i = 0; i < d.length; i += 4) {
      var r = d[i];
      var g = d[i + 1];
      var b = d[i + 2];
      d[i]     = (r * 0.393)+(g * 0.769)+(b * 0.189); // red
      d[i + 1] = (r * 0.349)+(g * 0.686)+(b * 0.168); // green
      d[i + 2] = (r * 0.272)+(g * 0.534)+(b * 0.131); // blue
    }
    return pixels;
};

红色蒙版效果

红色蒙版指的是,让图像呈现一种偏红的效果。算法是将红色通道设为红、绿、蓝三个值的平均值,而将绿色通道和蓝色通道都设为0。

red = function (pixels) {
    var d = pixels.data;
    for (var i = 0; i < d.length; i += 4) {
      var r = d[i];
      var g = d[i + 1];
      var b = d[i + 2];
      d[i] = (r+g+b)/3;        // 红色通道取平均值
      d[i + 1] = d[i + 2] = 0; // 绿色通道和蓝色通道都设为0
    }
    return pixels;
};

亮度效果

亮度效果(brightness)是指让图像变得更亮或更暗。算法将红色通道、绿色通道、蓝色通道,同时加上一个正值或负值。

brightness = function (pixels, delta) {    var d = pixels.data;    for (var i = 0; i < d.length; i += 4) {
          d[i] += delta;     // red
          d[i + 1] += delta; // green
          d[i + 2] += delta; // blue   
    }    return pixels;
};

反转效果

反转效果(invert)是指图片呈现一种色彩颠倒的效果。算法为红、绿、蓝通道都取各自的相反值(255-原值)。

invert = function (pixels) {    var d = pixels.data;    for (var i = 0; i < d.length; i += 4) {
        d[i] = 255 - d[i];
        d[i+1] = 255 - d[i + 1];
        d[i+2] = 255 - d[i + 2];
    }    return pixels;
};


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何在 Bootstrap 4 中實現多項目輪播?如何在 Bootstrap 4 中實現多項目輪播?Apr 30, 2025 pm 03:24 PM

在Bootstrap4中實現多項目輪播的解決方案在Bootstrap4中實現多項目輪播並不是一件簡單的事情。雖然Bootstrap...

deepseek官網是如何實現鼠標滾動事件穿透效果的?deepseek官網是如何實現鼠標滾動事件穿透效果的?Apr 30, 2025 pm 03:21 PM

如何實現鼠標滾動事件穿透效果?在我們瀏覽網頁時,經常會遇到一些特別的交互設計。比如在deepseek官網上,�...

HTML 視頻的播放控件樣式怎麼修改HTML 視頻的播放控件樣式怎麼修改Apr 30, 2025 pm 03:18 PM

無法直接通過CSS修改HTML視頻的默認播放控件樣式。 1.使用JavaScript創建自定義控件。 2.通過CSS美化這些控件。 3.考慮兼容性、用戶體驗和性能,使用庫如Video.js或Plyr可簡化過程。

在手機上使用原生select會帶來哪些問題?在手機上使用原生select會帶來哪些問題?Apr 30, 2025 pm 03:15 PM

在手機上使用原生select的潛在問題在開發移動端應用時,我們常常會遇到選擇框的需求。通常情況下,開發者傾...

在手機上使用原生select的弊端是什麼?在手機上使用原生select的弊端是什麼?Apr 30, 2025 pm 03:12 PM

在手機上使用原生select的弊端是什麼?在移動設備上開發應用時,選擇合適的UI組件是非常重要的。許多開發者�...

如何使用Three.js和Octree優化房間內第三人稱漫遊的碰撞處理?如何使用Three.js和Octree優化房間內第三人稱漫遊的碰撞處理?Apr 30, 2025 pm 03:09 PM

使用Three.js和Octree優化房間內第三人稱漫遊的碰撞處理在Three.js中使用Octree實現房間內的第三人稱漫遊並添加碰�...

在手機上使用原生select會遇到哪些問題?在手機上使用原生select會遇到哪些問題?Apr 30, 2025 pm 03:06 PM

使用原生select在手機上的問題在移動設備上開發應用時,我們經常會遇到需要用戶進行選擇的場景。雖然原生sel...

為什麼有的網站能實現鼠標滾動穿透效果,而有的不行?為什麼有的網站能實現鼠標滾動穿透效果,而有的不行?Apr 30, 2025 pm 03:03 PM

探究鼠標滾動事件的實現原理在瀏覽一些網站時,你可能注意到某些頁面元素在鼠標懸停時仍然允許滾動整個頁...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具