S07-02 数据可视化-Canvas-API
[TOC]
API-Canvas
索引
canvas
- <canvas>:
with height
,被用来通过 JS(Canvas API 或 WebGL API)绘制图形及图形动画的元素。 - el.getContext():
(contextType, contextAttributes?)
,返回canvas的上下文,如果上下文没有定义则返回null - el.toDataURL():
(type?, quality?)
,将 Canvas 转换为 Base64 编码的图像。
设置
- ctx.fillStyle:
color| gradient | pattern
,默认:#000
,设置或获取 Canvas 填充颜色或样式 - ctx.strokeStyle:
color| gradient | pattern
,默认:#000
,描边颜色 - ctx.globalAlpha:
number
,默认:1.0
,0~1的数值,值越小透明度越高,设置或获取 Canvas 的全局透明度。 - ctx.createLinearGradient():
(x0, y0, x1, y1)
,创建一个沿着参数坐标指定的线的线性渐变。 - ctx.createRadialGradient():
(x0, y0, r0, x1, y1, r1)
,创建一个沿着参数坐标指定的线的放射性渐变。 - gradient.addColorStop():
(offset, color)
,用于在渐变中设置颜色停靠点。gradient
是通过上述2个方法创建出来的CanvasGradient
对象。 - ctx.createPattern():
(image, repetition)
,用于创建一个图案。 - ctx.lineWidth:
number
,默认:1
,设置线条宽度。不带px单位 - ctx.lineCap:
butt | round | square
,默认:butt
,用于设置路径的端点样式。 - ctx.lineJoin:
round | bevel | miter
,默认:bevel
,控制路径连接处的形状。
路径
- ctx.beginPath():
()
,开始一条新的路径的方法。每次调用beginPath()
都会清除当前路径,使接下来的绘图操作不会连接到先前的路径上。 - ctx.closePath():
()
,用于关闭当前路径的方法。将路径的最后一部分连接回到起始点,形成一个闭合的路径。 - ctx.stroke():
()
,通过线条来绘制图形轮廓/描边(针对当前路径)。 - ctx.fill():
()
,通过填充路径的内容区域生成实心的图形(针对当前路径)。 - ctx.moveTo():
(x, y)
,将当前路径的起始点移动到指定的起始点坐标点。 - ctx.lineTo():
(x, y)
,通过连接当前路径的末端点和指定的(x, y)
坐标来绘制一条直线。 - ctx.rect():
(x, y, width, height)
,创建一个矩形路径。 - ctx.arc():
(x, y, radius, startAngle, endAngle, anticlockwise?)
,绘制一段圆弧或圆的方法。0表示3点钟方向。 - ctx.ellipsis():
(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise?)
,添加一个椭圆路径。 - ctx.bezierCurveTo():
(cp1x, cp1y, cp2x, cp2y, x, y)
,添加一个 3 次贝赛尔曲线路径。起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用moveTo()
进行修改。
绘制矩形
- ctx.fillRect():
(x, y, width, height)
,绘制填充矩形。 - ctx.strokeRect():
(x, y, width, height)
,绘制一个描边矩形。 - ctx.clearRect():
(x, y, width, height)
, 清除指定矩形区域,让清除部分完全透明。
绘制文本
- ctx.font:
font-style? font-variant? font-weight? font-size line-height? font-family
,默认:10px sans-serif
,设置文本的字体样式。 - ctx.textAlign:
start | end | left | right | center
,默认:start
,文本对齐选项。 - ctx.textBaseline:
top | hanging | middle | alphabetic | ideographic | bottom
,默认:alphabetic
,基线对齐选项。 - ctx.fillText():
(text, x, y, maxWidth?)
,绘制填充文本。 - ctx.strokeText():
(text, x, y, maxWidth?)
,绘制描边文本。
绘制图片
- ctx.drawImage():
(image, x, y)
,版本 1: 绘制图像到画布(不缩放、不裁剪) - ctx.drawImage():
(image, x, y, width, height)
,版本 2: 绘制图像并缩放。 - ctx.drawImage():
(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
,版本 3: 从图像中裁剪出指定的区域,并将其绘制到画布。
形变
- 保存和恢复绘画状态
- ctx.save():
()
,将当前的绘图状态保存到状态栈中。 - ctx.restore():
()
,从状态栈中恢复canvas的当前绘画状态。 - ctx.translate():
(x, y)
,平移整个画布上的所有内容。 - ctx.rotate():
(angle)
,用于旋转绘图上下文的坐标系。所有后续绘制的内容都将基于旋转后的坐标系进行。 - ctx.scale():
(x, y)
,用于缩放绘图上下文的整个坐标系。用来增减图形在canvas中的像素数目。会影响到所有后续绘制的图形。
动画
- setInterval():
(callback, interval?, arg1?, arg2?, ...)
,按照指定的时间间隔重复执行一个函数,直到被清除或页面关闭。 - setTimeout():
(callback, delay, arg1, arg2, ...)
,在指定的延迟时间后执行一个函数,只执行一次。 - requestAnimationFrame():
(callback)
,一种浏览器提供的机制,用于在浏览器的下一次重绘之前执行一个函数,它被广泛应用于动画的实现。
canvas
canvas
<canvas>:with height
,被用来通过 JS(Canvas API 或 WebGL API)绘制图形及图形动画的元素。
width:
number
,默认:300
,画布的宽度height:
number
,默认:150
,画布的高度- html
<canvas width="300" height="150"></canvas>
getContext()
el.getContext():(contextType, contextAttributes?)
,返回canvas的上下文,如果上下文没有定义则返回null 。
contextType:
'2d' | 'webgl' | 'webgl2' | 'bitmaprenderer'
,默认:'2d'
,指定渲染上下文类型2d
:常用,建立一个 CanvasRenderingContext2D 二维渲染上下文webgl
:创建一个 WebGLRenderingContext 三维渲染上下文对象webgl2
:创建一个 WebGL2RenderingContext 三维渲染上下文对象bitmaprenderer
:创建一个只提供将 canvas 内容替换为指定ImageBitmap功能的ImageBitmapRenderingContext
contextAttributes?:
{antialias, depth, stencil, alpha, premultipliedAlpha, preserveDrawingBuffer, failIfMajorPerformanceCaveat}
,默认:{}
,可以在创建渲染上下文的时候设置多个属性【更多】antialias
:boolean
,默认:true
,是否启用抗锯齿。true
表示启用抗锯齿。depth
:boolean
,默认:true
,是否启用深度缓冲。true
表示启用深度缓冲。stencil
:boolean
,默认:false
,是否启用模板缓冲。true
表示启用模板缓冲。alpha
:boolean
,默认:false
,是否启用透明度。true
表示启用。premultipliedAlpha
:boolean
,默认:true
,是否将 alpha 通道预乘到颜色通道中。preserveDrawingBuffer
:boolean
,默认:false
,是否保留绘制缓冲区。该属性常用于保存绘制内容进行后期处理。failIfMajorPerformanceCaveat
:boolean
,默认:false
,是否在性能较差时放弃创建上下文。
返回:
ctx:
CanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext | ImageBitmapRenderingContext | null
,返回指定类型的渲染上下文,如果上下文没有定义则返回null 。- js
// 获取 2D 上下文 const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // 获取 WebGL 上下文 const gl = canvas.getContext('webgl', { antialias: true, depth: true });
toDataURL()
el.toDataURL():(type?, quality?)
,将 Canvas 转换为 Base64 编码的图像。
type?:
MIME
,默认:image/png
,图片格式。MIME类型quality?:
number
,默认:0.92
,从 0 到 1 的区间内选择图片的质量。只在type
为'image/jpeg'
或'image/webp'
时才有效。返回:
dataURL:
string
,包含 data URI 的字符串。如:"data:image/png;base64,xxxx..."
- js
const canvas = document.getElementById('myCanvas'); const dataURL = canvas.toDataURL('image/png'); // 显示 Base64 图像 const img = new Image(); img.src = dataURL; document.body.appendChild(img); // 将图像添加到页面上显示 // 创建下载链接 const link = document.createElement('a'); link.href = dataURL; link.download = 'canvas-image.png'; // 设置下载的文件名 link.click(); // 模拟点击下载
设置
颜色
fillStyle
ctx.fillStyle:color| gradient | pattern
,默认:#000
,设置或获取 Canvas 填充颜色或样式
- js
// 颜色值 ctx.fillStyle = 'red'; ctx.fillRect(50, 50, 150, 100); // 线性渐变 const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0); gradient.addColorStop(0, 'red'); // 起始点为红色 gradient.addColorStop(1, 'blue'); // 结束点为蓝色 ctx.fillStyle = gradient; ctx.fillRect(50, 50, 150, 100); // 放射性渐变 const gradient2 = ctx.createRadialGradient(200, 150, 20, 200, 150, 150); gradient2.addColorStop(0, 'yellow'); // 中心点为黄色 gradient2.addColorStop(1, 'green'); // 外圈为绿色 ctx.fillStyle = gradient2; ctx.beginPath(); ctx.arc(200, 150, 150, 0, Math.PI * 2, false); ctx.fill(); // 图案 const img = new Image(); img.src = 'https://www.example.com/path/to/your/image.jpg'; // 图像路径 img.onload = function() { const pattern = ctx.createPattern(img, 'repeat'); // 图案以平铺方式重复 ctx.fillStyle = pattern; ctx.fillRect(50, 50, 300, 200); }; // 获取 fillStyle 的当前值 const currentFillStyle = ctx.fillStyle; console.log(currentFillStyle);
strokeStyle
ctx.strokeStyle:color| gradient | pattern
,默认:#000
,描边颜色
- js
// 示例如上 // 颜色值 // 线性渐变 // 放射性渐变 // 图案 // 获取 fillStyle 的当前值
透明
globalAlpha
ctx.globalAlpha:number
,默认:1.0
,0~1的数值,值越小透明度越高,设置或获取 Canvas 的全局透明度。
注意: 高频率绘制大量图形时,过度使用全局透明度可能会影响性能。
- js
const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // 设置全局透明度为 0.5(50% 透明) ctx.globalAlpha = 0.5; // 绘制一个半透明的矩形 ctx.fillStyle = 'red'; ctx.fillRect(50, 50, 200, 100);
渐变
createLinearGradient()
ctx.createLinearGradient():(x0, y0, x1, y1)
,创建一个沿着参数坐标指定的线的线性渐变。
x0, y0:
number
,渐变的起点坐标。不带px单位x1, y1:
number
,渐变的终点坐标。不带px单位返回:
gradient:
CanvasGradient
,可以通过addColorStop()
方法在渐变中添加颜色停靠点。- js
// 创建一个线性渐变,从左上角(0, 0)到右下角(400, 400) var gradient = ctx.createLinearGradient(0, 0, 400, 400); // 定义渐变颜色的停靠点 gradient.addColorStop(0, 'red'); // 从起点(0,0)开始为红色 gradient.addColorStop(0.5, 'yellow'); // 在中间50%位置为黄色 gradient.addColorStop(1, 'blue'); // 从终点(400, 400)为蓝色 // 使用渐变填充矩形 ctx.fillStyle = gradient;
createRadialGradient()
ctx.createRadialGradient():(x0, y0, r0, x1, y1, r1)
,创建一个沿着参数坐标指定的线的放射性渐变。
x0, y0:
number
,开始圆形的圆心。不带px单位r0:
number
,开始圆形的半径。不带px单位x1, y1:
number
,结束圆形的圆心。不带px单位r1:
number
,结束圆形的半径。不带px单位返回:
gradient:
CanvasGradient
,可以通过addColorStop()
方法在渐变中添加颜色停靠点。- js
// 创建一个径向渐变,起始圆心为(200, 200),半径为50 // 终止圆心为(200, 200),半径为200 var gradient = ctx.createRadialGradient(200, 200, 50, 200, 200, 200); // 定义渐变颜色的停靠点 gradient.addColorStop(0, 'red'); // 从起始圆心开始为红色 gradient.addColorStop(0.5, 'yellow'); // 在中间50%位置为黄色 gradient.addColorStop(1, 'blue'); // 在终止圆心位置为蓝色 // 使用渐变填充矩形 ctx.fillStyle = gradient;
addColorStop()
gradient.addColorStop():(offset, color)
,用于在渐变中设置颜色停靠点。gradient
是通过上述2个方法创建出来的CanvasGradient
对象。
offset:
number
,表示颜色停靠点的位置。介于0-1之间的数字,0表示渐变的起点,1表示渐变的终点color:
Color
,要应用的颜色,可以是任意有效的 CSS 颜色值。- js
// 创建一个线性渐变,从左上角(0, 0)到右下角(400, 400) var gradient = ctx.createLinearGradient(0, 0, 400, 400); // 定义渐变颜色的停靠点 gradient.addColorStop(0, 'red'); // 从起点(0,0)开始为红色 gradient.addColorStop(0.5, 'yellow'); // 在中间50%位置为黄色 gradient.addColorStop(1, 'blue'); // 从终点(400, 400)为蓝色
图案
createPattern()
ctx.createPattern():(image, repetition)
,用于创建一个图案。
image:
HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap
,用作图案的图像,可以是以下几种类型:HTMLImageElement
:<img>
标签加载的图片HTMLCanvasElement
:一个已有图像内容的<canvas>
元素HTMLVideoElement
:一个视频元素ImageBitmap
:用于提供更高效的图像处理
repetition:
'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'
,默认:'repeat'
,指定如何重复图像。返回:
pattern:
CanvasPattern
,可用作fillStyle
或strokeStyle
进行填充或描边。- js
var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); // 创建一个图像元素 var img = new Image(); img.src = 'https://www.example.com/your-image.png'; // 替换为你自己的图片链接 img.onload = function() { // 创建图案 var pattern = ctx.createPattern(img, 'repeat'); // 选择重复方式为 'repeat' // 将图案作为填充样式 ctx.fillStyle = pattern; // 绘制一个填充图案的矩形 ctx.fillRect(0, 0, canvas.width, canvas.height); };
线型
lineWidth
ctx.lineWidth:number
,默认:1
,设置线条宽度。不带px单位
- js
// 设置线条宽度为 5 ctx.lineWidth = 5; ctx.beginPath(); ctx.moveTo(50, 100); ctx.lineTo(450, 100); ctx.stroke(); // 绘制宽度为 5 的线条
lineCap
ctx.lineCap:butt | round | square
,默认:butt
,用于设置路径的端点样式。
butt
:平直的线条端点,不做任何修饰。round
:圆形的线条端点,端点会变成一个半圆形。square
:方形的线条端点,端点会延伸成一个正方形。- js
// 设置线条宽度 ctx.lineWidth = 20; // 设置端点为 'butt'(默认值) ctx.lineCap = 'butt'; ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(450, 50); ctx.stroke(); // 绘制线条,端点是平的
lineJoin
ctx.lineJoin:round | bevel | miter
,默认:miter
,控制路径连接处的形状。
bevel
:斜接连接。连接处形成一个斜切角。round
:圆形连接。连接处会形成一个圆形的角。miter
:尖角连接。连接处会根据角度形成一个尖锐的角(需要设置miterLimit
来控制最大尖角长度)。- js
// 设置线条宽度 ctx.lineWidth = 20; // 设置连接样式为 'bevel' ctx.lineJoin = 'bevel'; ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(150, 50); ctx.lineTo(100, 100); // 三条线段形成连接点 ctx.closePath(); // 关闭路径,形成闭合的形状 ctx.stroke(); // 绘制线条
路径
开启闭合
beginPath()
ctx.beginPath():()
,开始一条新的路径的方法。每次调用 beginPath()
都会清除当前路径,使接下来的绘图操作不会连接到先前的路径上。
- js
// 第一个矩形(之前的路径已经结束) ctx.beginPath(); // 开始新的路径 ctx.rect(50, 50, 200, 100); // 绘制一个矩形 ctx.fillStyle = 'blue'; ctx.fill(); // 填充矩形 // 第二个矩形(开始新路径) ctx.beginPath(); // 开始一个新的路径 ctx.rect(100, 200, 150, 75); // 绘制另一个矩形 ctx.fillStyle = 'green'; ctx.fill(); // 填充第二个矩形
closePath()
ctx.closePath():()
,用于关闭当前路径的方法。将路径的最后一部分连接回到起始点,形成一个闭合的路径。
- js
// 绘制一个矩形 ctx.beginPath(); // 开始路径 ctx.moveTo(50, 50); // 起点 ctx.lineTo(200, 50); // 绘制到(200, 50) ctx.lineTo(200, 150); // 绘制到(200, 150) ctx.lineTo(50, 150); // 绘制到(50, 150) ctx.closePath(); // 连接最后一点到起点,闭合路径 ctx.stroke(); // 绘制矩形的边框
移动笔触
moveTo()
ctx.moveTo():(x, y)
,将当前路径的起始点移动到指定的起始点坐标点。
x, y:
number
,目标位置的横坐标、纵坐标。不带px单位- js
ctx.beginPath(); // 使用 moveTo() 将路径的起始点移动到 (50, 50) ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.stroke();
绘制路径
stroke()
ctx.stroke():()
,通过线条来绘制图形轮廓/描边(针对当前路径)。
- js
// 设置绘图样式 ctx.strokeStyle = 'blue'; // 边框颜色 ctx.lineWidth = 5; // 线宽 // 绘制一个矩形 ctx.beginPath(); // 开始路径 ctx.rect(50, 50, 200, 150); // 绘制矩形 ctx.stroke(); // 绘制矩形的边框
fill()
ctx.fill():()
,通过填充路径的内容区域生成实心的图形(针对当前路径)。
- js
// 设置填充样式 ctx.fillStyle = 'yellow'; // 填充颜色 // 绘制并填充矩形 ctx.beginPath(); // 开始路径 ctx.rect(50, 50, 200, 150); // 绘制矩形 ctx.fill(); // 填充矩形的内部
直线
lineTo()
ctx.lineTo():(x, y)
,通过连接当前路径的末端点和指定的 (x, y)
坐标来绘制一条直线。
x, y:
number
,目标位置的横坐标、纵坐标。不带px单位- js
ctx.beginPath(); ctx.moveTo(50, 50); // 使用 lineTo() 绘制一条从 (50, 50) 到 (200, 50) 的水平线 ctx.lineTo(200, 50); ctx.stroke();
矩形
rect()
ctx.rect():(x, y, width, height)
,创建一个矩形路径。
x, y:
number
,矩形的起点位置。不带px单位width, height:
number
,矩形的宽度、高度。不带px单位- js
// 设置填充颜色 ctx.fillStyle = "blue"; // 创建矩形路径 ctx.beginPath(); // 开始路径 ctx.rect(50, 50, 200, 100); // 创建矩形路径 ctx.fill(); // 填充矩形
圆形
arc()
ctx.arc():(x, y, radius, startAngle, endAngle, anticlockwise?)
,绘制一段圆弧或圆的路径。0表示3点钟方向。
x, y:
number
,圆心点。不带px单位radius:
number
,半径。不带px单位startAngle, endAngle:
弧度
,开始、结束角度。0表示3点钟方向。anticlockwise?:
boolean
,默认:false
,是否逆时针绘制圆弧。true: 逆时针,false: 顺时针。- js
// 设置填充颜色 ctx.fillStyle = "blue"; // 绘制完整的圆 ctx.beginPath(); // 开始路径 ctx.arc(250, 250, 100, 0, 2 * Math.PI); // 圆心(250, 250),半径100,角度从0到2π ctx.fill(); // 填充圆
ellipsis()
ctx.ellipsis():(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise?)
,添加一个椭圆路径。
x, y:
number
,椭圆的圆心。radiusX, radiusY:
number
,椭圆的 x 轴和 y 轴半径。rotation:
弧度
,默认:0
,椭圆的旋转角度。startAngle, endAngle:
弧度
,绘制的起始点、结束点角度anticlockwise?:
boolean
,默认:false
,是否逆时针绘制圆弧。true: 逆时针,false: 顺时针。- js
// 设置填充颜色 ctx.fillStyle = "lightblue"; // 绘制一个椭圆 ctx.beginPath(); // 圆心(250, 250),半径150和100,旋转0,绘制完整椭圆 ctx.ellipse(250, 250, 150, 100, 0, 0, 2 * Math.PI); ctx.fill(); // 填充椭圆
曲线
bezierCurveTo()
ctx.bezierCurveTo():(cp1x, cp1y, cp2x, cp2y, x, y)
,添加一个 3 次贝赛尔曲线路径。起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用 moveTo()
进行修改。
cp1x, cp1y:
number
,第一个控制点。不带px单位cp2x, cp2y:
number
,第二个控制点。不带px单位x, y:
number
,第三个点是结束点。不带px单位注意: 起点和终点确定了曲线的方向和位置,而控制点决定了曲线的弯曲程度。
- js
// 开始路径 ctx.beginPath() // 移动到起点 (50, 250) ctx.moveTo(50, 250) // 绘制贝塞尔曲线,控制点为 (150, 50) 和 (350, 450),终点为 (450, 250) ctx.bezierCurveTo(150, 50, 350, 450, 450, 250) // 绘制路径 ctx.stroke()
绘制矩形
fillRect()
ctx.fillRect():(x, y, width, height)
,绘制填充矩形。
x, y:
number
,矩形起始点。不带px单位width, height:
number
,矩形的宽度、高度。不带px单位- js
// 设置填充颜色为红色 ctx.fillStyle = "red"; // 绘制一个填充矩形 ctx.fillRect(50, 50, 200, 100); // (x, y, width, height)
strokeRect()
ctx..strokeRect():(x, y, width, height)
,绘制一个描边矩形。
x, y:
number
,矩形起始点。不带px单位width, height:
number
,矩形的宽度、高度。不带px单位- js
// 设置描边颜色为红色 ctx.strokeStyle = "red"; // 绘制一个描边矩形 ctx.strokeRect(50, 50, 200, 100); // (x, y, width, height)
clearRect()
ctx.clearRect():(x, y, width, height)
, 清除指定矩形区域,让清除部分完全透明。
x, y:
number
,矩形区域左上角的 x,y 坐标。width, height:
number
,矩形区域的宽度和高度。- js
// 绘制一个红色矩形 ctx.fillStyle = 'red'; ctx.fillRect(50, 50, 200, 100); // 清除矩形的一部分(从坐标 (50, 50) 开始,宽度 100,高度 50) ctx.clearRect(50, 50, 100, 50); // 清除矩形的上半部分 // 重新绘制一个蓝色矩形 ctx.fillStyle = 'blue'; ctx.fillRect(150, 150, 200, 100);
绘制文本
font
ctx.font:font-style? font-variant? font-weight? font-size line-height? font-family
,默认:10px sans-serif
,设置文本的字体样式。
font-style?:
normal | italic | oblique
,定义字体样式:普通,斜体,倾斜体。font-variant?:
small-caps
,用于设置字体变体,通常是小型大写字母(如:small-caps
)。font-weight?:
normal | bold | bolder | lighter | 100...900
,设置字体的粗细,常见值包括:font-size:
px | em | rem | pt
,设置字体大小,常见单位包括:line-height?:
number | % | px | em | rem
,设置行高,可以是数字、百分比或单位。font-family:设置字体的家族。
- js
// 设置斜体和粗体字体 ctx.font = "italic bold 40px 'Times New Roman'"; // 设置文本颜色 ctx.fillStyle = "red"; // 绘制文本 ctx.fillText("Styled Text", 50, 100);
textAlign
ctx.textAlign:start | end | left | right | center
,默认:start
,文本对齐选项。
start和left的区别: 有些语言书写顺序是从右到左,这时二者就有区别了。
- js
// 设置字体 ctx.font = "30px Arial"; // 设置不同的对齐方式 ctx.textAlign = "start"; // 左对齐 ctx.fillText("Start Align", 50, 50); ctx.textAlign = "center"; // 居中对齐 ctx.fillText("Center Align", 250, 100); ctx.textAlign = "end"; // 右对齐 ctx.fillText("End Align", 450, 150);
textBaseline
ctx.textBaseline:top | hanging | middle | alphabetic | ideographic | bottom
,默认:alphabetic
,基线对齐选项。
- js
// 设置字体 ctx.font = "30px Arial"; // 设置不同的垂直对齐方式,并绘制文本 ctx.textBaseline = "top"; // 基线在文本顶部 ctx.fillText("Top Baseline", 50, 50); ctx.textBaseline = "hanging"; // 挂起基线 ctx.fillText("Hanging Baseline", 50, 100); ctx.textBaseline = "middle"; // 中心基线 ctx.fillText("Middle Baseline", 50, 150); ctx.textBaseline = "alphabetic"; // 字母基线(默认) ctx.fillText("Alphabetic Baseline", 50, 200); ctx.textBaseline = "ideographic"; // 适用于象形文字 ctx.fillText("Ideographic Baseline", 50, 250); ctx.textBaseline = "bottom"; // 基线在文本底部 ctx.fillText("Bottom Baseline", 50, 300);
fillText()
ctx.fillText():(text, x, y, maxWidth?)
,绘制填充文本。
text:
string
,文本内容。x, y:
number
,文本起始点。x表示左侧边缘,y表示基线位置。maxWidth?:
number
,指定绘制文本时的最大宽度- js
// 设置字体样式 ctx.font = "30px Arial"; ctx.fillStyle = "green"; // 设置填充颜色为绿色 // 在坐标 (50, 100) 绘制文本,最大宽度为 150 像素 ctx.fillText("This is a very long text", 50, 100, 150);
strokeText()
ctx.strokeText():(text, x, y, maxWidth?)
,绘制描边文本。
text:
string
,文本内容。x, y:
number
,文本起始点。x表示左侧边缘,y表示基线位置。maxWidth?:
number
,指定绘制文本时的最大宽度- js
// 设置字体样式 ctx.font = "30px Arial"; ctx.lineWidth = 3; // 设置线宽为 3 ctx.strokeStyle = "blue"; // 设置轮廓颜色为蓝色 // 绘制文本的轮廓,最大宽度为 150 像素 ctx.strokeText("This is a long text", 50, 100, 150);
绘制图片
drawImage()
ctx.drawImage():(image, x, y)
,版本 1: 绘制图像到画布(不缩放、不裁剪)
image:
Image | Canvas | Video
,绘制到上下文的元素。允许任何的画布图像源。x, y:
number
,图像起始位置(左上角)在画布上的水平、垂直坐标。不带px单位。- js
// 创建一个图像对象 var img = new Image(); img.src = 'https://www.example.com/your-image.jpg'; // 请替换成你自己的图片 URL img.onload = function() { // 当图像加载完成后,绘制图像 ctx.drawImage(img, 50, 50); // 将图像绘制到 (50, 50) 位置 };
ctx.drawImage():(image, x, y, width, height)
,版本 2: 绘制图像并缩放。
image:
Image | Canvas | Video
,绘制到上下文的元素。允许任何的画布图像源。x, y:
number
,图像起始位置(左上角)在画布上的水平、垂直坐标。不带px单位。width, height:
number
,缩放图像到指定的宽度和高度。不带px单位。- js
// 创建一个图像对象 var img = new Image(); img.src = 'https://www.example.com/your-image.jpg'; // 请替换成你自己的图片 URL img.onload = function() { // 绘制图像并缩放 ctx.drawImage(img, 50, 50, 200, 150); // 将图像绘制到 (50, 50) 位置,并缩放到 200x150 };
ctx.drawImage():(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
,版本 3: 从图像中裁剪出指定的区域,并将其绘制到画布。
image:
Image | Canvas | Video
,绘制到上下文的元素。允许任何的画布图像源。sx, sy:
number
,image裁剪区域的起始点坐标。不带px单位。sWidth, sHeight:
number
,image裁剪区域的宽度和高度。不带px单位。dx, dy:
number
,目标画布上的左上角坐标。不带px单位。dWidth, dHeight:
number
,目标画布上绘制的宽高。不带px单位。- js
// 创建一个图像对象 var img = new Image(); img.src = 'https://www.example.com/your-image.jpg'; // 请替换成你自己的图片 URL img.onload = function() { // 裁剪图像并绘制 ctx.drawImage(img, 100, 100, 300, 200, 50, 50, 250, 150); // 从 (100, 100) 开始裁剪,裁剪出 300x200 的区域 // 然后将裁剪的部分绘制到 (50, 50) 位置,缩放到 250x150 };
js/** 将视频的每帧绘制到画布上,实现视频播放的效果。 */ function draw() { ctx.drawImage(video, 0, 0, 500, 500); // 将视频帧绘制到画布上 requestAnimationFrame(draw); // 请求下一帧 } draw();
形变
save()
ctx.save():()
,将当前的绘图状态保存到状态栈中。
ctx.restore():()
,从状态栈中恢复canvas的当前绘画状态。
- js
// 绘制第一个矩形 ctx.save(); // 保存当前状态 ctx.fillStyle = 'red'; // 改变填充颜色为红色 ctx.fillRect(50, 50, 200, 100); // 绘制红色矩形 ctx.restore(); // 恢复之前保存的状态 // 绘制第二个矩形 ctx.save(); // 再次保存当前状态 ctx.fillStyle = 'blue'; // 改变填充颜色为蓝色 ctx.fillRect(100, 150, 200, 100); // 绘制蓝色矩形 ctx.restore(); // 恢复之前保存的状态
translate()
ctx.translate():(x, y)
,平移整个画布上的所有内容。
x, y:
number
,水平、垂直方向的移动距离。- js
// 绘制矩形 ctx.fillStyle = 'blue'; ctx.fillRect(50, 50, 100, 100); // 在 (50, 50) 位置绘制矩形 // 使用 translate 平移坐标系 ctx.translate(150, 0); // 将原点平移 150 像素到右侧 // 绘制另一个矩形 ctx.fillStyle = 'red'; ctx.fillRect(50, 50, 100, 100); // 此时矩形会绘制到 (200, 50) 位置
rotate()
ctx.rotate():(angle)
,用于旋转绘图上下文的坐标系。所有后续绘制的内容都将基于旋转后的坐标系进行。
angle:
弧度
,旋转的弧度。公式:degree * Math.PI / 180
。可以通过 translate() 方法改变中心点。- js
// 绘制矩形 ctx.fillStyle = 'green'; ctx.fillRect(50, 50, 100, 100); // 旋转坐标系 45 度(π/4 弧度) ctx.rotate(45 * Math.PI / 180); // 旋转 45 度 // 绘制矩形,旋转后的矩形 ctx.fillStyle = 'blue'; ctx.fillRect(50, 50, 100, 100); // 绘制位置会旋转
scale()
ctx.scale():(x, y)
,用于缩放绘图上下文的整个坐标系。用来增减图形在canvas中的像素数目。会影响到所有后续绘制的图形。
x, y:
number
,水平、垂直方向的缩放因子。大于1表示放大,小于1表示缩小,支持负数。- js
// 绘制未缩放的矩形 ctx.fillStyle = 'green'; ctx.fillRect(50, 50, 100, 100); // 使用 scale 进行缩放 ctx.scale(2, 1); // 水平放大 2 倍,垂直方向保持不变 // 绘制缩放后的矩形 ctx.fillStyle = 'blue'; ctx.fillRect(50, 50, 100, 100); // 水平方向放大,垂直方向不变,矩形宽200,高100
动画
setInterval()
setInterval():(callback, interval?, arg1?, arg2?, ...)
,按照指定的时间间隔重复执行一个函数,直到被清除或页面关闭。
callback:
(arg1?, arg2?, ...) => void
,要执行的回调函数。interval?:
ms
,时间间隔。arg1?, arg2?, ...:
any
,传递给回调函数的参数。返回:
intervalId:
number
,返回一个interval ID,可以调用clearInterval(intervalId)
清除定时器。- js
function greet(name) { console.log("Hello, " + name); } const intervalId = setInterval(greet, 2000, "Alice");
setTimeout()
setTimeout():(callback, delay, arg1, arg2, ...)
,在指定的延迟时间后执行一个函数,只执行一次。
callback:
(arg1?, arg2?, ...) => void
,要执行的回调函数。delay:
ms
,延迟时间。arg1, arg2, ...:
any
,传递给回调函数的参数。返回:
timeoutId:
number
,返回一个定时器 ID,可以调用clearTimeout(timeoutId)
清除定时器。- js
const timeoutId = setTimeout(function() { console.log("This will not be logged"); }, 5000); // 在 2 秒后清除定时器 setTimeout(function() { clearTimeout(timeoutId); // 清除定时器 console.log("Timeout cleared before it executed."); }, 2000);
requestAnimationFrame()
requestAnimationFrame():(callback)
,一种浏览器提供的机制,用于在浏览器的下一次重绘之前执行一个函数,它被广泛应用于动画的实现。
callback:
(timestamp?) => void
,当浏览器准备好绘制下一帧时执行。- timestamp?:
ms
,表示调用时的时间戳。可用于计算动画的进度。
- timestamp?:
注意: 它能够与浏览器的渲染帧同步,减少不必要的重绘,从而提高性能。动画过渡平滑。
注意: 当页面被切换到后台时,
requestAnimationFrame()
会暂停动画的执行,从而节省资源。返回:
id:
number
,返回一个整数 ID,该 ID 可以传递给cancelAnimationFrame()
来取消该帧的请求。- js
/** 让一个矩形在屏幕上移动 */ var x = 50; var y = 50; var dx = 2; var dy = 2; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布 ctx.fillStyle = 'green'; ctx.fillRect(x, y, 50, 50); // 绘制矩形 x += dx; // 更新 x 坐标 y += dy; // 更新 y 坐标 // 如果矩形到达边缘,改变运动方向 if (x + 50 > canvas.width || x < 0) { dx = -dx; } if (y + 50 > canvas.height || y < 0) { dy = -dy; } requestAnimationFrame(animate); // 请求下一帧 } animate(); // 启动动画