基本用法

必须先设置其 width 和 height 属性,指定可以绘图的区域大小

  1. <canvas id="drawing" width=" 200" height="200">A drawing of something.</canvas>

取得绘图上下文对象的引用,需要调用 getContext()方法并传入上下文的名字。

传入”2d”,就可以取得 2D 上下文对象。

  1. var drawing = document.getElementById("drawing");
  2. //确定浏览器支持<canvas>元素
  3. if (drawing.getContext){
  4. var context = drawing.getContext("2d");
  5. }

2D

填充 fill

描边 stroke

isPointInPath(): 用于在路径被关闭之前确定画布上的某一点是否位于路径上

  1. if (context.isPointInPath(100, 100)){
  2. alert("Point (100, 100) is in the path.");
  3. }

绘制矩形

  • 在画布上绘制的矩形会填充指定的颜色
    fillStyle + fillRect(x, y, width, height)

  • 在画布上绘制的矩形会使用指定的颜色描边
    strokeStyle + strokeRect(x, y, width, height)

  • 清除画布上的矩形区域
    clearRect(x, y, width, height)

  1. var drawing = document.getElementById("drawing");
  2. if (drawing.getContext) {
  3. var context = drawing.getContext("2d");
  4. // 绘制矩形
  5. context.strokeStyle = "red";
  6. context.lineWidth = 3;
  7. context.lineCap = "round"; // butt, square, round
  8. context.strokeRect(10, 10, 50, 50);
  9. context.fillStyle = "#0f0";
  10. context.fillRect(10, 10, 50, 50);
  11. //绘制半透明的蓝色矩形
  12. context.fillStyle = "rgba(0,0,255,0.5)";
  13. context.fillRect(30, 30, 50, 50);
  14. // 挖孔
  15. context.clearRect(40, 40, 10, 10);
  16. }

绘制路径

  • arc(x, y, radius, startAngle, endAngle, counterclockwise)
    以(x,y)为圆心绘 制一条弧线,弧线半径为 radius,起始和结束角度(用弧度表示)分别为 startAngle 和 endAngle。最后一个参数表示 startAngle 和 endAngle 是否按逆时针方向计算,值为 false 表示按顺时针方向计算。

  • arcTo(x1, y1, x2, y2, radius)
    从上一点开始绘制一条弧线,到(x2,y2)为止,并且以 给定的半径 radius 穿过(x1,y1)。

  • bezierCurveTo(c1x, c1y, c2x, c2y, x, y)
    从上一点开始绘制一条曲线,到(x,y)为 止,并且以(c1x,c1y)和(c2x,c2y)为控制点。

  • lineTo(x, y)
    从上一点开始绘制一条直线,到(x,y)为止。

  • moveTo(x, y)
    将绘图游标移动到(x,y),不画线。

  • quadraticCurveTo(cx, cy, x, y)
    从上一点开始绘制一条二次曲线,到(x,y)为止,并且以(cx,cy)作为控制点。

  • rect(x, y, width, height)
    从点(x,y)开始绘制一个矩形,宽度和高度分别由 width 和 height 指定。这个方法绘制的是矩形路径,而不是 strokeRect()和 fillRect()所绘制的独

  1. var drawing = document.getElementById("drawing");
  2. if (drawing.getContext) {
  3. var context = drawing.getContext("2d");
  4. // start path
  5. // 要绘制路径,首先必须调用 beginPath()方法,表示要开始绘制新路径
  6. context.beginPath();
  7. // draw outer circle
  8. // (x, y, radius, startAngle, endAngle, counterclockwise)
  9. // 最后一个参数表示 startAngle 和 endAngle 是否按逆时针方向计算,值为 false 表示按顺时针方向计算。
  10. context.arc(100, 100, 99, 0, 2 * Math.PI, false);
  11. // draw inner circle
  12. context.moveTo(194, 100);
  13. context.arc(100, 100, 94, 0, 2 * Math.PI, false);
  14. // draw minute
  15. context.moveTo(100, 100);
  16. context.lineTo(100, 25);
  17. // draw hour
  18. context.moveTo(100, 100);
  19. context.lineTo(35, 100);
  20. // stroke
  21. context.stroke();
  22. }

绘制文本

fillText(content, x, y, [最大像素宽度])

strokeText(content, x, y, [最大像素宽度])

  1. context.font = "bold 14px Arial";
  2. context.textAlign = "center"; // start,end,center,left,right
  3. context.textBaseline = "middle"; // top, hanging, middle, alphabetic, ideographic, bottom
  4. context.fillText("12", 100, 20);

如果需要把文本控制在某一区域中的时候,2D 上下文提供了辅助确定文本大小的方法 measureText()

  1. var drawing = document.getElementById("drawing");
  2. if (drawing.getContext) {
  3. var context = drawing.getContext("2d");
  4. // "start"、"end"、"left"、"right"和"center"
  5. context.textAlign = "start";
  6. // "top"、"hanging"、"middle"、"alphabetic"、"ideographic"和"bottom"
  7. context.textBaseline = "top";
  8. var fontSize = 100;
  9. context.font = fontSize + "px Arial";
  10. while (context.measureText("Hello world!").width > 140) {
  11. fontSize--;
  12. context.font = fontSize + "px Arial";
  13. }
  14. context.fillText("Hello world!", 10, 10);
  15. context.fillText("Font size is " + fontSize + "px", 10, 50);
  16. }

变换

rotate(angle): 围绕原点旋转图像 angle 弧度。

scale(scaleX, scaleY): 缩放图像,在 x 方向乘以 scaleX,在 y 方向乘以 scaleY。scaleX 和 scaleY 的默认值都是 1.0。

translate(x,y): 将坐标原点移动到(x,y)。执行这个变换之后,坐标(0,0)会变成之前由(x,y)表示的点。

transform(m1_1, m1_2, m2_1, m2_2, dx, dy): 直接修改变换矩阵

setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy): 将变换矩阵重置为默认状态,然后 再调用 transform()。

save() 与 restore()

有两个方法可以跟踪上下文的状态变化。

如果你知道将来还要返回某组属性与变换的组合,可以调用 save()方法。 调用这个方法后,当时的所有设置都会进入一个栈结构,得以妥善保管。然后可以对上下文进行其他修改。

等想要回到之前保存的设置时,可以调用 restore()方法,在保存设置的栈结构中向前返回一级,恢复之前的状态。

连续调用 save()可以把更多设置保存到栈结构中,之后再连续调用 restore()则可以一级一级返回。

  1. var drawing = document.getElementById("drawing");
  2. if (drawing.getContext) {
  3. var context = drawing.getContext("2d");
  4. context.fillStyle = "#ff0000";
  5. context.save();
  6. context.fillStyle = "#00ff00";
  7. context.translate(100, 100);
  8. context.save();
  9. context.fillStyle = "#0000ff";
  10. context.fillRect(0, 0, 100, 200); //从点(100,100)开始绘制蓝色矩形
  11. context.restore();
  12. context.fillRect(10, 10, 100, 200); //从点(110,110)开始绘制绿色矩形
  13. context.restore();
  14. context.fillRect(0, 0, 100, 200); //从点(0,0)开始绘制红色矩形
  15. }

save()方法保存的只是对绘图上下文的设置和变换,不会保存绘图上下文的内容。

绘制图像

drawImage()

有三种不同的参数组合:

  1. // 第一种,图像大小与原始大小一样
  2. var image = document.images[0];
  3. context.drawImage(image, 10, 10);
  4. // 第二种,缩放图像,目标宽度和目标高度
  5. context.drawImage(image, 50, 10, 20, 30);
  6. // 第三种,把图像中的某个区域绘制到上下文中
  7. context.drawImage(image, 0, 10, 50, 50, 0, 100, 40, 60);
  8. // 9 个参数:
  9. // 要绘制的图像、
  10. // 源图像的 x 坐标、
  11. // 源图像的 y 坐标、
  12. // 源图像的宽度、
  13. // 源图像的高度、
  14. // 目标图像的 x 坐标、
  15. // 目标图像的 y 坐标、
  16. // 目标图像的宽度、
  17. // 目标图像的高度
  1. // 结合使用 drawImage()和其他方法,可以对图像进行各种基本操作。而操作的结果可以通过 toDataURL()方法获得。
  2. // 有一个例外,即图像不能来自其他域。如果图像来自其他域,调用 toDataURL()会抛出一个错误。
  3. //取得图像的数据URI
  4. var imgURI = drawing.toDataURL("image/png");
  5. //显示图像
  6. var image = document.createElement("img");
  7. image.src = imgURI;
  8. document.body.appendChild(image);

阴影

shadowColor: 用 CSS 颜色格式表示的阴影颜色,默认为黑色。 shadowOffsetX: 形状或路径 x 轴方向的阴影偏移量,默认为 0。 shadowOffsetY: 形状或路径 y 轴方向的阴影偏移量,默认为 0。 shadowBlur: 模糊的像素数,默认 0,即不模糊。

  1. var context = drawing.getContext("2d");
  2. //设置阴影
  3. context.shadowOffsetX = 5; context.shadowOffsetY = 5;
  4. context.shadowBlur = 4; context.shadowColor = "rgba(0, 0, 0, 0.5)";
  5. //绘制红色矩形
  6. context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50);
  7. //绘制蓝色矩形
  8. context.fillStyle = "rgba(0,0,255,1)";
  9. context.fillRect(30, 30, 50, 50);

渐变

线性渐变

createLinearGradient(start_x, start_y, end_x, end_y)`

创建一个指定大小的渐变,并返回 CanvasGradient 对象的实例

创建了渐变对象后,下一步就是使用 addColorStop()方法来指定色标。这个方法接收两个参数: 色标位置和 CSS 颜色值。色标位置是一个 0(开始的颜色)到 1(结束的颜色)之间的数字。

  1. var gradient = context.createLinearGradient(30, 30, 70, 70);
  2. gradient.addColorStop(0, "#fff");
  3. gradient.addColorStop(1, "#000");
  4. // context.fillStyle = "#0f0";
  5. context.fillStyle = gradient;
  6. context.fillRect(10, 10, 50, 50);

确保渐变与形状对齐非常重要

  1. function createRectLinearGradient(context, x, y, width, height){
  2. return context.createLinearGradient(x, y, x+width, y+height);
  3. }
  4. var gradient = createRectLinearGradient(context, 30, 30, 50, 50);
  5. gradient.addColorStop(0, "white");
  6. gradient.addColorStop(1, "black");
  7. //绘制渐变矩形
  8. context.fillStyle = gradient;
  9. context.fillRect(30, 30, 50, 50);

径向渐变

createRadialGradient(start_center_x, start_center_y, start_r, end_center_x, end_center_y, end_r)

  1. var r_gradient = context.createRadialGradient(55, 55, 10, 55, 55, 30);
  2. r_gradient.addColorStop(0, "#fff");
  3. r_gradient.addColorStop(1, "#000");
  4. //绘制半透明的蓝色矩形
  5. // context.fillStyle = "rgba(0,0,255,0.5)";
  6. context.fillStyle = r_gradient;
  7. context.fillRect(30, 30, 50, 50);

模式

createPattern(一个 HTML <img>元素, 一个表示如何重复图像的字符串)

  1. var image = document.images[0],
  2. pattern = context.createPattern(image, "repeat");
  3. //绘制矩形
  4. context.fillStyle = pattern; context.fillRect(10, 10, 150, 150);

使用图像数据

getImageData()

  1. var imageData = context.getImageData(10, 5, 50, 50);

灰阶过滤器

  1. var drawing = document.getElementById("drawing");
  2. //确定浏览器支持<canvas>元素
  3. if (drawing.getContext){
  4. var context = drawing.getContext("2d"),
  5. image = document.images[0],
  6. imageData, data,
  7. i, len, average,
  8. red, green, blue, alpha;
  9. //绘制原始图像
  10. context.drawImage(image, 0, 0);
  11. //取得图像数据
  12. imageData = context.getImageData(0, 0, image.width, image.height);
  13. data = imageData.data;
  14. for (i=0, len=data.length; i < len; i+=4){
  15. red = data[i];
  16. green = data[i+1];
  17. blue = data[i+2];
  18. alpha = data[i+3];
  19. //求得 rgb 平均值
  20. average = Math.floor((red + green + blue) / 3);
  21. //设置颜色值,透明度不变
  22. data[i] = average;
  23. data[i+1] = average;
  24. data[i+2] = average;
  25. }
  26. //回写图像数据并显示结果
  27. imageData.data = data; context.putImageData(imageData, 0, 0);
  28. }

合成

globalAlpha

globalAlpha 是一个介于 0 和 1 之间的值(包括 0 和 1),用于指定所有绘制的透明度。默认值为 0。

如果所有后续操作都要基于相同的透明度,就可以先把 globalAlpha 设置为适当值,然后绘制,最后再把它设置回默认值 0。

  1. //绘制红色矩形
  2. context.fillStyle = "#ff0000";
  3. context.fillRect(10, 10, 50, 50);
  4. //修改全局透明度
  5. context.globalAlpha = 0.5;
  6. //绘制蓝色矩形
  7. context.fillStyle = "rgba(0,0,255,1)";
  8. context.fillRect(30, 30, 50, 50);
  9. //重置全局透明度
  10. context.globalAlpha = 0;

globalCompositionOperation

表示后绘制的图形怎样与先绘制的图形结合