H5 canvas
requestAnimationFrame
基本的画布能力
创建 canvas 元素需要给定 宽高
当浏览器不支持 canvas 元素时 会显示闭合标签中的内容要在画布上绘制图形,需要先取得绘图上下文 getContext()
对于平面图形,需要给这个方法传入参数"2d",表示要获取2D上下文对象:
let drawing = document.getElementById("drawing");
// 确保浏览器支持<canvas>
if (drawing.getContext) {
let context = drawing.getContext("2d");
// 其他代码
}
- 导出 canvas 元素上的图像
let drawing = document.getElementById("drawing");
// 确保浏览器支持<canvas>
if (drawing.getContext) {
// 取得图像的数据URI
let imgURI = drawing.toDataURL("image/png");
// 显示图片
let image = document.createElement("img");
image.src = imgURI;
document.body.appendChild(image);
}
2D 绘图上下文
2D绘图上下文提供了绘制2D图形的方法,包括矩形、弧形和路径。2D上下文的坐标原点(0, 0)在 canvas 元素的左上角。
所有坐标值都相对于该点计算,因此x坐标向右增长,y坐标向下增长。默认情况下,width和height表示两个方向上像素的最大值。
- 填充和描边
2D上下文有两个基本绘制操作:填充和描边。
fillStyle 设置填充样式
strokeStyle 设置描边样式
let context = drawing.getContext("2d");
context.strokeStyle = "red";
context.fillStyle = "#0000ff";
- 绘制矩形
矩形是唯一一个可以直接在2D绘图上下文中绘制的形状。
与绘制矩形相关的方法有3个:fillRect()、strokeRect()和clearRect()。这些方法都接收4个参数:矩形x坐标、矩形y坐标、矩形宽度和矩形高度。这几个参数的单位都是像素。
-
fillRect
fillRect()方法用于以指定颜色在画布上绘制并填充矩形。填充的颜色使用fillStyle属性指定
// 绘制红色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); // 绘制半透明蓝色矩形 context.fillStyle = "rgba(0,0,255,0.5)"; context.fillRect(30, 30, 50, 50);
-
strokeRect
strokeRect()方法使用通过strokeStyle属性指定的颜色绘制矩形轮廓
// 绘制红色轮廓的矩形 context.strokeStyle = "#ff0000"; context.strokeRect(10, 10, 50, 50); // 绘制半透明蓝色轮廓的矩形 context.strokeStyle = "rgba(0,0,255,0.5)"; context.strokeRect(30, 30, 50, 50); 注意 描边宽度由lineWidth属性控制,它可以是任意整数值。类似地,lineCap属性控制线条端点的形状["butt"(平头) 、"round"(出圆头)或"square"(出方头)],而lineJoin属性控制线条交点的形状["round"(圆转) 、"bevel"(取平)或"miter"(出尖)
-
clearRect
使用clearRect()方法可以擦除画布中某个区域。该方法用于把绘图上下文中的某个区域变透明。通过先绘制形状再擦除指定区域,可以创建出有趣的效果,比如从已有矩形中开个孔。
// 绘制红色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); // 绘制半透明蓝色矩形 context.fillStyle = "rgba(0,0,255,0.5)"; context.fillRect(30, 30, 50, 50); // 在前两个矩形重叠的区域擦除一个矩形区域 context.clearRect(40, 40, 10, 10);
- 绘制路径
2D绘图上下文支持很多在画布上绘制路径的方法。通过路径可以创建复杂的形状和线条。要绘制路径,必须首先调用beginPath()方法以表示要开始绘制新路径。然后,再调用下列方法来绘制路径。
方法名 | 参数 | 说明 |
---|---|---|
arc() | arc(x, y, radius, startAngle, endAngle, counterclockwise) | 以坐标(x, y)为圆心,以radius为半径绘制一条弧线,起始角度为startAngle,结束角度为endAngle(都是弧度)。最后一个参数counterclockwise表示是否逆时针计算起始角度和结束角度(默认为顺时针)。 |
arcTo() | arcTo(x1, y1, x2, y2, radius) | 以给定半径radius,经由(x1, y1)绘制一条从上一点到(x2, y2)的弧线。 |
bezierCurveTo() | bezierCurveTo(c1x, c1y, c2x, c2y, x, y) | 以(c1x, c1y)和(c2x, c2y)为控制点,绘制一条从上一点到(x, y)的弧线(三次贝塞尔曲线)。 |
lineTo() | lineTo(x, y) | 绘制一条从上一点到(x, y)的直线。 |
moveTo() | moveTo(x, y) | 不绘制线条,只把绘制光标移动到(x, y)。 |
quadraticCurveTo() | quadraticCurveTo(cx, cy, x, y) | 以(cx, cy)为控制点,绘制一条从上一点到(x, y)的弧线(二次贝塞尔曲线)。 |
rect() | rect(x, y, width, height) | 以给定宽度和高度在坐标点(x, y)绘制一个矩形。这个方法与strokeRect()和fillRect()的区别在于,它创建的是一条路径,而不是独立的图形。 |
创建路径之后,可以使用closePath()方法绘制一条返回起点的线。如果路径已经完成,则既可以指定fillStyle属性并调用fill()方法来填充路径,也可以指定strokeStyle属性并调用stroke()方法来描画路径,还可以调用clip()方法基于已有路径创建一个新剪切区域。
let drawing = document.getElementById("drawing");
// 确保浏览器支持<canvas>
if (drawing.getContext) {
let context = drawing.getContext("2d");
// 创建路径
context.beginPath();
// 绘制外圆
context.arc(100, 100, 99, 0, 2 * Math.PI, false);
// 绘制内圆
context.moveTo(194, 100);
context.arc(100, 100, 94, 0, 2 * Math.PI, false);
// 绘制分针
context.moveTo(100, 100);
context.lineTo(100, 15);
// 绘制时针
context.moveTo(100, 100);
context.lineTo(35, 100);
// 描画路径
context.stroke();
}
- 绘制文本
文本和图像混合也是常见的绘制需求,因此2D绘图上下文还提供了绘制文本的方法,即fillText()和strokeText()。
fillText() | 这两个方法都接收4个参数:要绘制的字符串、x坐标、y坐标和可选的最大像素宽度。 |
strokeText() | 而且,这两个方法最终绘制的结果都取决于以下3个属性 |
font | 以CSS语法指定的字体样式、大小、字体族等,比如"10px Arial" |
textAlign | 指定文本的对齐方式,可能的值包括"start"、"end"、"left"、"right"和"center"。推荐使用"start"和"end",不使用"left"和"right",因为前者无论在从左到右书写的语言还是从右到左书写的语言中含义都更明确。 |
textBaseLine | 指定文本的基线,可能的值包括"top"、"hanging"、"middle"、"alphabetic"、"ideographic"和"bottom" |
通常,fillText()方法是使用最多的,因为它模拟了在网页中渲染文本
context.font = "bold 14px Arial";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("12", 100, 20);
由于绘制文本很复杂,特别是想把文本绘制到特定区域的时候,因此2D上下文提供了用于辅助确定文本大小的measureText()方法。
这个方法接收一个参数,即要绘制的文本,然后返回一个TextMetrics对象。
measureText()方法使用font、textAlign和textBaseline属性当前的值计算绘制指定文本后的大小。例如,假设要把文本"Hello world!"放到一个140像素宽的矩形中,可以使用以下代码,从100像素的字体大小开始计算,不断递减,直到文本大小合适:
let fontSize = 100;
context.font = fontSize + "px Arial";
while(context.measureText("Hello world!").width > 140) {
fontSize--;
context.font = fontSize + "px Arial";
}
context.fillText("Hello world!", 10, 10);
context.fillText("Font size is " + fontSize + "px", 10, 50);
- 变换