【Web2D/3D】Canvas(第三篇)

1. 前言

<canvas>是HTML5新增元素,它是一个画板,开发人员基于它的2D上下文或webgl上下文,使用JS脚本绘制简单的动画、可交互画面,甚至进行视频渲染。

本篇介绍基于canvas的2D上下文绘制2D画面的一些方法和属性。

2. canvas元素

2D坐标系:左上点是坐标原点(0,0),x轴正方向向右,y轴正方向向下,x正方向为弧度0。

视口viewport:canvas宽高确定视口大小,默认宽高(300px, 150px)。

canvas元素是HTMLCanvasElement实例化对象,以下列出HTMLCanvasElement原型对象的方法和属性。

|------------------------------------------------------------|-------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|
| 方法和属性 | 描述 | 示例 |
| HTMLCanvasElement .prototype.getContext() | 功能:获取一个渲染上下文 输入:'2d' | 'webgl' | 'experimental-webgl' 输出:CanvasRenderingContext2D | const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); |
| HTMLCanvasElement .prototype.toDataURL() | <略> | <略> |
| HTMLCanvasElement .prototype.toBlob() | <略> | <略> |
| HTMLCanvasElement .prototype.captureStream() | <略> | <略> |
| HTMLCanvasElement .prototype .transferControlToOffscreen() | <略> | <略> |
| HTMLCanvasElement .prototype.width | 功能:设置画布的宽度,默认300px,不建议使用css设置width | <canvas id="canvas" width="500" height="450"> 不支持canvas </canvas> |
| HTMLCanvasElement .prototype.height | 功能:设置画布的高度,默认150px,不建议使用css设置height | <canvas id="canvas" width="500" height="450"> 不支持canvas </canvas> |

ctx是CanvasRenderingContext2D的实例化对象,CanvasRenderingContext2D原型对象的方法和属性如下。

|--------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 方法和属性 | 描述 | 示例 |
| 绘制矩形 |||
| CanvasRenderingContext2D .prototype.fillRect(x,y, width, height) | 功能:绘制一个填充矩形 输入: x 矩形左上角x轴坐标 y 矩形左上角y轴坐标 width 矩形宽度 height 矩形高度 | ctx.fillStyle = "rgb(200,0,0)"; ctx.fillRect (10, 10, 55, 50); |
| CanvasRenderingContext2D .prototype.strokeRect(x,y, width, height) | 功能:绘制一个描边矩形 输入:同fillRect的参数 | ctx.strokeRect(10, 70, 55, 50); |
| CanvasRenderingContext2D .prototype.clearRect(x,y, width, height) | 功能:清除指定的矩形区域,清除后这块区域变透明 输入:同fillRect的参数 | ctx.clearRect(15, 15, 50, 25); |
| 绘制路径 |||
| CanvasRenderingContext2D .prototype.beginPath() | 功能:新建一条路径 输入:无 | ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); ctx.stroke(); // 绘制出一个三角形 ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.fill(); // 绘制出一个三角形,并填充黑色 |
| CanvasRenderingContext2D .prototype.moveTo(x,y) | 功能:移动画笔到坐标x,y 输入: x 位置的x轴坐标 y 位置的y轴坐标 | ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); ctx.stroke(); // 绘制出一个三角形 ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.fill(); // 绘制出一个三角形,并填充黑色 |
| CanvasRenderingContext2D .prototype.lineTo(x,y) | 功能:定义一条从当前位置到目标点x,y的直线 输入: x 目标点的x轴坐标 y 目标点的y轴坐标 | ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); ctx.stroke(); // 绘制出一个三角形 ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.fill(); // 绘制出一个三角形,并填充黑色 |
| CanvasRenderingContext2D .prototype.closePath() | 功能:闭合路径 | ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); ctx.stroke(); // 绘制出一个三角形 ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.fill(); // 绘制出一个三角形,并填充黑色 |
| CanvasRenderingContext2D .prototype.stroke() | 功能:绘制路径 | ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); ctx.stroke(); // 绘制出一个三角形 ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.fill(); // 绘制出一个三角形,并填充黑色 |
| CanvasRenderingContext2D .prototype.fill() | 功能:填充闭合区域,如果路径未闭合,fill()会自动将路径闭合 | ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); ctx.stroke(); // 绘制出一个三角形 ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.fill(); // 绘制出一个三角形,并填充黑色 |
| CanvasRenderingContext2D .prototype.arc(x , y, r, startAngle, endAngle, anticlockwise) | 功能:绘制圆弧,以x,y为圆心,以r为半径,从startAngle弧度开始到endAngle弧度结束,anticlockwise true表示逆时针,false表示顺时针,默认false 注:弧度0表示x轴正方向 | ctx.beginPath(); ctx.arc(150, 50, 40, 0, -Math.PI / 2, true); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.arc(150, 150, 40, 0, Math.PI, false); ctx.fill(); |
| CanvasRenderingContext2D .prototype.arcTo(x1, y1, x2, y2, radius) | 功能:绘制圆弧,以x1,y1和x2,y2为控制点,以radius为圆弧半径 注:圆弧与当前点到x1,y1直线,以及x1,y1到x2,y2直线相切 | ctx.beginPath(); ctx.moveTo(50, 50); ctx.arcTo(200, 50, 200, 200, 100); ctx.lineTo(200, 200) ctx.stroke(); |
| CanvasRenderingContext2D .prototype.quadraticCurveTo(cpx1, cpy1, x, y) | 功能:以cpx1,cpy1为控制点,以x,y为终点,绘制二次贝塞尔曲线 | ctx.beginPath(); ctx.moveTo(10, 200); const cpx1=40, cpy1=100; const x=200, y=200; ctx.quadraticCurveTo(cpx1, cpy1, x, y); ctx.stroke(); |
| CanvasRenderingContext2D .prototype.bezierCurveTo(cpx1,cpy1, cpx2, cpy2, x, y); | 功能:以cpx1,cpy1和cpx2,cpy2为控制点,以x,y为终点,绘制三次贝塞尔曲线 | ctx.beginPath(); ctx.moveTo(40, 200); const cpx1=20, cpy1=100; const cpx2=100, cpy2= 20; const x=200, y=200; ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); ctx.stroke(); |
| CanvasRenderingContext2D .prototype.getLineDash() | 功能:获取当前虚线样式 输入:无 输出:Array<number> | ctx.setLineDash([20, 5]); ctx.lineDashOffset = 0; ctx.strokeRect(50, 50, 210, 210); const arr = ctx.getLineDash() |
| CanvasRenderingContext2D .prototype.setLineDash(widthArr) | 功能:设置线段与间隙长度的交替 输入:Array<number> | ctx.setLineDash([20, 5]); ctx.lineDashOffset = 0; ctx.strokeRect(50, 50, 210, 210); const arr = ctx.getLineDash() |
| CanvasRenderingContext2D .prototype.lineDashOffset = offset | 功能:设置起始偏移量 | ctx.setLineDash([20, 5]); ctx.lineDashOffset = 0; ctx.strokeRect(50, 50, 210, 210); const arr = ctx.getLineDash() |
| CanvasRenderingContext2D .prototype.fillStyle = color | 功能:设置图形填充颜色,默认黑色 输入:color 颜色值 | 渐变对象 | 图案对象 | ctx.fillStyle = "rgb(200,0,0)"; ctx.fillRect (10, 10, 55, 50); |
| CanvasRenderingContext2D .prototype.strokeStyle = color | 功能:设置图形描边颜色,默认黑色 输入:color 颜色值 | 渐变对象 | 图案对象 | ctx.strokeStyle = "rgb(200,0,0)"; ctx.strokeRect (10, 10, 55, 50); |
| CanvasRenderingContext2D .prototype.lineWidth = width | 功能:设置线宽度,正值,默认1.0,起点和终点连续中心,上下线宽各占一半 | ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(100, 10); ctx.lineTo(100, 100); ctx.lineWidth = 10; ctx.lineCap = 'round'; ctx.lineJoin = 'miter'; ctx.stroke(); |
| CanvasRenderingContext2D .prototype.lineCap = type | 功能:线条末端样式 输入:butt | round | square | ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(100, 10); ctx.lineTo(100, 100); ctx.lineWidth = 10; ctx.lineCap = 'round'; ctx.lineJoin = 'miter'; ctx.stroke(); |
| CanvasRenderingContext2D .prototype.lineJoin = type | 功能:同一个path内,设置线条和线条间接合处的样式 输入:round | bevel | miter | ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(100, 10); ctx.lineTo(100, 100); ctx.lineWidth = 10; ctx.lineCap = 'round'; ctx.lineJoin = 'miter'; ctx.stroke(); |
| 绘制文本 |||
| CanvasRenderingContext2D .prototype.fillText(text, x, y, maxWidth?) | 功能:在指定位置x,y填充指定文本text,绘制最大宽度可选 | ctx.font = "100px sans-serif"; ctx.fillText("热爱技术", 10, 100); ctx.strokeText("热爱技术", 10, 200) |
| CanvasRenderingContext2D .prototype.strokeText(text, x, y, maxWidth?) | 功能:在指定位置x,y描边指定文本text,绘制最大宽度可选 | ctx.font = "100px sans-serif"; ctx.fillText("热爱技术", 10, 100); ctx.strokeText("热爱技术", 10, 200) |
| CanvasRenderingContext2D .prototype.font = font | 功能:绘制文本的样式,默认'10px sanf-serif' | ctx.font = "100px sans-serif"; ctx.fillText("热爱技术", 10, 100); ctx.strokeText("热爱技术", 10, 200) |
| CanvasRenderingContext2D .prototype.textAlign = align | 功能:文本对齐方式,默认alphabetic 输入:top | hanging | middle | alphabetic | ideographic | bottom | ctx.font = "100px sans-serif"; ctx.fillText("热爱技术", 10, 100); ctx.strokeText("热爱技术", 10, 200) |
| CanvasRenderingContext2D .prototype.direction = direction | 功能:文本方向,默认inherit 输入:ltr | rtl | inherit | ctx.font = "100px sans-serif"; ctx.fillText("热爱技术", 10, 100); ctx.strokeText("热爱技术", 10, 200) |
| 绘制图像 |||
| CanvasRenderingContext2D .prototype.drawImage(image, x, y, width?, heigth?) | 功能:绘制图片 输入: image: HTMLImageElement, x 开始绘制位置的x轴坐标 y 开始绘制位置的y轴坐标 width 绘制的图片宽度 height 绘制的图片高度 注:Image继承于HTMLImageElement ||
| CanvasRenderingContext2D .prototype.drawImage(image, sx, sy, sWidth, sHeigth, dx, dy, dWidth, dHeigth) | 功能:绘制图片 输入: image: HTMLImageElement, sx,sy,sWidth,sHeight 从源图像扣图位置和大小 dx,dx,dWidth,dHeight 在canvas目标中显示位置和大小 ||
| 状态的保存和恢复 |||
| CanvasRenderingContext2D .prototype.save() | 功能:将canvas当前状态保存到栈中,入栈 | ctx.fillRect(0, 0, 150, 150); ctx.save(); ctx.restore(); |
| CanvasRenderingContext2D .prototype.restore() | 功能:将上一次保存的状态从栈弹出,出栈 | ctx.fillRect(0, 0, 150, 150); ctx.save(); ctx.restore(); |
| 变换 |||
| CanvasRenderingContext2D .prototype.translate(x,y) | 功能:将canvas原点移动到指定位置x,y 输入: x 目标位置的x轴坐标 y 目标位置的y轴坐标 | ctx.save(); ctx.translate(100, 100); ctx.strokeRect(0, 0, 100, 100) ctx.restore(); ctx.translate(220, 220); ctx.fillRect(0, 0, 100, 100); |
| CanvasRenderingContext2D .prototype.rotate(angle) | 功能:将canvas坐标轴顺时针旋转一个角度 | ctx.fillStyle = "red"; ctx.save(); ctx.translate(100, 100); ctx.rotate(Math.PI / 180 * 45); ctx.fillStyle = "blue"; ctx.fillRect(0, 0, 100, 100); ctx.restore(); ctx.save(); ctx.translate(0, 0); ctx.fillRect(0, 0, 50, 50) ctx.restore(); |
| CanvasRenderingContext2D .prototype.scale(x,y) | 功能:将canvas坐标轴横纵按比例缩放 输入: x x轴缩放比例 y y轴缩放比例 | |
| CanvasRenderingContext2D .prototype.transform(a,b,c,d,e,f) a c e b d f 0 0 1 | 功能:变换矩阵 a x轴缩放比例 b x轴skew c y轴skew d y轴缩放比例 e x轴平移量 f y轴平移量 | ctx.transform(1, 1, 0, 1, 0, 0); ctx.fillRect(0, 0, 100, 100); |
| 合成 |||
| CanvasRenderingContext2D .prototype.globalCompositeOperation = type | 功能:设置图形合成方式,默认不设置,新图像覆盖原图像 输入: 1. soure-in 仅新图像与老图像重叠部分,其它区域透明 2. soure-out 新图像与老图像不重叠部分,老图像不显示 3. source-atop 新图像仅显示与老图像重叠部分,老图像仍显示 4. destination-over 新图像在老图像下面 5. destination-in 仅老图像与新图像重叠部分,其它区域透明 6. destination-out 老图像与新图像不重叠部分,新图像不显示 7. destination-atop: 老图像仅显示重叠部分,新图像在老图像下面 8. lighter 新老图像都显示,相加操作 9. darken 保留重叠部分最黑的像素,位与操作 10. lighten 保留重叠部分,位域操作 11. xor,异或操作 12. copy 仅新图像保留,其它区域透明 | <略> |
| 裁剪路径 |||
| CanvasRenderingContext2D .prototype.clip() | 功能:将已创建的路径转换成裁剪路径,仅显示裁剪区域,隐藏裁剪路径外的区域 | <略> |

有兴趣的同学可以参见:学习 HTML5 Canvas 这一篇文章就够了 | 菜鸟教程 (runoob.com)

注:以上,如有不合理之处,还请帮忙指出,大家一起交流学习~

相关推荐
前端Hardy16 小时前
HTML&CSS:数据卡片可以这样设计
前端·javascript·css·3d·html
小彭努力中20 小时前
138. CSS3DRenderer渲染HTML标签
前端·深度学习·3d·webgl·three.js
AI生成未来1 天前
斯坦福&UC伯克利开源突破性视觉场景生成与编辑技术,精准描绘3D/4D世界!
3d·3d场景·4d
汪洪墩2 天前
【Mars3d】实现这个地图能靠左,不居中的样式效果
前端·javascript·vue.js·3d·webgl·cesium
Bearnaise2 天前
GaussianDreamer: Fast Generation from Text to 3D Gaussians——点云论文阅读(11)
论文阅读·人工智能·python·深度学习·opencv·计算机视觉·3d
智驾机器人技术前线2 天前
近期两篇NeRF/3DGS-based SLAM方案赏析:TS-SLAM and MBA-SLAM
3d·slam·nerf·3dgs
Tianwen_Burning2 天前
halcon3d disparity_image_to_xyz非常重要的算子及使用条件
算法·3d
光学测量小菜鸡3 天前
OpenCV双目立体视觉重建
opencv·3d·双目相机·结构光·sgbm
豆包MarsCode3 天前
基于豆包MarsCode 和 Threejs 实现3D地图可视化
大数据·开发语言·人工智能·python·3d·程序员
工业3D_大熊3 天前
3D数据格式转换工具HOOPS Exchange如何在读取CAD文件时处理镶嵌数据?
java·linux·c++·windows·macos·3d·c#