Canvas 使用实例

动画效果

通过改变坐标,很容易在画布 Canvas 元素上产生动画效果。

  1. var canvas = document.getElementById('myCanvas');
  2. var ctx = canvas.getContext('2d');
  3. var posX = 20;
  4. var posY = 100;
  5. setInterval(function () {
  6. ctx.fillStyle = 'black';
  7. ctx.fillRect(0, 0, canvas.width, canvas.height);
  8. posX += 1;
  9. posY += 0.25;
  10. ctx.beginPath();
  11. ctx.fillStyle = 'white';
  12. ctx.arc(posX, posY, 10, 0, Math.PI * 2, true);
  13. ctx.closePath();
  14. ctx.fill();
  15. }, 30);

上面代码会产生一个小圆点,每隔30毫秒就向右下方移动的效果。setInterval()函数的一开始,之所以要将画布重新渲染黑色底色,是为了抹去上一步的小圆点。

在这个例子的基础上,通过设置圆心坐标,可以产生各种运动轨迹。下面是先上升后下降的例子。

  1. var vx = 10;
  2. var vy = -10;
  3. var gravity = 1;
  4. setInterval(function () {
  5. posX += vx;
  6. posY += vy;
  7. vy += gravity;
  8. // ...
  9. });

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

像素处理

通过getImageData()方法和putImageData()方法,可以处理每个像素,进而操作图像内容,因此可以改写图像。

下面是图像处理的通用写法。

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

上面代码中,filter是一个处理像素的函数。以下是几种常见的filter

(1)灰度效果

灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值,这实际上将图像转成了黑白形式。

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

上面代码中,d[i]是红色值,d[i+1]是绿色值,d[i+2]是蓝色值,d[i+3]是 alpha 通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以3,再将结果写回数组。

(2)复古效果

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

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

(3)红色蒙版效果

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

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

(4)亮度效果

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

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

(5)反转效果

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

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