33:canvas - 上
一、介绍
- canvas 是 HTML5 新增的一个标签,表示画布
- canvas 也是 HTML5 的画布技术,可以通过编码的方式在画布上描绘图像
1 2 3 4 5 6 7 8
| <html> <head> ... </head> <body> <canvas></canvas> </body> </html>
|
- canvas 默认是一个行内块元素
- canvas 默认画布大小是 300 * 150
- canvas 默认没有边框, 背景默认为无色透明
1.1 canvas 画布大小
- 在绘图之前, 先要确定一个画布的大小
- 因为画布默认是按照比例调整
- 所以我们调整宽度或者高度的时候, 调整一个, 另一个自然会按照比例自己调整
- 我们也可以宽高一起调整
- 调整画布大小有两种方案
- 第一种 : 通过 css 样式 ( 不推荐 )
- 第二种 : 通过标签属性 ( 推荐 )
<canvas width="1000" height="500"></canvas>
- 两种方案的区别
- 通过 css 样式的调整方案(不推荐)
- 因为 css 并没有设置了画布的大小,而是把原来 300 * 150 的画布的可视窗口变成了 1000 * 500。所以真实画布并没有放大, 只是可视程度变大了
- 如:把一个 300 * 150 的图片,放大到 1000 * 500 的大小来看

- 通过属性的调整方案(推荐)
* 这才是真正的将画布大小调整到 1000 * 500

1.2 画布的坐标
- canvas 画布和 css 的坐标系一样。左上角为 0 0 ,向右向下延伸为正方向

二、canvas 初体验
- canvas 画布很简单,类似于 windows 电脑上的画板工具

- 在绘制之前,先选定一个形状工具(直线,矩形,圆形,...)
- 确定路径起点,落笔
- 移动到路径终点,抬笔
- 设定样式(粗细,颜色)
- 在 canvas 绘制也是一样的逻辑
- 创建一个画布工具箱
- 语法:
canvas元素.getContext('2d')
- 如:
const ctx = canvasEle.getContext('2d')
- 确定路径起点,落笔
- 将画笔移动到一个指定位置下笔
- 语法:
工具箱.moveTo(x轴坐标, y轴坐标)
ctx.moveTo(100, 100)
- 移动到路径终点,抬笔
- 将画笔移动到一个指定位置,画下一条轨迹(路径)
- 注意:这里暂时没有显示,因为只是画了一个轨迹(路径)
- 语法:
工具箱.lineTo(x轴坐标, y轴坐标)
ctx.lineTo(300, 100)
- 如果多个lineTo方法连续执行,表示连续绘制,即在本次抬笔的位置直接落笔。
- 设定路径样式(可在落笔之前设置)
- 语法:
工具箱.样式属性 = 样式值
- 线的宽度:
ctx.lineWidth = 10
- 线的颜色:
ctx.strokeStyle = '#000'
- 确定本次绘制的路径信息(生效,显现绘制效果)
- 如:绘制一条线段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const canvasEle = document.querySelector('#canvas')
const ctx = canvasEle.getContext('2d')
ctx.moveTo(100, 100)
ctx.lineTo(300, 100)
ctx.lineWidth = 10
ctx.strokeStyle = '#000'
ctx.stroke()
|
- 从坐标 ( 100, 100 ) 绘制到坐标 ( 300, 100 )
- 线段长度为 200px
- 线段宽度为 10px
- 线段颜色为 '#000' ( 黑色 )

三、canvas 线宽颜色问题
- 需要注意,在绘制任何图形时,尽量不要出现奇数宽度,因为canvas在划分了坐标点后,每次绘制都是绘制在点坐标上。
- 一个宽度为 1px 的线段就会以如下这种方式被画出来:

- canvas在描绘这个线段的时候,会把线段的最中心点放在这个像素点位上
- 也就是说,在描述线宽的时候,实际上会从 0.5px 的位置绘制到 1.5px 的位置,合计描述宽度为 1px
- 但是浏览器不能识别小数像素
- 也就是说浏览器没办法从 0.5 开始绘制,也没有办法绘制到 1.5 停止
- 那么就只能是从 0 开始绘制到 2。所以线宽就会变成 2px 了
- 又因为本身一个像素的黑色被强制拉伸到两个像素宽度,所以颜色就会变浅
- 就像我们一杯墨水, 倒在一个杯子里面就是黑色
- 但是到在一个杯子里面的时候, 又倒进去一杯水, 颜色就会变浅
- 所以最终呈现出来的样式,如下图:

- 所以,我们在进行 canvas 绘制时,涉及到线段的宽度时,一般不会把线段宽度设置成奇数,尽量设置为偶数
四、线段的开始与闭合
- 在绘制两条样式不同的独立线段时,如果直接进行绘制,后绘制的线段样式可能会影响先绘制的线段样式,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
ctx.moveTo(100, 100); ctx.lineTo(200, 100); ctx.lineWidth = 10; ctx.strokeStyle = "red"; ctx.stroke();
ctx.moveTo(100, 200); ctx.lineTo(200, 200); ctx.lineWidth = 4; ctx.strokeStyle = "#000"; ctx.stroke();
|

- 可以看到第二条线段的样式覆盖在了第一条线段上方
- 这是因为在绘制一条新的线段之前,需要先初始化工具箱中的样式设置。
- 也就是所谓的,准备绘制一条新的线段:
ctx.beginPath();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 100); ctx.lineWidth = 10; ctx.strokeStyle = "red"; ctx.stroke();
ctx.beginPath(); ctx.moveTo(100, 200); ctx.lineTo(200, 200); ctx.lineWidth = 4; ctx.strokeStyle = "#000"; ctx.stroke();
|

- 还可以通过绘制连续线段,组合成几何图形,如三角形:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(100, 100); ctx.lineTo(200, 100); ctx.lineTo(100, 200); ctx.lineTo(100, 100);
ctx.lineWidth = 8; ctx.strokeStyle = "red";
ctx.stroke();
|
绘制效果:


- 当最后一条线段的终点和第一条线段的起点重复时,并没有看到一种“闭合”的效果。
- 这就需要我们主动设置连续线段的闭合:
ctx.closePath()
- 只要已经绘制了至少两条连续线段,就可以使用closePath进行闭合,它会自动将最后一条线段的终点和第一条线段的起点进行连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(100, 100); ctx.lineTo(200, 100); ctx.lineTo(100, 200); ctx.lineTo(100, 100);
ctx.lineWidth = 8; ctx.strokeStyle = "red";
ctx.closePath();
ctx.stroke();
|

五、端点样式
- 在绘制连续线段时,canvas提供了多种线段连接点的样式处理
- 属性为:
ctx.lineJoin = '值'
- 尖角:
miter
(默认)
- 圆角:
round
- 斜角:
bevel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 150); ctx.lineTo(100, 200); ctx.lineWidth = 10; ctx.strokeStyle = "red";
ctx.lineJoin = 'miter'; ctx.stroke();
ctx.beginPath(); ctx.moveTo(200, 100); ctx.lineTo(300, 150); ctx.lineTo(200, 200); ctx.lineWidth = 10; ctx.strokeStyle = "red";
ctx.lineJoin = 'round'; ctx.stroke();
ctx.beginPath(); ctx.moveTo(300, 100); ctx.lineTo(400, 150); ctx.lineTo(300, 200); ctx.lineWidth = 10; ctx.strokeStyle = "red";
ctx.lineJoin = 'bevel'; ctx.stroke();
|
效果如图:

- 在绘制单条线段时,线段两端的样式也可以被控制
- 属性:
ctx.lineCap = '值'
- butt,无,默认
- round,圆
- square,方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
console.log(ctx);
ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 100); ctx.lineWidth = 20; ctx.strokeStyle = "red";
ctx.lineCap = "butt"; ctx.stroke();
ctx.beginPath(); ctx.moveTo(100, 150); ctx.lineTo(200, 150); ctx.lineWidth = 20; ctx.strokeStyle = "red";
ctx.lineCap = "round"; ctx.stroke();
ctx.beginPath(); ctx.moveTo(100, 200); ctx.lineTo(200, 200); ctx.lineWidth = 20; ctx.strokeStyle = "red";
ctx.lineCap = "square"; ctx.stroke();
|
效果如图:

- 注意:
- square 和 round 会让线段稍稍变长
- 线段端点样式的颜色会和线段颜色保持一致
六、填充
- 当使用连续线段绘制出几何图形后,还可以对图形进行颜色填充
- 设置填充颜色:
ctx.fillStyle = '颜色值'
- 填充:
ctx.fill()
1 2 3 4 5 6 7 8 9 10 11 12 13
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 100); ctx.lineTo(200, 200); ctx.lineTo(100, 100); ctx.closePath();
ctx.fillStyle = "pink"; ctx.fill();
|
效果如图:

- 注意:填充时可以不进行路径闭合,填充方法会自动闭合路径后,再进行填充
- 填充和描边可以同时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const canvas = document.querySelector(".mycanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 100); ctx.lineTo(200, 200); ctx.lineTo(100, 100); ctx.closePath();
ctx.lineWidth = 10; ctx.strokeStyle = "black"; ctx.stroke();
ctx.fillStyle = "pink"; ctx.fill();
|
效果如图:

七、canvas 的填充规则 - 非零填充(了解)
示例1
- 绘制一个 “回” 形
- 注意一个细节 :
- 里面的小正方形我们会按照 顺时针 的方向绘制
- 外面的大正方形我们也会按照 顺时针 的方向绘制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.moveTo(200, 100); ctx.lineTo(300, 100); ctx.lineTo(300, 200); ctx.lineTo(200, 200);
ctx.moveTo(150, 50); ctx.lineTo(350, 50); ctx.lineTo(350, 250); ctx.lineTo(150, 250);
ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.stroke();
|


- 我们发现,两个都被填充了
- 这是因为,在填充的时候,就是会一次性把所有的内容都会填充好
- 注意 :
- 和是否闭合路径 ( ctx.closePath() ) 没有关系
- 和里外正方形的绘制先后顺序没有关系
示例2
- 再绘制一个 “回” 形
- 注意一个细节:
- 里面的小正方形我们会按照 逆时针 的方向绘制
- 外面的大正方形我们也会按照 顺时针 的方向绘制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.moveTo(200, 100); ctx.lineTo(200, 200); ctx.lineTo(300, 200); ctx.lineTo(300, 100);
ctx.moveTo(150, 50); ctx.lineTo(350, 50); ctx.lineTo(350, 250); ctx.lineTo(150, 250);
ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.stroke();
|

填充后看效果:

- 此时发现,和刚才填充出来的结果不一样了
- 可以得出结论:填充的区域和线段绘制时的 顺时针 逆时针 方向有关系!
非零填充
- 其实我们的填充和顺时针逆时针有关系,但不是简单的顺逆时针的问题
- 非零填充的概念 :
- 从任何一个区域向画布最外层移动
- 按照经历最少的边数量计算
- 其中经历的顺时针边,记录为 +1
- 经历的逆时针边,记录为 -1
- 只要最终总和不为 零,那么该区域填充
- 如果最终总和为 零,那么该区域不填充
示例3:

- 这是两个矩形对接在一起, 一个是顺时针绘制, 一个是逆时针绘制
- 我们来分析一下看看
- 首先, 最左侧封闭图形区域

- 如果走最短的路线出来的话,会经历一条顺时针的边
- 记录为 +1
- 最终为 +1
- 所以该区域会被填充

- 经历最短路线出来的话,会经历一条逆时针的边
- 记录为 -1
- 最终为 -1
- 所以该区域会被填充

- 经历最短路线出来的话,必然会经历一条顺时针的边 和 一条逆时针的边
- 顺时针记录为 +1
- 逆时针记录为 -1
- 合计为 0
- 所以该区域不会被填充
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.moveTo(100, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 150); ctx.lineTo(100, 150); ctx.lineTo(100, 50);
ctx.moveTo(150, 100); ctx.lineTo(150, 200); ctx.lineTo(250, 200); ctx.lineTo(250, 100); ctx.lineTo(150, 100);
ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.stroke();
ctx.fill()
|

八、绘制矩形
- 矩形路径:
- 语法:
ctx.rect( 矩形起点 x 轴坐标, 矩形起点 y 轴坐标, 矩形宽度, 矩形高度 )
- 如:
ctx.rect(100, 100, 100, 100)
- 表示在坐标 100,100 的位置绘制一个 100*100 的矩形路径,默认无填充无描边
- 可通过
ctx.stroke()
描边,通过ctx.fill()
填充
- 可通过
lineWidth
,strokeStyle
,fillStyle
属性,分别设置描边宽度,描边色,填充色
- 描边矩形:
- 语法:
ctx.strokeRect( 矩形起点 x 轴坐标, 矩形起点 y 轴坐标, 矩形宽度, 矩形高度 )
- 如:
ctx.strokeRect(300, 100, 100, 100)
- 表示在坐标 300,100 的位置绘制一个 100*100 的描边矩形,无填充
- 可通过
lineWidth
,strokeStyle
属性,设置描边宽度,描边色
- 填充矩形:
- 语法:
ctx.fillRect( 矩形起点 x 轴坐标, 矩形起点 y 轴坐标, 矩形宽度, 矩形高度 )
- 如:
ctx.fillRect(500, 100, 100, 100)
- 表示在坐标 500,100 的位置绘制一个 100*100 的填充矩形,无描边
- 可通过
fillStyle
属性,设置填充色
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.rect(100, 100, 100, 100);
ctx.strokeRect(300, 100, 100, 100);
ctx.fillRect(500, 100, 100, 100);
|
效果如图:

九、绘制圆形
- 什么是圆:
- 圆 就是从一个点出发,按照半径,画弧线,当弧线饶了一圈回到原点的时候,就是一个圆形。
- 在canvas内,绘制圆形,其实就是在绘制弧线
- 什么是弧度

- 以圆心 o 做坐标轴,x 轴正方向上和圆周的交点为弧度起点

- 在圆周上,从弧度起点,顺着圆周移动,移动的距离成为弧长,当弧长和半径一样时
- 这段弧长所对应的圆心角是 1 弧度

- 根据圆周公式 : 周长 = 2 * π * r
- 所以:
* 一个圆周是 : 2 * π
* 半个圆周是 : π
* 四分之一圆周是 : π / 2
- 了解了什么是弧度,接下来就可以开始绘制弧线了,绘制弧线有两种方式:圆弧,椭圆弧
- 圆弧
- 语法:
ctx.arc( x, y, r, startAngle, endAngle, counterclockwise )
- x:圆心的 x 轴坐标
- y:圆心的 y 周坐标
- r:圆的半径
- startAngle:绘制弧线的起点弧度
- endAngle:绘制弧线的终点弧度
- counterclockwise:方向,false 为顺时针(默认),true 为逆时针
- 如:
ctx.arc( 150, 150, 100, 0, 1, false )
- 表示绘制一个圆心在坐标 150,150,半径100,从 0 顺时针 到 1 的弧线路径,默认无填充无描边
1 2 3 4 5 6 7 8 9 10 11 12 13
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.arc( 150, 150, 100, 0, Math.PI, false )
ctx.lineWidth = 2; ctx.strokeStyle = "red"; ctx.stroke();
|

- 椭圆弧
* 语法:`ctx.ellipse( x, y, radiusX, radiusY, rotation, startAngle, endAngle, antiClockwise )`
+ x:椭圆中心点的 x 轴坐标
+ y:椭圆中心点的 y 轴坐标
+ radiusX:椭圆在 x 轴方向上的半径
+ radiusY:椭圆在 y 轴方向上的半径
+ rotation:旋转弧度,指讲该椭圆进行旋转
+ startAngle:弧线开始弧度
+ endAngle:弧线结束弧度
+ antiClockwise:方向,false 表示逆时针绘制(默认),true 表示顺时针绘制
* 如:`ctx.ellipse( 300, 150, 200, 100, 0, 0, Math.PI * 2, false )`
* 表示绘制一个圆心在坐标 350,150,x轴半径200,y轴半径为100,不旋转,从 0 顺时针 到 Math.PI * 2 的弧线路径,默认无填充无描边
1 2 3 4 5 6 7 8 9 10 11 12
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.ellipse( 300, 150, 200, 100, 0, 0, Math.PI * 2, false )
ctx.lineWidth = 2; ctx.stroke();
|

* 这样一个椭圆就出来了,解释一下这些内容的意义

* 旋转弧度,就是在现在的基础上,让整个图形进行旋转
1
| ctx.ellipse( 300, 150, 200, 100, Math.PI / 2, 0, Math.PI * 2, false )
|

十、擦除画布
- 就像画画时的橡皮擦,擦除掉指定区域的内容
- 语法:
工具箱.clearRect( 矩形起点 x 轴坐标, 矩形起点 y 轴坐标, 矩形宽度, 矩形高度 )
- 如:
工具箱.clearRect( 150, 150, 30, 30 )
- 表示从坐标 150, 150 位置开始,擦除一块 30 * 30 的区域

- 注意:
- clearRect默认只能擦除填充和描边,并不能擦除路径
- canvas中的绘制方法(如stroke,fill),会以“上一次 beginPath 之后的所有路径为基础进行绘制
- 如果没有使用beginPath()方法,上一次描述的路径没有被清除,这一次进行描边等操作还会绘制出之前的路径,表现出一种类似没有擦除的状态。
- 所以为了彻底擦除,在使用了clearRect后,一般都会再执行一次beginPath方法
十一、绘制文字
- 在canvas内可以直接绘制文字,不需要通过线段一笔一划的写出来
- 描边文字(空心):
- 语法:
ctx.strokeText("文字内容", x 坐标, y 坐标);
- 填充文字(实心):
- 语法:
ctx.fillText("文字内容", x 坐标, y 坐标);
1 2 3 4 5 6 7 8 9
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.fillText("测试", 100, 100); ctx.strokeText("大前端", 100, 200);
|

- 文字样式修饰
- 字体大小:
ctx.font = '字体大小 字体'
- 文字水平对齐:
ctx.textAlign = 'left | center | right';
- 文字垂直对齐:
ctx.textBaseline = 'top | middle | bottom';
- 注意:文字的样式修饰需要在绘制之前设置
1 2 3 4 5 6 7 8 9 10 11
| const canvasEle = document.querySelector('.mycanvas')
const ctx = canvasEle.getContext('2d')
ctx.font = "50px 黑体"; ctx.fillText("测试", 100, 100);
|

水平对齐:ctx.textAlign |
垂直对齐:ctx.textBaseline |
start:文本在指定的位置开始 end:文本在指定的位置结束 center:居中对齐 left:左对齐 right:右对齐 |
alphabetic:默认,文本基线是普通的字母基线 top:文本基线是 em 方框的顶端 hanging:文本基线是悬挂基线 middle:文本基线是 em 方框的正中 ideographic:文本基线是 em 基线 bottom:文本基线是 em 方框的底端 |
 |
 |
- 获取文本信息
- 语法:
ctx.measureText("文本")
- 获取文本宽度:
ctx.measureText("前端").width
- 用于给文本添加下划线,或边框线等操作
十二、阴影
- 在canvas中,还可以对路径添加阴影效果(文字也可以有阴影)
- 阴影 x 轴偏移:
ctx.shadowOffsetX = number;
- 阴影 y 轴偏移:
ctx.shadowOffsetY = number;
- 模糊大小:
ctx.shadowBlur = number;
- 阴影颜色:
ctx.shadowColor = '颜色值';
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const canvasEle = document.querySelector('.mycanvas');
const ctx = canvasEle.getContext('2d');
ctx.shadowOffsetX = 30; ctx.shadowOffsetY = 10; ctx.shadowBlur = 2; ctx.shadowColor = "#aaa";
ctx.font = "50px 黑体"; ctx.strokeText("测试", 100, 50); ctx.fillText("测试", 300, 50);
ctx.strokeRect( 100, 80, 100, 50); ctx.fillRect( 300, 80, 100, 50);
ctx.arc( 150, 200, 50, 0, 2 * Math.PI); ctx.stroke(); ctx.beginPath(); ctx.arc( 350, 200, 50, 0, 2 * Math.PI); ctx.fill();
|
十三、绘制虚线
- 语法:
工具箱.setLineDash([ 第一段长度, 第二段长度, ... ])
- 如:
ctx.setLineDash([5, 10])
- 表示绘制出的虚线为:实5,虚10,实5,虚10,……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const canvasEle = document.querySelector('.mycanvas');
const ctx = canvasEle.getContext('2d'); console.log(ctx);
ctx.setLineDash([ 5, 10 ]);
ctx.moveTo( 100, 50 ); ctx.lineTo( 400, 50 ); ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.stroke();
ctx.font = "100px 黑体"; ctx.strokeText("测试", 100, 200);
|
注意:填充无法设置虚线效果
十四、总结
- 创建一个画笔对象(获取工具箱)
const ctx = canvasElement.getContext('2d');
- 常用属性
- 线条粗细:
ctx.lineWidth = number;
- 描边色:
ctx.strokeStyle = '颜色值';
- 端点样式:
ctx.lineCap = 'butt | round | square';
- 接洽点样式:
ctx.lineJoin = 'miter | bevel | round';
- 填充色:
ctx.fillStyle = '颜色值';
- 字体大小:
ctx.font = '字体大小 字体';
- 文字水平对齐:
ctx.textAlign = 'left | center | right';
- 文字垂直对齐:
ctx.textBaseline = 'top | middle | bottom';
- 阴影 x 轴偏移:
ctx.shadowOffsetX = number;
- 阴影 y 轴偏移:
ctx.shadowOffsetY = number;
- 模糊大小:
ctx.shadowBlur = number;
- 阴影颜色:
ctx.shadowColor = '颜色值';
- 常用方法
- 下次绘制开启新路径(弃用已存在路径):
ctx.beginPath();
- 开始绘制线段的起点:
ctx.moveTo(x, y);
- 连线到:
ctx.lineTo(x, y);
- 闭合路径:
ctx.closePath();
- 描边:
ctx.stroke();
- 填充:
ctx.fill();
- 矩形路径:
ctx.rect(x, y, w, h);
- 描边矩形:
ctx.strokeRect(x, y, w, h);
- 填充矩形:
ctx.fillRect(x, y, w, h);
- 圆弧路径:
ctx.arc(cx, cy, r, start, end, false);
- 椭圆弧路径:
ctx.ellipse( cx, cy, xr, yr, rotate, start, end, false );
- 擦除:
ctx.clearRect(x, y, w, h);
- 填充文字:
ctx.fillText(string, x, y);
- 描边文字:
ctx.strokeText(string, x, y);
- 获取文字信息:
ctx.measureText('测试');
- 设置虚线:
setLineDash([线段1宽度, 线段2宽度, ...])