Skip to content

Canvas 笔记

HTML5 画布(Canvas)元素

html
<canvas id="myCanvas" width="500" height="300"></canvas>
<canvas id="myCanvas" width="500" height="300"></canvas>

浏览器不支持画布(canvas)时的备案

html
<canvas id="myCanvas" width="500" height="300"> your browser doesn't support canvas! </canvas>
<canvas id="myCanvas" width="500" height="300"> your browser doesn't support canvas! </canvas>

2d context

javascript
var context = canvas.getContext("2d");
var context = canvas.getContext("2d");

Webgl context (3d)

javascript
var context = canvas.getContext("webgl");
var context = canvas.getContext("webgl");

图形

绘制方形

javascript
context.rect(x, y, width, height);
context.fill();
context.stroke();
context.rect(x, y, width, height);
context.fill();
context.stroke();

填充区域

javascript
context.fillRect(x, y, width, height);
context.fillRect(x, y, width, height);

绘制方形的边框

javascript
context.strokeRect(x, y, width, height);
context.strokeRect(x, y, width, height);

绘制圆形

javascript
context.arc(x, y, radius, 0, Math.PI * 2);
context.fill();
context.stroke();
context.arc(x, y, radius, 0, Math.PI * 2);
context.fill();
context.stroke();

风格

填充

javascript
context.fillStyle = "red";
context.fill();
context.fillStyle = "red";
context.fill();

勾勒

javascript
context.strokeStyle = "red";
context.stroke();
context.strokeStyle = "red";
context.stroke();

线性渐变

javascript
var grd = context.createLinearGradient(x1, y1, x2, y2);
grd.addColorStop(0, "red");
grd.addColorStop(1, "blue");
context.fillStyle = grd;
context.fill();
var grd = context.createLinearGradient(x1, y1, x2, y2);
grd.addColorStop(0, "red");
grd.addColorStop(1, "blue");
context.fillStyle = grd;
context.fill();

径向渐变

javascript
var grd = context.createRadialGradient(x1, y1, radius1, x2, y2, radius2);
grd.addColorStop(0, "red");
grd.addColorStop(1, "blue");
context.fillStyle = grd;
context.fill();
var grd = context.createRadialGradient(x1, y1, radius1, x2, y2, radius2);
grd.addColorStop(0, "red");
grd.addColorStop(1, "blue");
context.fillStyle = grd;
context.fill();

图案

javascript
var imageObj = new Image();
imageObj.onload = function () {
  var pattern = context.createPattern(imageObj, "repeat");
  context.fillStyle = pattern;
  context.fill();
};
imageObj.src = "path/to/my/image.jpg";
var imageObj = new Image();
imageObj.onload = function () {
  var pattern = context.createPattern(imageObj, "repeat");
  context.fillStyle = pattern;
  context.fill();
};
imageObj.src = "path/to/my/image.jpg";

交点

javascript
context.lineJoin = "miter|round|bevel";
context.lineJoin = "miter|round|bevel";

线头

javascript
context.lineCap = "butt|round|square";
context.lineCap = "butt|round|square";

阴影

javascript
context.shadowColor = "black";
context.shadowBlur = 20;
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowColor = "black";
context.shadowBlur = 20;
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;

Alpha (透明)

javascript
context.globalAlpha = 0.5; // between 0 and 1
context.globalAlpha = 0.5; // between 0 and 1

颜色格式

字符串

javascript
context.fillStyle = "red";
context.fillStyle = "red";

16 进制

javascript
context.fillStyle = "#ff0000";
context.fillStyle = "#ff0000";

16 进制简写

javascript
context.fillStyle = "#f00";
context.fillStyle = "#f00";

RGB

javascript
context.fillStyle = "rgb(255,0,0)";
context.fillStyle = "rgb(255,0,0)";

RGBA

javascript
context.fillStyle = "rgba(255,0,0,1)";
context.fillStyle = "rgba(255,0,0,1)";

路径

开始路径

javascript
context.beginPath();
context.beginPath();

画线

javascript
context.lineTo(x, y);
context.lineTo(x, y);

弧形

javascript
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);

二次曲线

javascript
context.quadraticCurveTo(cx, cy, x, y);
context.quadraticCurveTo(cx, cy, x, y);

三次曲线

javascript
context.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);
context.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);

关闭路径

javascript
context.closePath();
context.closePath();

文本

写文字

javascript
context.font = "40px Arial";
context.fillStyle = "red";
context.fillText("Hello World!", x, y);
context.font = "40px Arial";
context.fillStyle = "red";
context.fillText("Hello World!", x, y);

写镂空文字

javascript
context.font = "40pt Arial";
context.strokeStyle = "red";
context.strokeText("Hello World!", x, y);
context.font = "40pt Arial";
context.strokeStyle = "red";
context.strokeText("Hello World!", x, y);

粗体

javascript
context.font = "bold 40px Arial";
context.font = "bold 40px Arial";

斜体

javascript
context.font = "italic 40px Arial";
context.font = "italic 40px Arial";

对齐方式

javascript
context.textAlign = "start|end|left|center|right";
context.textAlign = "start|end|left|center|right";

文字基线

javascript
context.textBaseline = "top|hanging|middle|alphabetic|ideographic|bottom";
context.textBaseline = "top|hanging|middle|alphabetic|ideographic|bottom";

获取文本宽度

javascript
var width = context.measureText("Hello world").width;
var width = context.measureText("Hello world").width;

图片

画图

javascript
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, x, y);
};
imageObj.src = "path/to/my/image.jpg";
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, x, y);
};
imageObj.src = "path/to/my/image.jpg";

指定尺寸画图

javascript
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, x, y, width, height);
};
imageObj.src = "path/to/my/image.jpg";
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, x, y, width, height);
};
imageObj.src = "path/to/my/image.jpg";

裁剪图片

javascript
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, sx, sy, sw, sh, dx, dy, dw, dh);
};
imageObj.src = "path/to/my/image.jpg";
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, sx, sy, sw, sh, dx, dy, dw, dh);
};
imageObj.src = "path/to/my/image.jpg";

状态存储

存储

javascript
context.save();
context.save();

恢复

javascript
context.restore();
context.restore();

裁剪

javascript
// draw path here
context.clip();
// draw path here
context.clip();

动画

移动

javascript
context.translate(x, y);
context.translate(x, y);

扩大缩小

javascript
context.scale(x, y);
context.scale(x, y);

旋转

javascript
context.rotate(radians);
context.rotate(radians);

水平翻转

javascript
context.scale(-1, 1);
context.scale(-1, 1);

上下翻转

javascript
context.scale(1, -1);
context.scale(1, -1);

自定义变换

javascript
context.transform(a, b, c, d, e, f);
context.transform(a, b, c, d, e, f);

设置变换

javascript
context.setTransform(a, b, c, d, e, f);
context.setTransform(a, b, c, d, e, f);

切割

javascript
context.transform(1, sy, sx, 1, 0, 0);
context.transform(1, sy, sx, 1, 0, 0);

重置

javascript
context.setTransform(1, 0, 0, 1, 0, 0);
context.setTransform(1, 0, 0, 1, 0, 0);

Data URLs

获取 Data URL

javascript
var dataURL = canvas.toDataURL();
var dataURL = canvas.toDataURL();

使用 Data URL 生成图像

javascript
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, 0, 0);
};

imageObj.src = dataURL;
var imageObj = new Image();
imageObj.onload = function () {
  context.drawImage(imageObj, 0, 0);
};

imageObj.src = dataURL;

图像数据

获取图像数据

javascript
var imageData = context.getImageData(x, y, width, height);
var data = imageData.data;
var imageData = context.getImageData(x, y, width, height);
var data = imageData.data;

遍历像素点

javascript
var imageData = context.getImageData(x, y, width, height);
var data = imageData.data;
var len = data.length;
var i, red, green, blue, alpha;

for (i = 0; i < len; i += 4) {
  red = data[i];
  green = data[i + 1];
  blue = data[i + 2];
  alpha = data[i + 3];
}
var imageData = context.getImageData(x, y, width, height);
var data = imageData.data;
var len = data.length;
var i, red, green, blue, alpha;

for (i = 0; i < len; i += 4) {
  red = data[i];
  green = data[i + 1];
  blue = data[i + 2];
  alpha = data[i + 3];
}

沿坐标遍历像素点

javascript
var imageData = context.getImageData(x, y, width, height);
var data = imageData.data;
var x, y, red, green, blue, alpha;

for (y = 0; y < imageHeight; y++) {
  for (x = 0; x < imageWidth; x++) {
    red = data[(imageWidth * y + x) * 4];
    green = data[(imageWidth * y + x) * 4 + 1];
    blue = data[(imageWidth * y + x) * 4 + 2];
    alpha = data[(imageWidth * y + x) * 4 + 3];
  }
}
var imageData = context.getImageData(x, y, width, height);
var data = imageData.data;
var x, y, red, green, blue, alpha;

for (y = 0; y < imageHeight; y++) {
  for (x = 0; x < imageWidth; x++) {
    red = data[(imageWidth * y + x) * 4];
    green = data[(imageWidth * y + x) * 4 + 1];
    blue = data[(imageWidth * y + x) * 4 + 2];
    alpha = data[(imageWidth * y + x) * 4 + 3];
  }
}

设置图像数据

javascript
context.putImageData(imageData, x, y);
context.putImageData(imageData, x, y);

canvas-note-2023-07-23-23-42-00

合成

合成操作

javascript
context.globalCompositeOperation =
  "source-atop|source-in|source-out|source-over|destination-atop|destination-in|destination-out|destination-over|lighter|xor|copy";
context.globalCompositeOperation =
  "source-atop|source-in|source-out|source-over|destination-atop|destination-in|destination-out|destination-over|lighter|xor|copy";

canvas 利用 clip 清除不规则区域

canvas 的 API 中,可以清除像素的就是 clearRect 方法,但是 clearRect 方法的清除区域矩形,如何清除不规则图形呢?

我们引入了剪辑区域这个强大的功能,也就是 clip 方法。用法很简单:

javascript
ctx.save();
ctx.beginPath();
ctx.arc(x2, y2, a, 0, 2 * Math.PI);
ctx.clip();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.arc(x2, y2, a, 0, 2 * Math.PI);
ctx.clip();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();

上面那段代码就实现了圆形区域的擦除,也就是先实现一个圆形路径,然后把这个路径作为剪辑区域,再清除像素就行了。

有个注意点就是需要先保存绘图环境,清除完像素后要重置绘图环境,如果不重置的话以后的绘图都是会被限制在那个剪辑区域中。

最后编辑时间:

Version 4.0 (framework-1.0.0-rc.20)