Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Gray-Ice

个人博客兼个人网站

我先把整体需要明白的内容都放在最上面这一行。
创建canvas元素至少要设置宽和高。
2D绘图上下文提供了绘制方法,包括矩形,弧形和路径。2D上下文的坐标原点(0, 0)在canvas元素的左上角。所有坐标值都相对于该点计算。因为x坐标向右增长,y坐标向下增长。默认情况下,width和height表示两个方向上像素的最大值。
fill和stroke是两种绘图的方式,可以简单理解为fill为填充绘图,stroke为描边绘图。
那么下面是一些常用的方法。
canvas.getContext(contextId, options); 这个方法十分的重要,其作用是获取上下文。在2d绘图中参数一般只填写”2d”,如:canvas.getContext(“2d”);
canvas.toDataURL(MIMEType); 这个方法用于导出canvas元素上的图像。这个方法接受一个参数: 要生成图像的MIME类型(与用来创建图形的上下文无关)。
context.fillStyle = “Style”; context为canvas.getContext(“2d”)得到的返回值。这个属性用于设置fill的样式。样式可以是CSS支持的任意格式: 名称,十六进制代码,rgb,rgba,hsl或hsla。如:canvas.fillStyle = “#ffffff”或canvas.fillStyle = “rgb(255, 255, 255)”
context.strokeStyle = “Style”; 这个属性用于设置stroke的样式。其与fillStyle一样,也支持CSS的任意格式。

绘制矩形

context.fillRect(x, y, width, height); 这个方法用于绘制fill矩形。从(x, y)坐标点开始,绘制一个宽width,高height的矩形。
context.strokeRect(x, y, width, height); 这个方法用于绘制stroke矩形。从(x, y)坐标点开始,绘制一个宽width,高height的矩形。
context.clearRect(x, y, width, height); 这个方法用于擦除一片矩形区域,从(x, y)坐标点开始, 擦除一片宽width, 高height的矩形空间。
context.lineWidth = width; 这个属性用于控制描边宽度,它可以是任意整数值。

绘制路径

context.beginPath(); 这个方法表示要开始绘制新路径,在开始绘制路径之前必须要调用这个方法。
context.fill(); 用fill的形式绘制路径。
context.stroke(); 用stroke的形式绘制路径。
context.arc(x, y, radius, startAngle, endAngle, counterclockwise); 这个方法用于绘制弧线。它以(x, y)为圆心,以radius为半径,以startAngle为起始角度,以endAngle为结束角度绘制一条弧线。couterclockwise接受一个布尔值,表示是顺时针绘制还是逆时针绘制。默认为顺时针。
context.arcTo(x1, y1, x2, y2, radius); 以给定半径radius,经由(x1, y1)绘制一条从上到(x2, y2)的弧线。
context.bezierCurveTo(c1x, c1y, c2x, c2y, x, y); 以(c1x, c1y)和(c2x, c2y)为控制点,绘制一条从上一点到(x, y)的弧线(三次贝赛尔曲线)。
context.lineTo(x, y); 绘制一条从上一点到(x, y)的直线。
context.moveTo(x, y); 不绘制线条,只把绘制光标移动到(x, y)。
context.quadraticCurveTo(cx, cy, x, y); 以(cx, cy)为控制点,绘制一条从上一点到(x, y)的弧线(二次贝赛尔曲线)。
context.rect(x, y, width, height); 以给定宽度和高度在坐标点(x, y)绘制一个矩形。这个方法与strokeRect()和fillRect()的区别在于,它创建的是一条路径,而不是独立的图形。
context.closePath(); 绘制一条返回起点的线。
context.isPointInPath(x, y); 这个方法用于确定指定的点是否在路径上,可以在关闭路径前随时调用。
context.clip() 基于已有路径创建一个新剪切区域。

绘制文本

context.fillText(String, x, y, maxWidth); 绘制fill样式的文本,将其绘制在坐标点(x, y)。maxWidth为最大宽度。
context.strokeText(String, x, y, maxWidth); 绘制stroke样式的文本,将其绘制在坐标点(x, y)。maxWidth为最大宽度。
context.font = “Style”; 以CSS语法指定的字体样式,大小,字体族等,比如”10px Arial”。
context.textAlign = “start | end | left | right | center”; 指定文本的对其方式。如果该属性的值是”start”,那么x坐标在从左到右书写的语言中表示文本的左侧坐标,而end会让x坐标在从左到右书写的语言中表示文本的右侧坐标。
context.textBaseline = “top | hanging | middle | alphabetic | ideographic | bottom”; 指定文本的基线。设置”top”意味着y轴表示文本顶部,”bottom”表示文本底部。
context.measureText(String); 该方法使用font, textAlign和textBaseline属性当前的值计算绘制指定文本后的大小。

变换

context.rotate(angle); 围绕原点把图像旋转angle弧度。
context.scale(scaleX, scaleY); 通过在x轴乘以scaleX,在y轴乘以scaleY来缩放图像。scaleX和scaleY的默认值都是1.0。
context.translate(x, y); 把原点移动到(x, y)。执行这个操作后,坐标(0, 0)就会变成(x, y)。
context.transform(m1_1, m1_2, m2_1, m2_2, dx, dy); 通过矩阵乘法直接修改矩阵。
context.save(); 保存当前属性和变换状态到暂存栈。
context.restore(); 从暂存栈中取出并恢复之前保存的设置。

绘制图像

img参数可以是HTML的img元素,也可以是另一个canvas元素。
另外有时候会出现img为HTML的img元素时,没有绘制出来图片的情况。出现这个问题的原因是这样的: 图片还没有加载到img元素,canvas就把这个元素给画上去了,所以画了个寂寞。。。这种情况下只需要等img加载完成后再绘制图片就好了,比如使用img.onload等方式来等待其加载完成。
context.drawImage(img, x, y); 将img绘制到(x, y)。
context.drawImage(img, x, y, width, height); 将img绘制到(x, y),其宽度为width,高度为height。
context.drawImage(img, sourceX, sourceY, sourceWidth, sourceHeight, targetX, targetY, targetWidth, targetHeight); 从img的(sourceX, sourceY)开始,截取宽sourceWidth,高sourceHeight大小的矩形,将其绘制到(targetX, targetY),其宽度为targetWidth,高度为targetHeight。

阴影

context.shadowColor = “color”; CSS颜色值,表示要绘制的阴影颜色,默认为黑色。
context.shadowOffsetX = value; 阴影相对于形状或路径的x坐标的偏移量,默认为0。
context.shadowOffsetY = value; 阴影相对于形状或路径的Y坐标的偏移量,默认为0。
context.shadowBlur = value; 表示阴影的模糊量。默认值为0, 表示不模糊。

渐变

分为线性渐变和径向渐变。

线性渐变

context.createLinearGradient(startX, startY, endX, endY); 该方法会返回一个CanvasGradient实例,我们如果要对这个渐变做出改变,应该操作返回的这个CanvasGradient。这个方法接收4个参数,起点x, 起点y, 终点x, 终点y。该方法会根据这些参数创建一个画布,绘制的图像若是超出了该画布,则不会绘制出渐变效果。
CanvasGradient.addColorStop(pos, String); 为渐变指定色标。这个方法接收两个参数,第一个参数是色标的位置,其范围为0~1。第二个参数是CSS颜色字符串。所以在使用的时候,一般都要调用这个方法两次,用于指定渐变的色标。

使用方法如下:

1
2
3
4
5
let linearGradient = context.createLinearGradient(0, 0, 30, 30);
linearGradient.addColorStop(0, "white");
linearGradient.addColorStop(1, "black");
context.fillStyle = linearGradient;
context.fillRect(0, 0, 20, 20);

为了让渐变覆盖整个矩形,而不只是其中一部分,两者的坐标必须搭配合适。如果矩形没有绘制到渐变的范围内,则只会显示部分渐变。

径向渐变

context.createRadialGradient(r1x, r1y, r1r, r2x, r2y, r2r); 该方法接收6个参数,分别对应两个圆形圆心的坐标和半径。前三个参数指定起点圆形中心的x, y坐标和半径,后三个参数指定终点圆形中心的x,y坐标和半径。径向渐变使用方法与线性渐变一样。
JS示例:

1
2
3
4
5
let gradient = context.createRadialGradient(100, 100, 30, 100, 100, 70);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
context.fillStyle = gradient;
context.fillRect(30, 30, 140, 140);

图像数据

主要是对原始图像进行操作。
context.getImageData(x, y, width, height); 该方法可以获取原始图像数据。这个方法接受四个参数: 要取得数据中第一个像素的左上角坐标(x, y)和要取得的像素的宽度width和高度height。该方法返回一个ImageData实例。
ImageData: 每个ImageData都包含3个属性: width. height和data。其中data属性是包含图像的原始像素信息的数组。每个像素在data数组中都由4个值表示,分别代表红,绿,蓝和透明值。也就是说,第一个像素在数组中的位置为data[0], data[1], data[2], data[3],而这四个值分别对应了RGBA中的Red,Green,Blue和Alpha。这个数组中的每个值都在0~255范围内(包括0和255)。
context.putImageData(ImageData, x, y); 该方法将ImageData对象绘制到画布上。
下面代码是红宝书上实现的一个灰阶过滤器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let imgData = context.getImageData(0, 0, 300, 300);
let data = imgData.data;
let len = data.length;
let red, blue, green, average, alpha;
for(let i = 0; i < len; i+=4)
{
red = data[i];
green = data[i + 1];
blue = data[i + 2];
alpha = data[i + 3];
average = Math.floor((red + green + blue) / 3);
data[i] = average;
data[i + 1] = average;
data[i + 2] = average;
}
imgData.data = data;
context.putImageData(imgData, 0, 0);

合成

2D上下文中绘制的所有内容都会应用两个属性: globalAlpha和globalCompositionOperation。其中globalAlpha属性是一个范围在0~1的值(包括0和1),用于指定所有绘制内容的透明度,默认值为0。如果所有后来的绘制都需要使用同样的透明度,那么可以将globalApha设置为适当的值,执行绘制,然后再把globalAlpha设置为0。
globalCompositionOperattion属性表示新绘制的形状如何与上下文中已有的形状融合。这个属性是一个字符串,可以取以下值。
source-over: 默认值,新图形绘制在原有图形上面。
source-in: 新图形只绘制出与原有图形重叠的部分,画布上其余部分全部透明。
source-out: 新图形只绘制出不与原有图形重叠的部分,画布上其余部分全部透明。
source-atop: 新图形只绘制出与原有图形重叠的部分,原有图形不受影响。
destination-over: 新图形绘制在原有图形下面,重叠部分只有原图形透明像素下的部分可见。
destination-in: 新图形绘制在原有图形下面,画布上只剩下二者重叠的部分,其余部分完全透明。
destination-out: 新图形与原有图形重叠的部分完全透明,原图形其余部分不受影响。
destination-atop: 新图形绘制在原有图形的下面,原有图形与新图形不重叠的部分完全透明。
lighter: 新图形与原有图形重叠部分的像素值相加,使该部分变亮。
copy: 新图形将擦除并完全取代原有图形。
xor: 新图形与原有图形重叠部分的像素执行”异或”计算。
不同浏览器在实现这些选项时可能存在差异。

本篇完。

评论



愿火焰指引你