在前端领域,如果只是懂 Vue
或者 React
,未来在职场的竞争力可能会比较弱。
根据我多年在家待业经验来看,前端未来在 数据可视化
和 AI
这两个领域会比较香,而 Canvas
是数据可视化在前端方面的基础技术。
本文就用光的速度将 canvas
给入门了。
01.gif
要入门一个技术,前期最重要是快!所以本文只讲入门内容,能应付简单项目。深入的知识点会在其他文章讲解。
Canvas
中文名叫 “画布”,是 HTML5
新增的一个标签。Canvas
允许开发者通过 JS
在这个标签上绘制各种图案。Canvas
拥有多种绘制路径、矩形、圆形、字符以及图片的方法。Canvas
在某些情况下可以 “代替” 图片。Canvas
可用于动画、游戏、数据可视化、图片编辑器、实时视频处理等领域。Canvas | SVG |
---|---|
用JS动态生成元素(一个HTML元素) | 用XML描述元素(类似HTML元素那样,可用多个元素来描述一个图形) |
位图(受屏幕分辨率影响) | 矢量图(不受屏幕分辨率影响) |
不支持事件 | 支持事件 |
数据发生变化需要重绘 | 不需要重绘 |
就上面的描述而言可能有点难懂,你可以打开 AntV
旗下的图形编辑引擎做对比。G6[1] 是使用 canvas
开发的,X6[2] 是使用 svg
开发的。
我的建议是:如果要展示的数据量比较大,比如一条数据就是一个元素节点,那使用 canvas
会比较合适;如果用户操作的交互比较多,而且对清晰度有要求(矢量图),那么使用 svg
会比较合适。
学习前端一定要动手敲代码,然后看效果展示。
起步阶段会用几句代码说明 canvas
如何使用,本例会画一条直线。
HTML
中创建 canvas
元素js
获取 canvas
标签canvas
标签中获取到绘图工具canvas
标签上绘制图形02.png
<!-- 1、创建 canvas 元素 -->
<canvas
id="c"
width="300"
height="200"
style="border: 1px solid #ccc;"
></canvas>
<script>
// 2、获取 canvas 对象
const cnv = document.getElementById('c')
// 3、获取 canvas 上下文环境对象
const cxt = cnv.getContext('2d')
// 4、绘制图形
cxt.moveTo(100, 100) // 起点坐标 (x, y)
cxt.lineTo(200, 100) // 终点坐标 (x, y)
cxt.stroke() // 将起点和终点连接起来
</script>
复制代码
moveTo
、 lineTo
和 stroke
方法暂时可以不用管,它们的作用是绘制图形,这些方法在后面会讲到~
canvas
有 默认的 宽度(300px) 和 高度(150px)
如果不在 canvas
上设置宽高,那 canvas
元素的默认宽度是300px,默认高度是150px。
canvas
元素提供了 width
和 height
两个属性,可设置它的宽高。
需要注意的是,这两个属性只需传入数值,不需要传入单位(比如 px
等)。
<canvas width="600" height="400"></canvas>
复制代码
使用 css
设置 canvas
的宽高,会出现 内容被拉伸 的后果!!!
03.png
<style>
#c {
width: 400px;
height: 400px;
border: 1px solid #ccc;
}
</style>
<canvas id="c"></canvas>
<script>
// 1、获取canvas对象
const cnv = document.getElementById('c')
// 2、获取canvas上下文环境对象
const cxt = cnv.getContext('2d')
// 3、绘制图形
cxt.moveTo(100, 100) // 起点
cxt.lineTo(200, 100) // 终点
cxt.stroke() // 将起点和终点连接起来
console.log(cnv.width) // 获取 canvas 的宽度,输出:300
console.log(cnv.height) // 获取 canvas 的高度,输出:150
</script>
复制代码
canvas
的默认宽度是300px,默认高度是150px。
css
修改 canvas
的宽高(比如本例变成 400px * 400px),那宽度就由 300px 拉伸到 400px,高度由 150px 拉伸到 400px。js
获取 canvas
的宽高,此时返回的是 canvas
的默认值。最后出现的效果如上图所示。
线条的默认宽度是 1px
,默认颜色是黑色。
但由于默认情况下 canvas
会将线条的中心点和像素的底部对齐,所以会导致显示效果是 2px
和非纯黑色问题。
暂时只有 IE 9
以上才支持 canvas
。但好消息是 IE
已经有自己的墓碑了。
如需兼容 IE 7 和 8
,可以使用 ExplorerCanvas[3] 。但即使是使用了 ExplorerCanvas
仍然会有所限制,比如无法使用 fillText()
方法等。
在绘制基础图形之前,需要先搞清除 Canvas
使用的坐标系。
Canvas
使用的是 W3C 坐标系 ,也就是遵循我们屏幕、报纸的阅读习惯,从上往下,从左往右。
04.jpg
W3C 坐标系 和 数学直角坐标系 的 X轴
是一样的,只是 Y轴
的反向相反。
W3C 坐标系 的 Y轴
正方向向下。
最简单的起步方式是画一条直线。这里所说的 “直线” 是几何学里的 “线段” 的意思。
需要用到这3个方法:
moveTo(x1, y1)
:起点坐标 (x, y)lineTo(x2, y2)
:下一个点的坐标 (x, y)stroke()
:将所有坐标用一条线连起来起步阶段可以先这样理解。
05.png
<canvas id="c" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 绘制直线
cxt.moveTo(50, 100) // 起点坐标
cxt.lineTo(200, 50) // 下一个点的坐标
cxt.stroke() // 将上面的坐标用一条线连接起来
</script>
复制代码
上面的代码所呈现的效果,可以看下图解释(手不太聪明,画得不是很标准,希望能看懂)
06.jpg
如需画多条直线,可以用会上面那几个方法。
07.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.moveTo(20, 100)
cxt.lineTo(200, 100)
cxt.stroke()
cxt.moveTo(20, 120.5)
cxt.lineTo(200, 120.5)
cxt.stroke()
</script>
复制代码
仔细观察一下,为什么两条线的粗细不一样的?
明明使用的方法都是一样的,只是第二条直线的 Y轴
的值是有小数点。
答:默认情况下 canvas
会将线条的中心点和像素的底部对齐,所以会导致显示效果是 2px
和非纯黑色问题。
08.jpg
上图每个格子代表 1px
。
线的中心点会和画布像素点的底部对齐,所以会线中间是黑色的,但由于一个像素就不能再切割了,所以会有半个像素被染色,就变成了浅灰色。
所以如果你设置的 Y轴
值是一个整数,就会出现上面那种情况。
lineWidth
:线的粗细strokeStyle
:线的颜色lineCap
:线帽:默认: butt
; 圆形: round
; 方形: square
09.png
<canvas id="c" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 绘制直线
cxt.moveTo(50, 50)
cxt.lineTo(200, 50)
// 修改直线的宽度
cxt.lineWidth = 20
// 修改直线的颜色
cxt.strokeStyle = 'pink'
// 修改直线两端样式
cxt.lineCap = 'round' // 默认: butt; 圆形: round; 方形: square
cxt.stroke()
</script>
复制代码
开辟新路径的方法:
beginPath()
在绘制多条线段的同时,还要设置线段样式,通常需要开辟新路径。
要不然样式之间会相互污染。
比如这样
10.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 第一条线
cxt.moveTo(20, 100)
cxt.lineTo(200, 100)
cxt.lineWidth = 10
cxt.strokeStyle = 'pink'
cxt.stroke()
// 第二条线
cxt.moveTo(20, 120.5)
cxt.lineTo(200, 120.5)
cxt.stroke()
</script>
复制代码
如果不想相互污染,需要做2件事:
beginPath()
方法,重新开一个路径如果上面2步却了其中1步都会有影响。
beginPath()
11.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 第一条线
cxt.moveTo(20, 100)
cxt.lineTo(200, 100)
cxt.lineWidth = 10
cxt.strokeStyle = 'pink'
cxt.stroke()
// 第二条线
cxt.beginPath() // 重新开启一个路径
cxt.moveTo(20, 120.5)
cxt.lineTo(200, 120.5)
cxt.stroke()
</script>
复制代码
第一条线的样式会影响之后的线。
但如果使用了 beginPath()
,后面的线段不会影响前面的线段。
12.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 第一条线
cxt.moveTo(20, 100)
cxt.lineTo(200, 100)
cxt.stroke()
// 第二条线
cxt.beginPath() // 重新开启一个路径
cxt.moveTo(20, 120.5)
cxt.lineTo(200, 120.5)
cxt.lineWidth = 4
cxt.strokeStyle = 'red'
cxt.stroke()
</script>
复制代码
beginPath()
的情况这个情况会反过来,后面的线能影响前面的线。
13.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 第一条线
cxt.moveTo(20, 100)
cxt.lineTo(200, 100)
cxt.lineWidth = 10
cxt.strokeStyle = 'pink'
cxt.stroke()
// 第二条线
cxt.moveTo(20, 120.5)
cxt.lineTo(200, 120.5)
cxt.lineWidth = 4
cxt.strokeStyle = 'red'
cxt.stroke()
</script>
复制代码
在设置 beginPath()
的同时,也各自设置样式。这样就能做到相互不影响了。
14.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.moveTo(20, 100)
cxt.lineTo(200, 100)
cxt.lineWidth = 10
cxt.strokeStyle = 'pink'
cxt.stroke()
cxt.beginPath() // 重新开启一个路径
cxt.moveTo(20, 120.5)
cxt.lineTo(200, 120.5)
cxt.lineWidth = 4
cxt.strokeStyle = 'red'
cxt.stroke()
</script>
复制代码
和 直线 差不多,都是使用 moveTo()
、lineTo()
和 stroke()
方法可以绘制折线。
15.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.moveTo(50, 200)
cxt.lineTo(100, 50)
cxt.lineTo(200, 200)
cxt.lineTo(250, 50)
cxt.stroke()
</script>
复制代码
画这种折线,最好在草稿纸上画一个坐标系,自己计算并描绘一下每个点大概在什么什么位置,最后在 canvas
中看看效果。
根据前面的基础,我们可以 使用线段来描绘矩形,但 canvas
也提供了 rect()
等方法可以直接生成矩形。
可以使用前面画线段的方法来绘制矩形
16.png
canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 绘制矩形
cxt.moveTo(50, 50)
cxt.lineTo(200, 50)
cxt.lineTo(200, 120)
cxt.lineTo(50, 120)
cxt.lineTo(50, 50) // 需要闭合,又或者使用 closePath() 方法进行闭合,推荐使用 closePath()
cxt.stroke()
</script>
复制代码
上面的代码几个点分别对应下图。
17.jpg
strokeRect()
描边矩形strokeStyle
:设置描边的属性(颜色、渐变、图案)strokeRect(x, y, width, height)
:描边矩形(x和y是矩形左上角起点;width 和 height 是矩形的宽高)strokeStyle
必须写在 strokeRect()
前面,不然样式不生效。18.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// strokeStyle 属性
// strokeRect(x, y, width, height) 方法
cxt.strokeStyle = 'pink'
cxt.strokeRect(50, 50, 200, 100)
</script>
复制代码
上面的代码可以这样理解
19.jpg
fillRect()
填充矩形fillRect()
和 strokeRect()
方法差不多,但 fillRect()
的作用是填充。
需要注意的是,fillStyle
必须写在 fillRect()
之前,不然样式不生效。
20.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// fillStyle 属性
// fillRect(x, y, width, height) 方法
cxt.fillStyle = 'pink'
cxt.fillRect(50, 50, 200, 100) // fillRect(x, y, width, height)
</script>
复制代码
strokeRect()
和 fillRect()
同时使用 strokeRect()
和 fillRect()
会产生描边和填充的效果
21.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.strokeStyle = 'red'
cxt.strokeRect(50, 50, 200, 100) // strokeRect(x, y, width, height)
cxt.fillStyle = 'yellow'
cxt.fillRect(50, 50, 200, 100) // fillRect(x, y, width, height)
</script>
复制代码
rect()
生成矩形rect()
和 fillRect() 、strokeRect()
的用法差不多,唯一的区别是:
strokeRect()
和 fillRect()
这两个方法调用后会立即绘制;rect()
方法被调用后,不会立刻绘制矩形,而是需要调用 stroke()
或 fill()
辅助渲染。
22.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.strokeStyle = 'red'
cxt.fillStyle = 'pink'
cxt.rect(50, 50, 200, 100) // rect(x, y, width, height)
cxt.stroke()
cxt.fill()
</script>
复制代码
等价公式:
cxt.strokeStyle = 'red',
cxt.rect(50, 50, 200, 100)
cxt.stroke()
// 等价于
cxt.strokeStyle = 'red'
cxt.strokerect(50, 50, 200, 100)
// -----------------------------
cxt.fillStyle = 'hotpink'
cxt.rect(50, 50, 200, 100)
cxt.fill()
// 等价于
cxt.fillStyle = 'yellowgreen'
cxt.fillRect(50, 50, 200, 100)
复制代码
clearRect()
清空矩形使用 clearRect()
方法可以清空指定区域。
clearRect(x, y, width, height)
复制代码
其语法和创建 cxt.rect()
差不多。
23.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.fillStyle = 'pink' // 设置填充颜色
cxt.fillRect(50, 50, 200, 200) // 填充矩形
cxt.clearRect(60, 60, 180, 90) // 清空矩形
</script>
复制代码
canvas
画布元素是矩形,所以可以通过下面的代码把整个画布清空掉。
// 省略部分代码
cxt.clearRect(0, 0, cnv.width, cnv.height)
复制代码
要清空的区域:从画布左上角开始,直到画布的宽和画布的高为止。
Canvas
要画多边形,需要使用 moveTo()
、 lineTo()
和 closePath()
。
虽然三角形是常见图形,但 canvas
并没有提供类似 rect()
的方法来绘制三角形。
需要确定三角形3个点的坐标位置,然后使用 stroke()
或者 fill()
方法生成三角形。
24.png
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.moveTo(50, 50)
cxt.lineTo(200, 50)
cxt.lineTo(200, 200)
// 注意点:如果使用 lineTo 闭合图形,是不能很好闭合拐角位的。
cxt.lineTo(50, 50) // 闭合
cxt.stroke()
</script>
复制代码
注意,默认情况下不会自动从最后一个点连接到起点。最后一步需要设置一下 cxt.lineTo(50, 50)
,让它与 cxt.moveTo(50, 50)
一样。这样可以让路径回到起点,形成一个闭合效果。
但这样做其实是有点问题的,而且也比较麻烦,要记住起始点坐标。
上面的闭合操作,如果遇到设置了 lineWidth
或者 lineJoin
就会有问题,比如:
25.png
// 省略部分代码
cxt.lineWidth = 20
复制代码
当线段变粗后,起始点和结束点的链接处,拐角就出现“不正常”现象。
如果需要真正闭合,可以使用 closePath()
方法。
26.png
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">id=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"c" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">width=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">height=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">style=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"border: 1px solid #ccc;"></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cnv = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(193, 132, 1);line-height: 26px;">document.getElementById(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'c')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cxt = cnv.getContext(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'2d')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.moveTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(160, 161, 167);font-style: italic;line-height: 26px;">// 手动闭合<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.closePath()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineJoin = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'miter' <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(160, 161, 167);font-style: italic;line-height: 26px;">// 线条连接的样式。miter: 默认; bevel: 斜面; round: 圆角<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineWidth = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">20<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.stroke()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>
使用 `cxt.closePath()` 可以自动将终点和起始点连接起来,此时看上去就正常多了。
### 菱形
有一组邻边相等的平行四边形是菱形
![](https://oss-cn-hangzhou.aliyuncs.com/codingsky/cdn/img/2022-08-04/1ad6e769a674d23ac7947e64ce70d869)
27.png```
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">id=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"c" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">width=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">height=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">style=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"border: 1px solid #ccc;"></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cnv = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(193, 132, 1);line-height: 26px;">document.getElementById(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'c')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cxt = cnv.getContext(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'2d')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.moveTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">150, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">250, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">100)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">150, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">150)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">100)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.closePath()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.stroke()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>
要绘制直线类型的图形,在草稿纸上标记出起始点和每个拐角的点,然后再连线即可。相对曲线图形来说,直线图形是比较容易的。
圆形
--
绘制圆形的方法是 `arc()`。
**语法:**
``` arc(x, y, r, sAngle, eAngle,counterclockwise)
复制代码
``` ```
x
和 y
: 圆心坐标r
: 半径sAngle
: 开始角度eAngle
: 结束角度counterclockwise
: 绘制方向(true: 逆时针; false: 顺时针),默认 false
28.jpg开始角度和结束角度,都是以弧度为单位。例如 180°就写成 Math.PI
,360°写成 Math.PI * 2
,以此类推。
在实际开发中,为了让自己或者别的开发者更容易看懂弧度的数值,1°应该写成 Math.PI / 180
。
100 * Math.PI / 180
110 * Math.PI / 180
241 * Math.PI / 180
注意:绘制圆形之前,必须先调用 beginPath()
方法!!!在绘制完成之后,还需要调用 closePath()
方法!!!
29.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.beginPath()
cxt.arc(150, 150, 80, 0, 360 * Math.PI / 180)
cxt.closePath()
cxt.stroke()
script>
复制代码
```
```
半圆
如果使用 arc()
方法画圆时,没做到刚好绕完一周(360°)就直接闭合路径,就会出现半圆的状态。
30.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.beginPath()
cxt.arc(150, 150, 100, 0, 180 * Math.PI / 180) // 顺时针
cxt.closePath()
cxt.stroke()
script>
复制代码
```
```
上面的代码中,cxt.arc
最后一个参数没传,默认是 false
,所以是顺时针绘制。
31.jpg如果希望半圆的弧面在上方,可以将 cxt.arc
最后一个参数设置成 true
32.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.beginPath()
cxt.arc(150, 150, 100, 0, 180 * Math.PI / 180, true)
cxt.closePath()
cxt.stroke()
script>
复制代码
```
```
弧线
使用 arc()
方法画半圆时,如果最后不调用 closePath()
方法,就不会出现闭合路径。也就是说,那是一条弧线。
在 canvas
中,画弧线有2中方法:arc()
和 arcTo()
。
arc() 画弧线
如果想画一条 0° ~ 30°
的弧线,可以这样写
33.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.beginPath()
cxt.arc(150, 150, 100, 0, 30 * Math.PI / 180)
cxt.stroke()
script>
复制代码
```
```
原理如下图所示,红线代表画出来的那条弧线。
34.jpg
arcTo() 画弧线
arcTo()
的使用方法会更加复杂,如果初学看不太懂的话可以先跳过,看完后面的再回来补补。
语法:
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
arcTo(cx, cy, x2, y2, radius)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码
- `cx`: 两切线交点的横坐标
- `cy`: 两切线交点的纵坐标
- `x2`: 结束点的横坐标
- `y2`: 结束点的纵坐标
- `radius`: 半径
其中,`(cx, cy)` 也叫控制点,`(x2, y2)` 也叫结束点。
是不是有点奇怪,为什么没有 `x1` 和 `y1` ?
`(x1, y1)` 是开始点,通常是由 `moveTo()` 或者 `lineTo()` 提供。
`arcTo()` 方法利用 **开始点、控制点和结束点形成的夹角,绘制一段与夹角的两边相切并且半径为 `radius` 的圆弧**。
![](https://oss-cn-hangzhou.aliyuncs.com/codingsky/cdn/img/2022-08-04/519ae940dbfd3db437a271f73cb413f9)
35.jpg举个例子
![](https://oss-cn-hangzhou.aliyuncs.com/codingsky/cdn/img/2022-08-04/bec65dbd5581b07a3449f41714a17ad7)
36.png```
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">id=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"c" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">width=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">height=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">style=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"border: 1px solid #ccc;"></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cnv = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(193, 132, 1);line-height: 26px;">document.getElementById(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'c')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cxt = cnv.getContext(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'2d')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.moveTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">40, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">40)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.arcTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">120, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">40, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">120, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">120, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">80)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.stroke()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>
基础样式
====
前面学完基础图形,接下来可以开始了解一下如何设置元素的基础样式。
描边 stroke()
-----------
前面的案例中,其实已经知道使用 `stroke()` 方法进行描边了。这里就不再多讲这个方法。
线条宽度 lineWidth
--------------
`lineWidth` 默认值是 `1` ,默认单位是 `px`。
**语法:**
```
lineWidth = 线宽
复制代码
```
```
37.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 线宽 10
cxt.beginPath()
cxt.moveTo(50, 50)
cxt.lineTo(250, 50)
cxt.lineWidth = 10 // 设置线宽
cxt.stroke()
// 线宽 20
cxt.beginPath()
cxt.moveTo(50, 150)
cxt.lineTo(250, 150)
cxt.lineWidth = 20 // 设置线宽
cxt.stroke()
// 线宽 30
cxt.beginPath()
cxt.moveTo(50, 250)
cxt.lineTo(250, 250)
cxt.lineWidth = 30 // 设置线宽
cxt.stroke()
script>
复制代码
```
```
线条颜色 strokeStyle
使用 strokeStyle
可以设置线条颜色
语法:
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
strokeStyle = 颜色值<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>
![](https://oss-cn-hangzhou.aliyuncs.com/codingsky/cdn/img/2022-08-04/f301508a0a6d337f1bfc88d04c7aaa1d)
38.png```
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">id=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"c" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">width=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">height=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">style=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"border: 1px solid #ccc;"></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cnv = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(193, 132, 1);line-height: 26px;">document.getElementById(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'c')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cxt = cnv.getContext(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'2d')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.moveTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">250, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineWidth = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">20<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.strokeStyle = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'pink' <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(160, 161, 167);font-style: italic;line-height: 26px;">// 设置颜色<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.stroke()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>
为了展示方便,我将 `lineWidth` 设为 20。
线帽 lineCap
----------
线帽指的是线段的开始和结尾处的样式,使用 `lineCap` 可以设置
**语法:**
```
lineCap = '属性值'
复制代码
```
```
属性值包括:
butt
: 默认值,无线帽
square
: 方形线帽
round
: 圆形线帽
39.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
// 设置线宽,方便演示
cxt.lineWidth = 16
// 默认线帽 butt
cxt.beginPath()
cxt.moveTo(50, 60)
cxt.lineTo(250, 60)
cxt.stroke()
// 方形线帽 square
cxt.beginPath()
cxt.lineCap = 'square'
cxt.moveTo(50, 150)
cxt.lineTo(250, 150)
cxt.stroke()
// 圆形线帽 round
cxt.beginPath()
cxt.lineCap = 'round'
cxt.moveTo(50, 250)
cxt.lineTo(250, 250)
cxt.stroke()
script>
复制代码
```
```
使用 square
和 round
的话,会使线条变得稍微长一点点,这是给线条增加线帽的部分,这个长度在日常开发中需要注意。
线帽只对线条的开始和结尾处产生作用,对拐角不会产生任何作用。
拐角样式 lineJoin
如果需要设置拐角样式,可以使用 lineJoin
。
语法:
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
lineJoin = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'属性值'<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>
属性值包括:
- `miter`: 默认值,尖角
- `round`: 圆角
- `bevel`: 斜角
![](https://oss-cn-hangzhou.aliyuncs.com/codingsky/cdn/img/2022-08-04/8f170f8243b68c1b2904ac29cfab38db)
40.png```
<pre data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(0, 0, 0);font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;">```
<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">id=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"c" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">width=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">height=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"300" <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">style=<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">"border: 1px solid #ccc;"></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">canvas><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;"><<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cnv = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(193, 132, 1);line-height: 26px;">document.getElementById(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'c')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(166, 38, 164);line-height: 26px;">const cxt = cnv.getContext(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'2d')<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineWidth = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">20<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(160, 161, 167);font-style: italic;line-height: 26px;">// 默认,尖角<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.moveTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">40)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">40)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">90)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.stroke()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(160, 161, 167);font-style: italic;line-height: 26px;">// 斜角 bevel<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.beginPath()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.moveTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">140)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">140)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">190)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineJoin = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'bevel'<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.stroke()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(160, 161, 167);font-style: italic;line-height: 26px;">// 圆角 round<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.beginPath()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.moveTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">50, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">240)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">240)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineTo(<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">200, <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(152, 104, 1);line-height: 26px;">290)<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.lineJoin = <span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(80, 161, 79);line-height: 26px;">'round'<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br> cxt.stroke()<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br></<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(228, 86, 73);line-height: 26px;">script><br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>复制代码<br style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></br>
虚线 setLineDash()
----------------
使用 `setLineDash()` 方法可以将描边设置成虚线。
**语法:**
```
setLineDash([])
复制代码
```
```
需要传入一个数组,且元素是数值型。
虚线分3种情况
- 只传1个值
- 有2个值
- 有3个以上的值
41.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>
<script>
const cnv = document.getElementById('c')
const cxt = cnv.getContext('2d')
cxt.lineWidth = 20
cxt.strokeStyle = 'pink'
cxt.moveTo(50, 50)
cxt.lineTo(200, 50)
cxt.setLineDash([10]) // 只传1个参数,实线与空白都是 10px
cxt.stroke()
cxt.beginPath()
cxt.moveTo(50, 100)
cxt.lineTo(200, 100)
cxt.setLineDash([10, 20]) // 2个参数,此时,实线是 10px, 空白 20px
cxt.stroke()
cxt.beginPath()
cxt.moveTo(50, 150)
cxt.lineTo(200, 150)
cxt.setLineDash([10, 20, 5]) // 传3个以上的参数,此例:10px实线,20px空白,5px实线,10px空白,20px实线,5px空白 ……
cxt.stroke()
script>
复制代码
```
```
此外,还可以始终 cxt.getLineDash()
获取虚线不重复的距离;
用 cxt.lineDashOffset
设置虚线的偏移位。
填充
使用 fill()
可以填充图形,根据前面的例子应该掌握了如何使用 fill()
42.png```
```
<canvas id="c" width="300" height="300" style="border: 1px solid #ccc;">canvas>