canvas 绘图
1. 前端中可用的绘画技术
canvas
: 专用于绘制2D
图形 / 图像SVG
: 专用于绘制矢量图WebGL
: 目前不是HTML5
标准技术, 功能强大,3D
图像 / 图形
2. 定义与语法
H5
新增的canvas
元素用于在网页中实现任意的绘图操作;canvas
默认是一个 300 * 150 的inline-block
- 每个
canvas
元素上有且只有一根 "画笔" 对象 -> 绘图上下文对象
<canvas id="canvasTest" width="500" height="400">
你的浏览器不支持 canvas 标签
</canvas>
3. canvas 基本方法
var ctx = canvasTest.getContext('2d')
: 获取画布上画笔对象console.dir(ctx)
: 查看画笔对象的相关属性和方法成员ctx.fillStyle='#f00'
: 填充绘画的颜色, 渐变或模式ctx.strokeStyle='#000'
: 填充笔触( 描边 )的颜色, 渐变或模式ctx.lineWidth = 1
: 描边 / 线条的宽度ctx.font = '10px sans-serif'
: 绘制文本所用字号 / 字体ctx.textBaseline = 'alphabetic'
: 设置文本对齐的基线ctx.shadowOffsetX= 0
: 设置阴影水平偏移量ctx.shadowOffsetY= 0
: 设置阴影垂直偏移量ctx.shadowColor: ' rgba(0, 0, 0, 0)'
: 设置阴影颜色及透明度ctx.shadowBlur: 0
: 设置阴影模糊半径ctx.clearRect(x, y, w, h)
: 清除一个矩形范围内的所有内容
3.1. canvas 的尺寸如何设置
canvas
画布的尺寸若用css
指定, 其实并未修改真正的尺寸, 而是进行"拉伸" ->canvas
尺寸不能用css
指定- 可以使用
HTML
元素的属性 /JS
对象属性来指定
- 可以使用
3.2. canvas 绘图填充渐变 / canvas 绘图笔触( 描边 ) 渐变
<canvas id="canvasTest" width="500" height="400">
你的浏览器不支持 canvas 标签
</canvas>
<script type="text/javascript">
let canvasTest = document.getElementById('canvasTest')
let ctx = canvasTest.getContext('2d')
let g = ctx.createLinearGradient(x1, y1, x2, y2) // 这里是线性渐变, 径向渐变使用 createRadialGradient(x1, y1, r1, x2, y2, r2)
g.addColorStop(offset, color) // offset: 浮点值, 设置颜色的位置(0.0 表示画布的原点位置, 1.0 表示 画布的终点位置) color: 设置渐变颜色
g.addColorStop(offset1, color1) // 径向渐变 和 线性渐变一样
ctx.fillStyle = g // 将渐变用作填充
ctx.strokeStyle = g // 将渐变用作笔触( 描边 )
ctx.fillRect(x, y, w, h) // 用渐变填充矩形
ctx.strokeRect(x, y, w, h) // 用渐变描边一个矩形
</script>
4. 使用 canvas 的画笔绘制矩形
- 矩形定位点在左上角: 左上角的坐标为 0, 0
ctx.fillStyle = '#000'
: 填充颜色ctx.strokeStyle = '#000
: 描边颜色ctx.fillRect(x, y, w, h)
: 填充一个矩形ctx.strokeRect(x, y, w, h)
: 描边一个矩形ctx.clearRect(x, y, w, h)
: 清除一个矩形范围内的所有内容- Ex:
<style> body{ text-align: center; } canvas{ background: #ddd; } </style> <canvas id="canvasTest"> 你的浏览器不支持 canvas 标签 </canvas> <script type="text/javascript"> let canvasTest = document.getElementById('canvasTest') canvasTest.width = 500 canvasTest.height = 400 let ctx = canvasTest.getContext('2d') // 填充一个淡绿色背景 ctx.fillStyle = '#AFA' ctx.fillRect(0, 0, 250, 200) </script>
4.1. canvas 绘图实现动画
-
原理: 使用周期性定时器执行"清除画布内容, 再重新绘制内容"
-
Ex:
<style> body{ text-align: center; } canvas{ background: #ddd; } </style> <canvas id="canvasTest"> 你的浏览器不支持 canvas 标签 </canvas> <script type="text/javascript"> let canvasTest = document.getElementById('canvasTest') canvasTest.width = 500 canvasTest.height = 400 let ctx = canvasTest.getContext('2d') let x = 0 let xDirection = 1 let y = 0 // 定时器: 动画引擎 let canvasAnimation = null clearInterval(canvasAnimation) canvasAnimation = setInterval(function () { // 清除已有内容 ctx.clearRect(0, 0 , 500, 400) // 绘制新的内容 ctx.strokeRect(x, y, 100, 80) x = 10 * xDirection if (x >= 400) { xDirection = -1 } else if (x <= 0) { xDirection = 1 } }, 50) </script>
5. 使用 canvas 画笔绘制文本
canvas
绘制文本的定位点(0, 0) 在文本基线的起点ctx.font = '10px sans-serif'
: 设置文本的大小及字体ctx.textBaseline = 'alphabetic'
: 设置文本基线, 可取值:top
/bottom
/middle
/alphabetic
ctx.fillText(txt, x, y)
: 填充文本ctx.strokeText(txt, x, y)
: 描边文本ctx.measureText(txt).width
: 测量, 根据当前指定的字号和字体计算指定文本宽度- Ex:
<style> body{ text-align: center; } canvas{ background: #ddd; } </style> <canvas id="canvasTest"> 你的浏览器不支持 canvas 标签 </canvas> <script type="text/javascript"> let canvasTest = document.getElementById('canvasTest') canvasTest.width = 500 canvasTest.height = 400 let ctx = canvasTest.getContext('2d') let txt = 'abgyj中国人' ctx.font = '16px SimHei' ctx.textBaseline = 'top' ctx.fillText(txt, 0, 0) ctx.strokeText(txt, 200, 100) console.log(ctx.measureText(txt)) </script>
5.1. 为图形文字添加阴影
-
ctx.shadowColor = '#666'
: 设置阴影的颜色 -
ctx.shadowOffsetX = 8
: 设置阴影水平偏移量 -
ctx.shadowOffsetY = 8
: 设置阴影垂直偏移量 -
ctx.shadowBlur = 10
: 设置阴影模糊半径 -
Ex:
<style> body{ text-align: center; } canvas{ background: #ddd; } </style> <canvas id="canvasTest"> 你的浏览器不支持 canvas 标签 </canvas> <script type="text/javascript"> let canvasTest = document.getElementById('canvasTest') canvasTest.width = 500 canvasTest.height = 400 let ctx = canvasTest.getContext('2d') ctx.textBaseline = 'top' ctx.font = '80px SimHei' let txt = 'lcy' ctx.fillText(txt, 100, 100) ctx.shadowColor = '#666' ctx.shadowOffsetX = 8 ctx.shadowOffsetY = 8 ctx.shadowBlur = 10 ctx.fillText(txt, 100, 200) </script>
6. 使用 canvas 绘制路径
path
: 路径, 类似于Photoshop
中的钢笔工具, 路径本身不可见, 可用于: 描边, 填充, 选区裁剪ctx.beginPath()
: 开始绘制一条新路径ctx.clostPath()
: 闭合路径ctx.moveTo(x, y)
: 移动到某一点ctx.lineTo(x, y)
: 从当前点到指定点绘制直线ctx.arc(cx, cy, r, start, end)
: 绘制圆形 / 圆弧路径ctx.ellipse(cx, cy, rx, ry, start, end)
: 绘制椭圆路径ctx.bezierCurveTo()
: 绘制贝塞尔曲线路径ctx.stroke()
: 使用当前路径描边ctx.fill()
: 使用当前路径进行填充ctx.clip()
: 使用当前路径进行裁剪- Ex:
<style> body{ text-align: center; } canvas{ background: #ddd; } </style> <canvas id="canvasTest"> 你的浏览器不支持 canvas 标签 </canvas> <script type="text/javascript"> let canvasTest = document.getElementById('canvasTest') canvasTest.width = 500 canvasTest.height = 400 let ctx = canvasTest.getContext('2d') // 绘制灰色的背景圆环 ctx.beginPath() ctx.arc(250, 200, 100, 0, 2*Math.PI) ctx.lineWidth = 20 ctx.strokeStyle = '#AAA' ctx.stroke() // 绘制圆形的进度条 let start = -90 let end = -90 let timer = setInterval(function () { ctx.beginPath() ctx.arc(250, 200, 100, start * Math.PI / 180, end * Math.PI / 180) ctx.strokeStyle = '#0A0' ctx.stroke() end = 3 if (end > 270) { clearInterval(timer) } }, 50) </script>
7. 使用 canvas 绘制图像
- 绘制图像时, 客户端必须等待图片异步加载完成
<canvas id="canvasTest" width="500" height="400">
您的浏览器不支持 canvas
</canvas>
<script type="text/javascript">
let canvasTest = document.getElementById('canvasTest')
let ctx = canvasTest.getContext('2d')
let img = new Image()
img.src = 'xxx.png' // 客户端会自动异步下载此图片
console.log(img.width) // 0
// 图片加载完成事件
img.onload = function () {
console.log(img.width) // 有值
ctx.drawImage(img, x, y) // 原尺寸绘图
ctx.drawImage(img, x, y, w, h) // 缩放绘图
}
</script>
8. 使用 canvas 绘制变形后的图形 / 图像
CSS
中有变形的属性:transform: rotate / translate / scale / skew
, 这些变形属性只能用于特定的HTML DOM
元素canvas
绘图只有一个元素:<canvas></canvas>
, 若想仅仅让其中的某个图形 / 图像变形, 不能使用css
变形属性
8.1. 绘图上下文提供了专用的变形方法
-
ctx.rotate(旋转的弧度)
: 让画笔旋转指定的弧度- 画笔的旋转轴为画笔的坐标原点
- 画笔的旋转具有累加效果
- 若想让绘图内容绕着其他点旋转, 必须平移画布的坐标原点
-
ctx.translate(x, y)
: 平移画笔的坐标原点-
注意: 画笔原点平移, 其上所有点的坐标值都发生了变化
-
-
ctx.scale()
: 画笔缩放 -
ctx.save()
: 保存当前画笔的变形状态 -
ctx.restore()
: 恢复画笔变形状态到最近一次保存的值 -
Ex: 绘制绕自己为中心旋转的小飞机
<style> body{ text-align: center; } canvas{ background: #ddd; } </style> <canvas id="canvasTest"> 你的浏览器不支持 canvas 标签 </canvas> <script type="text/javascript"> let canvasTest = document.getElementById('canvasTest') canvasTest.width = 500 canvasTest.height = 400 let ctx = canvasTest.getContext('2d') let img = new Image() img.src = 'img/fly.png' img.onload = function () { let degOne = 0 // 飞机1 旋转的角度 let degThree = 0 // 飞机3 旋转的角度 setInterval(function () { // 绘制飞机1 ctx.sava() // 保存画笔当前的变形状态 // 平移 -> 选装 -> 绘图 -> 逆向选装 -> 逆向平移 ctx.translate(img.width / 2, img.height / 2) ctx.rotate(degOne * Math.PI / 180) ctx.drawImage(img, -img.width / 2, -img.height / 2) ctx.restore() // 恢复画笔最近的变形状态 degOne = 5 // 绘制飞机2 ctx.drawImage(img, 500 - img.width, 0) // 绘制飞机3 // 平移 -> 选装 -> 绘图 -> 逆向选装 -> 逆向平移 ctx.translate(img.width / 2, img.height / 2) ctx.rotate(degThree * Math.PI / 180) ctx.drawImage(img, -img.width / 2, -img.height / 2) ctx.rotate(-degThree * Math.PI / 180) ctx.translate(-img.width / 2, -(400 - img.height / 2)) degThree = 10 }, 20) } </script>
-
Ex: 绘制验证码
<style> body{ text-align: center; } canvas{ background: #ddd; } </style> <canvas id="canvasTest"> 你的浏览器不支持 canvas 标签 </canvas> <script type="text/javascript"> let canvasTest = document.getElementById('canvasTest') let cw = 120 let ch = 30 canvasTest.width = cw canvasTest.height = ch let ctx = canvasTest.getContext('2d') /* 1. 绘制背景颜色 -- 填充矩形 */ ctx.fillStyle = randomColor(150, 230) ctx.fillRect(0, 0, cw, ch) /* 2. 循环绘制 4 个随机字符 */ ctx.textBaseline = 'top' let pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789' for (let i = 0; i < 4; i ) { let randomString = pool[randomNum(0, pool.length)] // 随机一个字符 let fontSize = randomNum(10, 40) // 字体大小 ctx.font = `${fontSize}px SimHei` let fontColor = randomNum(50, 150) ctx.strokeStyle = fontColor let deg = randomNum(-40, 45) let x = -fontSize / 2 // 每个字符左上角的坐标 let y = -fontSize / 2 // 绘制一个字符: 保存状态 -> 平移 -> 旋转 -> 绘制 -> 恢复状态 ctx.save() ctx.translate(30 * i 15, 15) ctx.rotate(deg * Math.PI / 180) ctx.strokeText(randomString, x, y) ctx.restore() } /* 3.绘制 5 条干扰线 -- 直线路径 */ for(let i = 0; i < 5; i ) { ctx.beginPath() ctx.moveTo(randomNum(0, cw), randomNum(0, ch)) ctx.lineTo(randomNum(0, cw), randomNum(0, ch)) ctx.strokeStyle = randomColor(0, 255) ctx.stroke() } /* 4.绘制50个杂色点 -- 半径为 0.5 圆形路径 */ for(let i = 0; i < 50; i ) { ctx.beginPath() ctx.arc(randomNum(0, cw), randomNum(0, ch), 0.5, 0, 2 * Math.PI) ctx.strokeStyle = randomColor(0, 255) ctx.fill() } // random number, 返回指定范围内的随机整数 function randomNum(min, max) { return Math.floor(Math.random() * (max - min) min) } // random color, 返回指定范围的随机颜色 function randomColor(min, max) { let r = randomNum(min, max) let g = randomNum(min, max) let b = randomNum(min, max) return `rgb(${r}, ${g}, ${b})` } </script>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhckeikh
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13