简介
canvas 是H5新增的一个用于图形绘制的标签。
<canvas id="my-canvas" width="600" height="600"> 该浏览器版本不支持canvas标签 </canvas>
</canvas>
不可缺省
API及用法
canvas尺寸设置
canvas的width、height默认值分别是300,、150
- 设置canvas 的 width、height 属性:
<canvas id="my-canvas" width="600" height="600"> 该浏览器版本不支持canvas标签 </canvas>
- 用js设置
/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('#my-canvas')
canvas.width = 600 // 不需要px等单位
canvas.height = 600
注:不要使用css 设置canvas 尺寸
上下文对象
/** 获取上下文对象 */
const ctx = canvas.getContext('2d')
画笔的颜色或者样式
-
ctx.strokeStyle
,画布绘制形状时设置画笔的颜色或者样式。默认值是#000
,黑色。 -
ctx.fillStyle
,画布绘制形状时画笔填充内部的颜色或者样式。默认值是#000
,黑色。
ctx.strokeStyle = color;
ctx.strokeStyle = gradient;
ctx.strokeStyle = pattern;
绘制矩形
canvas提供了三种方法绘制矩形
fillRect(x, y, width, height)
:绘制一个填充的矩形strokeRect(x, y, width, height)
:绘制一个矩形的边框clearRect(x, y, width, height)
:清除指定矩形区域,让清除部分完全透明。
例子1:绘制一个矩形边框
/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('#my-canvas')
canvas.width = 600
canvas.height = 600
/** 获取上下文对象 */
const ctx = canvas.getContext('2d')
ctx.strokeStyle = 'red'
ctx.strokeRect(100, 100, 100, 100)
例子2:绘制一个填充的矩形
/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('#my-canvas')
canvas.width = 600
canvas.height = 600
/** 获取上下文对象 */
const ctx = canvas.getContext('2d')
ctx.strokeStyle = 'red'
ctx.strokeRect(100, 100, 100, 100)
绘制路径
beginPath()
:新建一条路径closePath()
:闭合路径moveTo()
:设置起点lineTo()
:绘制直线stroke()
:通过线条来绘制图形轮廓。fill()
:通过填充路径的内容区域生成实心的图形
当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。
例子:画一个三角形
/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('#my-canvas')
/** 获取上下文对象 */
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'red'
// 绘制路径
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.lineTo(100, 100)
ctx.lineTo(50, 150)
ctx.fill()
绘制圆弧
-
arc(x, y, radius, startAngle, endAngle, anticlockwise)
画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。 -
arcTo(x1, y1, x2, y2, radius)
根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。
arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式: 弧度=
(Math.PI/180)*角度
。
例子1:绘制一个半圆
/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('#my-canvas')
/** 获取上下文对象 */
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'red'
// 绘制半圆
ctx.arc(100, 100, 50, 0, Math.PI, true)
// 填充
ctx.fill()
二次贝塞尔曲线及三次贝塞尔曲线
quadraticCurveTo(cp1x, cp1y, x, y)
绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
例子:
/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('my-canvas')
// 上下文
const ctx = canvas.getContext('2d')
ctx.moveTo(100, 100)
ctx.quadraticCurveTo(125, 50, 200, 75)
ctx.stroke()
绘制文本
fillText(text, x, y [, maxWidth])
在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.strokeText(text, x, y [, maxWidth])
在指定的(x,y)位置绘制文本边框,绘制的最大宽度是可选的.
例子:
/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('my-canvas')
// 上下文
const ctx = canvas.getContext('2d')
ctx.font = '30px 宋体'
ctx.fillText('你好你好你好', 100, 100)
ctx.font = '30px 宋体'
ctx.strokeText('你好你好你好', 100, 200)
文本的样式
font = value
当前我们用来绘制文本的样式. 这个字符串使用和 CSS font 属性相同的语法. 默认的字体是10px sans-serif。
textAlign = value
文本对齐选项. 可选的值包括:start
,end
,left
,right
,center
. 默认值是start
。textBaseline = value
基线对齐选项. 可选的值包括:top
,hanging
,middle
,alphabetic
,ideographic
,bottom
。默认值是alphabetic
。direction = value
文本方向。可能的值包括:ltr
,rtl
,inherit
。默认值是inherit
。
绘制图像
drawImage(image, dx, dy)
drawImage(image, dx, dy, dWidth, dHeight)
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('#my-canvas')
/** 获取上下文对象 */
const ctx = canvas.getContext('2d')
const image = new Image()
image.src =
'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a5e7e4005461436aa0d0d7e4cccf3f24~tplv-k3u1fbpfcp-watermark.image'
image.onload = function () {
ctx.drawImage(image, 520, 180, 520, 1000, 100, 100, 120, 320)
}
形变
translate(x, y)
: 移动,该方法接受两个参数。x 是左右偏移量,y 是上下偏移量,如右图所示。rotate(angle)
: 旋转,该方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。scale(x, y)
: 缩放,该方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比1小,会缩小图形, 如果比1大会放大图形。默认值为1, 为实际大小。
状态的保存和恢复
save()
:保存画布(canvas)的所有状态restore
():恢复画布状态
save都可以保存什么?
- 当前的坐标变换信息(比如旋转rotate()或平移setTransform())
- 当前剪贴区域
- 图形上下文对象(
CanvasRenderingContext2D
)的当前属性值
例子:
/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('#my-canvas')
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 400, 30)
ctx.save() // 保存当前状态 01
ctx.fillStyle = 'blue'
ctx.fillRect(0, 30, 400, 30)
ctx.save() // 保存当前状态 02
ctx.fillStyle = 'yellow'
ctx.fillRect(0, 60, 400, 30)
ctx.restore() // 取出保存的状态 02 恢复
ctx.fillRect(0, 90, 400, 30)
ctx.restore() // 取出保存的状态 01 恢复
ctx.fillRect(0, 120, 400, 30)
合成
globalCompositeOperation = type
: 这个属性设定了在画新图形时采用的遮盖策略,其值是一个标识12种遮盖方式的字符串。
source-over
: 默认值
/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('my-canvas')
// 上下文
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'deeppink'
ctx.arc(100, 100, 50, 0, Math.PI * 2, false)
ctx.fill()
ctx.globalCompositeOperation = 'source-over'
ctx.fillStyle = 'blue'
ctx.fillRect(100, 100, 100, 100)
destination-over
source-in
destination-in
source-out
destination-out
source-atop
destination-atop
lighter
:两个重叠图形的颜色是通过颜色值相加来确定的。
copy
:只显示新图形
xor
:图像中,那些重叠和正常绘制之外的其他地方是透明的。
multiply
:将顶层像素与底层相应像素相乘,结果是一幅更黑暗的图片。
screen
:像素被倒转,相乘,再倒转,结果是一幅更明亮的图片。
裁剪路径
clip()
:将当前正在构建的路径转换为当前的裁剪路径。
/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('my-canvas')
// 上下文
const ctx = canvas.getContext('2d')
ctx.arc(100, 100, 75, 0, Math.PI * 2, false)
ctx.clip()
ctx.fillRect(0, 0, 100, 100)
样式和颜色
颜色
fillStyle = color
设置图形的填充颜色。strokeStyle = color
设置图形轮廓的颜色。globalAlpha = transparencyValue
这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。
线型
lineWidth = value
设置线条宽度。lineCap = type
设置线条末端样式,type取以下值:butt
线段末端以方形结束,默认值round
线段末端以圆形结束。square
线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域
lineJoin = type
设定线条与线条间接合处的样式,type取以下值:round
通过填充一个额外的,圆心在相连部分末端的扇形,绘制拐角的形状。 圆角的半径是线段的宽度。bevel
在相连部分的末端填充一个额外的以三角形为底的区域, 每个部分都有各自独立的矩形拐角。miter
默认值,通过延伸相连部分的外边缘,使其相交于一点,形成一个额外的菱形区域。这个设置可以通过 miterLimit 属性看到效果。
setLineDash(segments)
设置当前虚线样式。
segments:
一个Array数组。一组描述交替绘制线段和间距(坐标空间单位)长度的数字。 如果数组元素的数量是奇数, 数组的元素会被复制并重复。例如, [5, 15, 25] 会变成 [5, 15, 25, 5, 15, 25]。lineDashOffset = value
设置虚线样式的起始偏移量。- 例子:
/** @type {HTMLCanvasElement} */ const canvas = document.getElementById('my-canvas') // 上下文 const ctx = canvas.getContext('2d') let y = 20 function drawDashedLine(pattern) { ctx.beginPath() ctx.setLineDash(pattern) ctx.moveTo(0, y) ctx.lineTo(300, y) ctx.stroke() y += 20 } drawDashedLine([]) drawDashedLine([1, 1]) drawDashedLine([10, 10]) drawDashedLine([20, 5]) drawDashedLine([15, 3, 3, 3]) drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3]) drawDashedLine([12, 3, 3]) // 等同于 [12, 3, 3, 12, 3, 3]
效果:
- 例子2: 虚线边框矩形
/** @type {HTMLCanvasElement} */ const canvas = document.getElementById('my-canvas') // 上下文 const ctx = canvas.getContext('2d') ctx.setLineDash([4, 2]) ctx.strokeRect(10, 10, 100, 100)
效果:
- 例子:
lineDashOffset = value
设置虚线样式的起始偏移量。
例子:蚂蚁线/** @type {HTMLCanvasElement} */ const canvas = document.getElementById('my-canvas') // 上下文 const ctx = canvas.getContext('2d') var offset = 0 function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height) ctx.setLineDash([4, 2]) ctx.lineDashOffset = -offset ctx.strokeRect(10, 10, 100, 100) } function march() { offset++ if (offset > 16) { offset = 0 } draw() } setInterval(() => { march() }, 20)
效果:
渐变
createLinearGradient(x1, y1, x2, y2)
:该方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。
例子:/** @type {HTMLCanvasElement} */ const canvas = document.getElementById('canvas') // 上下文 const ctx = canvas.getContext('2d') // 线性渐变 const linear = ctx.createLinearGradient(100, 100, 100, 300) linear.addColorStop(0, 'red') linear.addColorStop(0.2, 'orange') linear.addColorStop(0.4, 'yellow') linear.addColorStop(0.6, 'green') linear.addColorStop(0.8, 'blue') linear.addColorStop(1, 'purple') ctx.fillStyle = linear ctx.fillRect(100, 100, 200, 200)
createRadialGradient(x1, y1, r1, x2, y2, r2)
:方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。
图案样式
createPattern(image, type)
:该方法接受两个参数。Image 可以是一个 Image 对象的引用,或者另一个 canvas 对象。Type 必须是下面的字符串值之一:repeat,repeat-x,repeat-y 和 no-repeat。
例子:/** @type {HTMLCanvasElement} */ const canvas = document.getElementById('my-canvas') // 上下文 const ctx = canvas.getContext('2d') // 创建新 image 对象,用作图案 var img = new Image() img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png' img.onload = function () { // 创建图案 var ptrn = ctx.createPattern(img, 'repeat') ctx.fillStyle = ptrn ctx.fillRect(0, 0, 150, 150) }
阴影
-
shadowOffsetX = float
shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0。 -
shadowOffsetY = float
shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0。 -
shadowBlur = float
shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0。 -
shadowColor = color
shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。例子:
/** @type {HTMLCanvasElement} */ const canvas = document.getElementById('canvas') // 上下文 const ctx = canvas.getContext('2d') ctx.shadowOffsetX = 10 ctx.shadowOffsetY = 10 ctx.shadowBlur = 3 ctx.shadowColor = 'red' ctx.font = '30px 宋体' ctx.fillText('你好你好你好你好', 100, 100)