Canvas
Canvas 是 HTML5 提供的一个用于在网页上绘制图形和动画的元素。它是一个类似画布的区域,您可以在上面使用 JavaScript 绘制各种图形、文本和动画。
HTMLCanvasElement
<canvas id="myCanvas"></canvas>
注意
- 默认 canvas 画布大小为 300px * 150px
- 不能使用 javascript 给 canvas 画布添加 css 样式的宽高(如
myCanvas.style.cssText='width: 800px; height: 400px;'
),必须使用 canvas 默认的宽高属性(如myCanvas.width = 800
myCanvas.height = 400
),否则将会出现画笔位置偏移 - 默认 canvas 满屏时会出现滚动条(如
myCanvas.width = document.documentElement.clientWidth
myCanvas.height = document.documentElement.clientHeight
),可以设置内外边距归零且使用绝对定位四面归零法解决
2D 渲染上下文
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
绘制矩形
ctx.fillRect()
绘制一个填充的矩形。
ctx.fillRect(x, y, width, height)
参数:
x
:矩形的左上角 x 轴坐标。y
:矩形的左上角 y 轴坐标。width
:矩形的宽度。height
:矩形的高度。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 设置填充样式
ctx.fillStyle = 'blue' // 设置填充颜色
// 绘制一个填充矩形
ctx.fillRect(50, 50, 100, 60)
ctx.strokeRect()
绘制线条的矩形。
ctx.strokeRect(x, y, width, height)
参数:
x
:矩形左上角的 x 轴坐标。y
:矩形左上角的 y 轴坐标。width
:矩形的宽度。height
:矩形的高度。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 设置线条样式
ctx.strokeStyle = 'blue' // 设置描边颜色
ctx.lineWidth = 2 // 设置描边线宽
// 绘制一个描边矩形
ctx.strokeRect(50, 50, 100, 60)
ctx.roundRect()
绘制一个圆角线条的矩形。
roundRect(x, y, width, height, radii)
参数:
x
: 矩形起点的 x 轴坐标(以像素为单位)。y
: 矩形起点的 y 轴坐标(以像素为单位)。width
: 矩形的宽度。正值在右边,负值在左边。height
: 矩形的高度。正值下降,负值上升。radii
: 指定要用于矩形拐角的圆弧半径。
radii 取值
- all-corners
- [all-corners]
- [top-left-and-bottom-right, top-right-and-bottom-left]
- [top-left, top-right-and-bottom-left, bottom-right]
- [top-left, top-right, bottom-right, bottom-left]
示例:
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// Rounded rectangle with zero radius (specified as a number)
ctx.strokeStyle = 'red'
ctx.beginPath()
ctx.roundRect(10, 20, 150, 100, 0)
ctx.stroke()
// Rounded rectangle with 40px radius (single element list)
ctx.strokeStyle = 'blue'
ctx.beginPath()
ctx.roundRect(10, 20, 150, 100, [40])
ctx.stroke()
// Rounded rectangle with 2 different radii
ctx.strokeStyle = 'orange'
ctx.beginPath()
ctx.roundRect(10, 150, 150, 100, [10, 40])
ctx.stroke()
// Rounded rectangle with four different radii
ctx.strokeStyle = 'green'
ctx.beginPath()
ctx.roundRect(400, 20, 200, 100, [0, 30, 50, 60])
ctx.stroke()
ctx.clearRect()
清除 Canvas 中指定区域的像素,使该区域变为透明。
ctx.clearRect(x, y, width, height)
参数:
x
:要清除的矩形区域的左上角 x 坐标。y
:要清除的矩形区域的左上角 y 坐标。width
:要清除的矩形区域的宽度。height
:要清除的矩形区域的高度。
示例:
// 清除整个 Canvas ,相当于 ctx.reset()
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 清除 Canvas 中指定区域
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 绘制一个矩形
ctx.fillStyle = 'blue'
ctx.fillRect(50, 50, 100, 100)
// 清除矩形的一部分,使其变为透明
ctx.clearRect(75, 75, 50, 50)
ctx.reset()
重置 Canvas 为默认状态。
ctx.reset()
绘制线条
ctx.beginPath()
开始新的线条。
ctx.closePath()
关闭当前线条。
ctx.moveTo()
将当前绘图位置(绘制点)移动到指定的坐标 (x, y),而不创建实际的路径线段。通常与其他路径绘制方法(如 ctx.lineTo()、ctx.arc() 等)一起使用,用于指定路径的起始点或在路径中移动到一个新的位置。
ctx.moveTo(x, y)
ctx.lineTo()
创建一条从当前绘图位置到指定坐标 (x, y) 的直线路径,起点是当前路径的终点(或者初始点,如果路径为空),终点是指定的坐标 (x, y)。
ctx.lineTo(x, y)
ctx.rect()
创建一个矩形的轮廓,但不会绘制矩形本身,需要使用 ctx.stroke() 方法描边路径,或使用 ctx.fill() 方法填充矩形区域。
ctx.rect(x, y, width, height)
参数:
x
:矩形左上角的 x 轴坐标。y
:矩形左上角的 y 轴坐标。width
:矩形的宽度。height
:矩形的高度。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 创建一个矩形路径
ctx.rect(50, 50, 100, 60)
// 设置线条样式
ctx.strokeStyle = 'blue'
// 描边矩形路径
ctx.stroke()
ctx.stroke()
绘制路径的轮廓。
ctx.stroke()
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 创建路径
ctx.beginPath()
// 移动到起始点
ctx.moveTo(50, 50)
// 添加一条线段
ctx.lineTo(150, 50)
// 设置线条样式
ctx.strokeStyle = 'blue'
ctx.lineWidth = 3 // 线宽为3像素
// 描边路径
ctx.stroke()
ctx.fill()
填充当前路径所定义的图形。
ctx.fill()
ctx.fill(path)
ctx.fill(fillRule)
ctx.fill(path, fillRule)
参数:
path
: 指定一个路径对象,并使用当前的填充样式来填充该路径所定义的图形。路径对象通常是 Path2D 类的实例。fillRule
: 指定一个填充规则,用于定义填充路径内的区域的规则。可选值: "nonzero" (非零填充规则)和 "evenodd" (奇偶填充规则)。
示例:
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
ctx.rect(10, 10, 150, 100)
ctx.fill()
WARNING
在调用 ctx.fill() 之前,通常需要使用一系列的路径绘制方法(例如 moveTo()、lineTo()、arc()、rect() 等)来创建一个封闭的路径,然后 fill() 方法会填充该路径内的区域。
ctx.setLineDash()
设置线条的虚线样式。
ctx.setLineDash(segments)
参数:
segments
: 是一个包含一组数字的数组,用于指定线条的虚线样式。这个数组中的数字依次表示实线长度和虚线长度,以交替的方式定义虚线模式。例如,[5, 10] 表示线条以 5 个像素的实线后跟 10 个像素的虚线,然后重复这个模式。
示例:
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// Dashed line
ctx.beginPath()
ctx.setLineDash([5, 15])
ctx.moveTo(0, 50)
ctx.lineTo(300, 50)
ctx.stroke()
// Solid line
ctx.beginPath()
ctx.setLineDash([])
ctx.moveTo(0, 100)
ctx.lineTo(300, 100)
ctx.stroke()
ctx.bezierCurveTo()
绘制一条三次贝塞尔曲线。
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
参数:
cp1x
和cp1y
:第一个控制点的 x 和 y 坐标。cp2x
和cp2y
:第二个控制点的 x 和 y 坐标。x
和y
:曲线的终点坐标。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.moveTo(50, 50) // 移动到起始点
ctx.bezierCurveTo(100, 100, 200, 100, 250, 50) // 绘制贝塞尔曲线
ctx.lineWidth = 2
ctx.strokeStyle = 'blue'
ctx.stroke() // 描边曲线
ctx.quadraticCurveTo()
创建一条二次贝塞尔曲线路径。
ctx.quadraticCurveTo(cp1x, cp1y, x, y)
参数:
cp1x
:控制点的 x 轴坐标。cp1y
:控制点的 y 轴坐标。x
:结束点的 x 轴坐标。y
:结束点的 y 轴坐标。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 移动到起始点
ctx.moveTo(50, 50)
// 创建二次贝塞尔曲线路径
ctx.quadraticCurveTo(100, 10, 200, 50)
// 设置线条样式
ctx.strokeStyle = 'blue'
// 描边路径
ctx.stroke()
绘制圆弧
ctx.arc()
绘制圆形的路径或填充圆形区域
ctx.arc(x, y, radius, startAngle, endAngle)
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
参数:
x
:圆弧中心的 x 坐标。y
:圆弧中心的 y 坐标。radius
:圆弧的半径。startAngle
:圆弧的起始角度,以弧度表示(0 度表示水平向右,逆时针方向增加)。endAngle
:圆弧的结束角度,以弧度表示。anticlockwise
:一个可选的布尔值,表示是否以逆时针方向绘制圆弧(默认为 false,即顺时针方向)。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 绘制一个完整的圆
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI * 2) // 绘制一个半径为50的完整圆
ctx.closePath()
ctx.fill() // 填充圆形区域
// 绘制一个扇形
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI / 2) // 绘制一个半径为50的四分之一圆
ctx.lineTo(100, 100) // 连接到圆心,形成一个扇形
ctx.closePath()
ctx.fill() // 填充扇形区域
// 绘制一个圆环
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI * 2) // 绘制一个半径为50的完整圆
ctx.arc(100, 100, 40, 0, Math.PI * 2, true) // 再绘制一个半径为40的圆,覆盖在上面
ctx.closePath()
ctx.fill() // 填充形成的圆环区域
ctx.arcTo()
绘制两条线段之间的弧线,以使图形更加平滑连接
ctx.arcTo(x1, y1, x2, y2, radius)
参数:
x1
和y1
:第一条线段的终点坐标。x2
和y2
:第二条线段的起始坐标。radius
:圆弧的半径。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.moveTo(50, 50) // 移动到第一条线段的起始点
ctx.lineTo(150, 50) // 第一条线段
ctx.lineTo(150, 100) // 第二条线段
// 使用 arcTo 方法绘制平滑连接
ctx.arcTo(150, 150, 100, 150, 50)
ctx.lineTo(50, 150) // 第三条线段
ctx.lineTo(50, 50) // 第四条线段
ctx.stroke() // 描边路径
ctx.ellipse()
绘制椭圆或椭圆弧。
ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle [, anticlockwise])
参数:
x
和y
:椭圆的中心点坐标。radiusX
和radiusY
:椭圆的水平半径和垂直半径。这两个参数分别定义了椭圆在 x 轴和 y 轴上的半径长度。rotation
:椭圆的旋转角度,以弧度表示。通常情况下,这个参数为 0,表示椭圆不旋转。startAngle
和endAngle
:椭圆弧的起始角度和结束角度,以弧度表示。这两个参数定义了椭圆弧的起始和结束位置。anticlockwise
(可选):一个布尔值,指定绘制椭圆弧的方向。如果设置为 true,则逆时针绘制,如果设置为 false 或省略,则顺时针绘制。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.ellipse(100, 100, 50, 30, 0, 0, Math.PI * 2)
ctx.stroke()
绘制文本
文本是以左下角为初始坐标。
ctx.fillText()
绘制文本。
ctx.fillText(text, x, y [, maxWidth])
参数:
text
:要绘制的文本内容,是一个字符串。x
:文本绘制的起始 x 轴坐标。y
:文本绘制的起始 y 轴坐标。maxWidth
(可选):文本的最大宽度,如果提供了这个参数,浏览器会自动将文本缩放以适应指定的宽度。如果文本超过了最大宽度,它将被截断。
ctx.strokeText()
绘制文本边框。
ctx.strokeText(text, x, y, maxWidth)
参数:
text
:要绘制的文本字符串。x
:文本绘制的起始点 x 轴坐标。y
:文本绘制的起始点 y 轴坐标。maxWidth
(可选):文本的最大宽度。如果指定了 maxWidth,则文本将在此宽度内自动换行。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 设置文本样式
ctx.font = '30px Arial' // 设置字体和字号
ctx.strokeStyle = 'blue' // 设置文本描边颜色
ctx.lineWidth = 2 // 设置描边线宽
// 描边文本
ctx.strokeText('Hello, Canvas!', 50, 50)
绘制图像
ctx.drawImage()
将图片、视频或另一个 Canvas 元素的内容绘制到当前的 Canvas 上。
ctx.drawImage(image, dx, dy)
ctx.drawImage(image, dx, dy, dWidth, dHeight)
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
参数:
image
:要绘制的图像、视频或 Canvas 元素。dx
:在目标 Canvas 上放置图像的 x 轴坐标。dy
:在目标 Canvas 上放置图像的 y 轴坐标。dWidth
:绘制到目标 Canvas 上的图像宽度。dHeight
:绘制到目标 Canvas 上的图像高度。sx
:源图像的 x 轴起始位置。sy
:源图像的 y 轴起始位置。sWidth
:源图像的宽度。sHeight
:源图像的高度。
示例:
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
// 图片
const img = new Image()
img.src = 'image.jpg' // 替换为实际图像的路径
img.onload = function () {
// 将图像绘制到 Canvas 上
ctx.drawImage(img, 0, 0)
}
// 视频
const video = document.createElement('video')
video.src = 'video.mp4'
function render() {
ctx.drawImage(video, 0, 0)
requestAnimationFrame(render)
}
render()
ctx.createImageData()
创建一个新的空白图像数据对象。
ctx.createImageData(width, height)
参数:
width
:图像数据的宽度,以像素为单位。height
:图像数据的高度,以像素为单位。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 创建一个空白的图像数据对象,宽度为 100 像素,高度为 50 像素
var imageData = ctx.createImageData(100, 50)
// imageData 对象现在表示一个 100x50 的矩形区域,每个像素都是全透明的
// 修改像素数据,使图像变成红色
for (var i = 0; i < imageData.data.length; i += 4) {
// 每个像素由 4 个字节表示,依次为红、绿、蓝和透明通道
// 将红色通道设置为最大值(255),其他通道设置为 0
imageData.data[i] = 255 // 红色通道
imageData.data[i + 1] = 0 // 绿色通道
imageData.data[i + 2] = 0 // 蓝色通道
imageData.data[i + 3] = 255 // 透明通道
}
// 将修改后的图像数据绘制到 Canvas 上
ctx.putImageData(imageData, 10, 10)
cxt.getImageData()
获取指定区域的像素数据。
getImageData(sx, sy, sw, sh)
参数:
x
:指定要获取像素数据的区域的左上角 x 轴坐标。y
:指定要获取像素数据的区域的左上角 y 轴坐标。width
:指定要获取像素数据的区域的宽度。height
:指定要获取像素数据的区域的高度。
ctx.putImageData()
将像素数据从 ImageData 对象(通常通过 ctx.getImageData() 获取)绘制到 Canvas 上的指定位置。
ctx.putImageData(imageData, dx, dy)
参数:
imageData
:包含要绘制的像素数据的 ImageData 对象。dx
:目标 Canvas 上 x 轴的坐标,即绘制的起始点的 x 轴位置。dy
:目标 Canvas 上 y 轴的坐标,即绘制的起始点的 y 轴位置。
示例:
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const image = new Image()
image.src = 'plumeria.jpg'
image.addEventListener('load', () => {
ctx.drawImage(image, 0, 0, 233, 320)
const imageData = ctx.getImageData(10, 20, 80, 230)
ctx.putImageData(imageData, 260, 0)
ctx.putImageData(imageData, 380, 50)
ctx.putImageData(imageData, 500, 100)
})
ctx.createPattern()
创建一个图像重复(印章)填充模式。
ctx.createPattern(image, repetition)
参数:
image
:要用作填充的图像,可以是一个<img>
元素、一个<canvas>
元素,或者一个<video>
元素。repetition
:指定填充图像的重复方式,可以是字符串 "repeat"、"repeat-x"、"repeat-y" 或 "no-repeat"。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 创建一个填充模式,使用一个图像作为填充
var img = new Image()
img.src = 'pattern.png' // 替换为实际图像的路径
img.onload = function () {
var pattern = ctx.createPattern(img, 'repeat') // 图像重复填充
// 使用填充模式作为填充样式
ctx.fillStyle = pattern
// 创建一个矩形路径并填充
ctx.fillRect(50, 50, 200, 150)
}
裁剪
ctx.clip()
创建一个裁剪区域,将后续的绘图限制在该区域内。
ctx.clip()
ctx.clip(path)
ctx.clip(fillRule)
ctx.clip(path, fillRule)
参数:
path
: 是一个路径对象或路径的定义,用于定义裁剪区域。fillRule
: 是一个字符串,表示填充规则,可以是 "evenodd" 或 "nonzero"。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 绘制一个矩形
ctx.fillStyle = 'blue'
ctx.fillRect(50, 50, 100, 100)
// 创建一个裁剪区域,限制后续的绘图只在裁剪区域内可见
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI * 2)
ctx.clip()
// 在裁剪区域内绘制另一个矩形
ctx.fillStyle = 'red'
ctx.fillRect(75, 75, 50, 50)
颜色
ctx.strokeStyle
设置路径颜色。颜色值支持:颜色名称、十六进制、RGB/RGBA、HSL/HSLA。
ctx.fillStyle
设置填充颜色。颜色值支持:颜色名称、十六进制、RGB/RGBA、HSL/HSLA。
样式
线条
ctx.lineWidth
设置线条宽度。
ctx.lineCap
设置线条末端的样式,可选值为:"butt"(平头)、"round"(圆头)、"square"(方头)。
ctx.lineDashOffset
设置虚线的偏移量。
ctx.lineJoin
设置线条的连接方式,即定义线条相交处的外观样式。可选值为:"miter"(尖角)、"round"(圆角)、"bevel"(斜角)。
ctx.miterLimit
设置在尖锐角连接线段时控制尖锐角的最大长度与线条宽度的比率(只有 ctx.lineJoin 设置为 "miter" 时生效)。
ctx.lineWidth
设置线条的宽度,默认单位像素,无需携带。
文本
ctx.font
设置文本字体和大小。
ctx.textAlign
设置文本对齐方式。
ctx.textBaseline
设置文本基线。
ctx.letterSpacing
设置文本字母间距。
ctx.wordSpacing
设置文本单词间距
图像
globalCompositeOperation
多个图像进行合并或混合。
可选值:
- "source-over"(默认值):新绘制的图形会覆盖在已有的图形上。
- "source-in":新绘制的图形只会保留与已有图形重叠的部分,其他部分会被裁剪掉。
- "source-out":新绘制的图形只会保留与已有图形不重叠的部分,重叠部分会被裁剪掉。
- "source-atop":新绘制的图形会与已有图形重叠,但不会覆盖已有图形的内容,只在重叠部分绘制新图形。
- "destination-over":新绘制的图形会放置在已有图形下方。
- "destination-in":新绘制的图形只会保留与已有图形重叠的部分,但不会覆盖已有图形的内容。
- "destination-out":新绘制的图形会删除与已有图形重叠的部分,但不会影响已有图形的内容。
- "destination-atop":新绘制的图形会与已有图形重叠,但不会覆盖已有图形的内容,只在重叠部分绘制新图形。
- "lighter":新绘制的图形与已有图形混合,颜色相加。
- "xor":新绘制的图形与已有图形进行异或混合,产生一种奇特的效果。
渐变
ctx.createLinearGradient()
创建一个线性渐变。
ctx.createLinearGradient(x0, y0, x1, y1)
参数:
x0
和y0
:渐变的起始点坐标。x1
和y1
:渐变的结束点坐标。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 创建线性渐变,从点 (50, 50) 到点 (250, 50)
var gradient = ctx.createLinearGradient(50, 50, 250, 50)
// 添加颜色停止点
gradient.addColorStop(0, 'red')
gradient.addColorStop(0.5, 'yellow')
gradient.addColorStop(1, 'green')
// 使用线性渐变作为填充样式
ctx.fillStyle = gradient
// 创建一个矩形路径并填充
ctx.fillRect(50, 20, 200, 60)
WARNING
一旦创建了线性渐变对象 gradient,您可以通过 gradient.addColorStop()
方法向锥形渐变中添加颜色停止点,以指定不同颜色在渐变中的位置。
ctx.createRadialGradient()
创建一个径向渐变
ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
参数:
x0
和y0
:内部圆的中心点坐标。r0
:内部圆的半径。x1
和y1
:外部圆的中心点坐标。r1
:外部圆的半径。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 创建径向渐变,从内部圆到外部圆
var gradient = ctx.createRadialGradient(100, 100, 20, 100, 100, 100)
// 添加颜色停止点
gradient.addColorStop(0, 'red')
gradient.addColorStop(0.5, 'yellow')
gradient.addColorStop(1, 'green')
// 使用径向渐变作为填充样式
ctx.fillStyle = gradient
// 创建一个圆形路径并填充
ctx.beginPath()
ctx.arc(100, 100, 100, 0, Math.PI * 2)
ctx.fill()
WARNING
一旦创建了径向渐变对象 gradient,您可以通过 gradient.addColorStop()
方法向锥形渐变中添加颜色停止点,以指定不同颜色在渐变中的位置。
ctx.createConicGradient()
创建一个锥形渐变。
const gradient = ctx.createConicGradient(x, y, angle)
参数解释如下:
x
和y
:锥形渐变的中心点坐标。angle
:锥形渐变的起始角度,以弧度表示,从正 x 轴的方向开始,顺时针旋转。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 创建锥形渐变
var gradient = ctx.createConicGradient(100, 100, 0)
// 添加颜色停止点
gradient.addColorStop(0, 'red')
gradient.addColorStop(0.25, 'yellow')
gradient.addColorStop(0.5, 'green')
gradient.addColorStop(0.75, 'blue')
gradient.addColorStop(1, 'red')
// 使用锥形渐变作为填充样式
ctx.fillStyle = gradient
// 创建一个圆形路径并填充
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI * 2)
ctx.fill()
WARNING
一旦创建了锥形渐变对象 gradient,您可以通过 gradient.addColorStop()
方法向锥形渐变中添加颜色停止点,以指定不同颜色在渐变中的位置。
阴影
ctx.shadowBlur
设置阴影模糊级别。
ctx.shadowColor
设置阴影颜色。
ctx.shadowOffsetX
设置阴影的水平偏移量。
ctx.shadowOffsetY
设置阴影的垂直偏移量。
滤镜
ctx.filter
设置滤镜效果,可选值为:"blur()"(模糊)、"brightness()"(亮度)、"contrast()"(对比度)、"grayscale()"(灰度)、"hue-rotate()"(旋转色相)、"invert()"(反转颜色)、"opacity()"(不透明度)、"saturate()"(饱和度)、"sepia()"(深褐色)。
变换
ctx.rotate()
对当前绘图状态应用旋转变换。
ctx.rotate(angle)
参数:
angle
:表示要旋转的角度,以弧度为单位。正值表示顺时针旋转,负值表示逆时针旋转。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 绘制一个矩形
ctx.fillStyle = 'blue'
ctx.fillRect(50, 50, 100, 60)
// 旋转坐标系 45 度(弧度表示)
ctx.rotate(Math.PI / 4)
// 绘制一个旋转后的矩形
ctx.fillStyle = 'red'
ctx.fillRect(50, 50, 100, 60)
Math.PI
Math.PI = 180 度,Math.PI * 2 = 360 度,依此类推。
ctx.scale()
对当前绘图状态应用缩放变换。
ctx.scale(scaleX, scaleY)
参数:
- scaleX:表示在水平方向上进行缩放的比例因子。值小于 1 表示缩小,大于 1 表示放大,1 表示不变。
- scaleY:表示在垂直方向上进行缩放的比例因子。同样,值小于 1 表示缩小,大于 1 表示放大,1 表示不变。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 绘制一个矩形
ctx.fillStyle = 'blue'
ctx.fillRect(50, 50, 100, 60)
// 进行水平和垂直方向上的缩放
ctx.scale(2, 1.5)
// 绘制一个缩放后的矩形
ctx.fillStyle = 'red'
ctx.fillRect(50, 50, 100, 60)
ctx.transform()
应用仿射变换矩阵来变换绘图坐标系。
ctx.transform(a, b, c, d, e, f)
参数:
a
:水平缩放因子b
:水平倾斜因子c
:垂直倾斜因子d
:垂直缩放因子e
:水平平移量f
:垂直平移量
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 绘制一个矩形
ctx.fillStyle = 'blue'
ctx.fillRect(50, 50, 100, 60)
// 应用仿射变换来旋转和平移坐标系
ctx.transform(1, 0, 0, 1, 50, 50) // 平移坐标系到 (50, 50)
ctx.transform(
Math.cos(Math.PI / 4),
Math.sin(Math.PI / 4),
-Math.sin(Math.PI / 4),
Math.cos(Math.PI / 4),
0,
0
) // 旋转45度
// 绘制一个变换后的矩形
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 100, 60)
与 ctx.setTransform() 区别
- ctx.setTransform(a, b, c, d, e, f)
- 这个方法不是累积的,它会直接设置绘图坐标系的变换矩阵,覆盖之前的任何变换。
- 通常用于在重新设置绘图坐标系之前,以确保绘制操作不会受到之前变换的影响。
- ctx.transform(a, b, c, d, e, f)
- 这个方法是累积的,它会将新的变换与之前的变换相乘,以得到最终的变换效果。
- 通常用于在已经有一些变换的情况下,进一步对绘图坐标系进行变换。
总结:如果需要在清除之前的所有变换并设置一个新的变换矩阵时,可以使用 ctx.setTransform()。如果希望在之前的变换基础上添加更多变换,可以使用 ctx.transform()。
ctx.translate()
平移(移动)绘图坐标系的原点。
ctx.translate(x, y)
参数:
x
:表示在水平方向上移动原点的距离。y
:表示在垂直方向上移动原点的距离。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 绘制一个矩形
ctx.fillStyle = 'blue'
ctx.fillRect(50, 50, 100, 60)
// 平移坐标系原点
ctx.translate(50, 50)
// 绘制一个平移后的矩形
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 100, 60)
ctx.setTransform()
设置当前的变换矩阵。
ctx.setTransform(a, b, c, d, e, f)
参数:
a
:水平缩放(scaling)和旋转(rotation)。b
:水平倾斜(skewing)和旋转。c
:垂直倾斜和旋转。d
:垂直缩放和旋转。e
:水平平移(translation)。f
:垂直平移。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 应用一些变换,例如平移和旋转
ctx.translate(50, 50)
ctx.rotate(Math.PI / 4)
// 清除之前的所有变换,将绘图坐标系重置为默认状态
ctx.setTransform(1, 0, 0, 1, 0, 0)
// 在默认状态下绘制一个不受之前变换影响的图形
ctx.fillStyle = 'blue'
ctx.fillRect(50, 50, 100, 60)
ctx.resetTransform()
将当前的变换矩阵重置为默认状态。
ctx.resetTransform()
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 应用一些变换操作
ctx.translate(50, 50)
ctx.rotate(Math.PI / 4)
ctx.scale(2, 2)
// 在变换状态下绘制一个矩形
ctx.fillRect(0, 0, 50, 50)
// 重置变换矩阵
ctx.resetTransform()
// 在恢复到默认状态下绘制另一个矩形
ctx.fillRect(100, 100, 50, 50)
保存
ctx.save()
保存当前的绘图状态,包括绘图样式(如颜色、线宽、填充样式等)、变换矩阵(如平移、旋转、缩放等)以及其他属性。
ctx.save()
恢复
ctx.restore()
恢复到之前保存的绘图状态,它会将当前状态替换为之前保存的状态,从而撤销了之后的绘图操作。
ctx.restore()
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 保存当前绘图状态
ctx.save()
// 设置新的绘图样式
ctx.fillStyle = 'red'
ctx.lineWidth = 3
// 绘制一个矩形
ctx.fillRect(50, 50, 100, 100)
// 恢复到之前保存的绘图状态
ctx.restore()
// 绘制另一个矩形,样式和线宽恢复为之前保存的状态
ctx.fillRect(200, 50, 100, 100)
动画
window.requestAnimationFrame()
requestAnimationFrame(callback)
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
let earthAngle = 0
let moonAngle = 0
function loop() {
// 保存初始化画布
ctx.save()
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 太阳
ctx.beginPath()
ctx.arc(400, 300, 100, 0, 2 * Math.PI)
ctx.fillStyle = '#e3fa14'
ctx.shadowColor = '#e3fa14'
ctx.shadowBlur = 10
ctx.fill()
ctx.closePath()
// 地球
ctx.beginPath()
ctx.translate(400, 300)
ctx.rotate(
((earthAngle > 60 ? (earthAngle = 0) : earthAngle++) * Math.PI) / 180
)
ctx.translate(200, 0)
ctx.arc(0, 0, 20, 0.2 * Math.PI)
ctx.fillStyle = 'blue'
ctx.shadowBlur = 0
ctx.fill()
ctx.closePath()
// 月球
ctx.beginPath()
ctx.fillStyle = '#fff'
ctx.rotate((++moonAngle * Math.PI) / 180)
ctx.arc(40, 0, 6, 0, 2 * Math.PI)
ctx.fill()
ctx.closePath()
// 恢复至初始化画布
ctx.restore()
// 递归调用自身
requestAnimationFrame(loop)
}
requestAnimationFrame(loop)
数据 URL
将 Canvas 中的图像转换为 Data URL 地址。Data URL 是一种将图像嵌入到文档中的方式,它以文本字符串的形式表示图像数据。
toDataURL([type][, encoderOptions])
参数:
type
(可选):用于指定生成的 Data URL 的图像类型。常见的类型包括:"image/png"(默认值)、"image/jpeg"、"image/gif" 。encoderOptions
(可选):用于指定图像编码的选项。对于 JPEG 和 WebP 图像,您可以指定图像的质量,范围从 0 到 1,其中 1 表示最高质量。
示例:
var canvas = document.getElementById('myCanvas')
var ctx = canvas.getContext('2d')
// 在 Canvas 上绘制一个矩形
ctx.fillStyle = 'blue'
ctx.fillRect(10, 10, 100, 80)
// 使用 toDataURL() 方法将 Canvas 中的绘图结果转换为 Data URL(JPEG 格式,质量为 0.8)
var dataURL = canvas.toDataURL('image/jpeg', 0.8)
// 创建图片
const img = new Image()
img.src = dataURL
封装 Path2D
用于创建和存储路径,以便在后续的绘图操作中重复使用。
new Path2D()
创建一个空的路径对象,或者可以传入一个现有路径对象或路径字符串来创建一个新的路径对象。
new Path2D()
new Path2D(path)
new Path2D(d)
参数:
path
: 当使用另一个 Path2D 对象调用时,将创建 path 参数的副本。d
: 当使用由 SVG 路径数据组成的字符串调用时,将从该描述创建一个新路径。
示例
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// Path
let path1 = new Path2D()
path1.rect(10, 10, 100, 100)
let path2 = new Path2D(path1)
path2.moveTo(220, 60)
path2.arc(170, 60, 50, 0, 2 * Math.PI)
ctx.stroke(path2)
// SVG
let p = new Path2D('M10 10 h 80 v 80 h -80 Z')
ctx.fill(p)
path.addPath()
将一个路径添加到另一个路径中。
addPath(path [, transform])
参数:
path
: 要添加到当前路径的路径对象,通常是另一个 Path2D 对象,以合并两者的路径。transform
: 在添加路径时对路径进行变换。这是一个 DOMMatrix 或 SVGMatrix 对象,表示 2D 变换矩阵。
示例:
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// Create first path and add a rectangle
let p1 = new Path2D()
p1.rect(0, 0, 100, 150)
// Create second path and add a rectangle
let p2 = new Path2D()
p2.rect(0, 0, 100, 75)
// Draw the first path
p1.addPath(p2)
ctx.fill(p1)