关于canvas
canvas对于大部分前端开发人员来说,可以用一个词来形容--既熟悉又陌生。为什么这样说,因为大部分前端开发人员在写业务代码的时候用到canvas的概率很小,就算用到了,也只是类似drawImage
这个API,并且,对drawImage
这个API的了解也并不深刻,只知道它可以将图片绘制到画布上,其他的功能大部分人应该都不知道。
其实drawImage
这个API除了能将图片绘制到画布上,也可以对绘制到画布上的图片进行缩放。代码如下:
ctx.drawImage(img, x, y, img.naturalWidth, img.naturalHeight, 0, 0, canvasHeight * (scaleRate / 100), canvasWidth * (scaleRate / 100))
最后两个参数是对绘制到画布上的图片设置缩放后的宽高。详细的解释可以查MDN。
canvas具体有哪些功能
上面的drawImage
只是个引子。如果你对canvas研究的比较深刻,那么你会发现,和浏览器其他的API相比,如果想要开发一个产品,其他的API可能需要很多组合在一起才能开发出来一套产品。canvas不同,canvas的API本身就是一套成熟的产品。
我们具体来看它都具有哪些功能:
绘制矩形
fillRect(x, y, width, height)
绘制一个填充的矩形strokeRect(x, y, width, height)
绘制一个矩形的边框clearRect(x, y, width, height)
清除指定矩形区域,让清除部分完全透明。
绘制路径
- 首先,你需要创建路径起始点。
- 然后你使用画图命令去画出路径。
- 之后你把路径封闭。
- 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。
beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。closePath()
闭合路径之后图形绘制命令又重新指向到上下文中。stroke()
通过线条来绘制图形轮廓。fill()
通过填充路径的内容区域生成实心的图形。
移动笔触
和绘制直线
- moveTo() 移动笔尖的位置
- lineTo() 绘制直线
绘制圆弧
arc(x,y,radius,startAngle,endAngle,anticlockwise)
画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
arcTo(x1, y1, x2, y2, radius)
根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。
二次贝塞尔曲线及三次贝塞尔曲线
如果你不了解贝塞尔曲线,那么如果你使用过photeshop,photoshop的钢笔工具绘制的实际上就是贝塞尔曲线,有两个定点和一个控制点,或者多个控制点。
如果photoshop的钢笔工具也不知道,那么就找时间科普一下吧
- quadraticCurveTo(cp1x, cp1y, x, y)
绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
- bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
颜色和样式
fillStyle
可以给绘制的内容填充颜色,比如:
const draw =() => {
let ctx = document.getElementById('canvas').getContext('2d');
for(let i=0;i<6;i ){
for(let j=0;j<6;j ){
ctx.fillStyle = `rgb(${Math.floor(255-42.5*i)},${Math.floor(255-42.5*j)},0)`
ctx.fillRect(j*25,i*25,25,25)
}
}
}
这段代码会绘制一个类似取色板的东西。
线型
设置线条的各种样式
- lineWidth = value
- lineCap =
butt|round|square
线条末端样式 - lineJoin =
round|bevel|miter
线条间结合处样式 - miterLimit = value 两条线相交时交接处最大长度
- getLineDash 当前虚线样式
- setLineDash 设置当前虚线样式
图案样式
createPattern()
绘制图片的各种纹理,类似photoshop中的填充功能,我是这么理解的。
阴影
设置阴影样式
shadowOffsetX = float
shadowOffsetY = float
shadowBlur = float
shadowColor = color
绘制文本
fillText(text,x,y,[maxwidth])
填充(实体的文字)strokeText(text,x,y,[maxwidth])
描边(镂空的文字)
文本样式
font = value
textAlign = start|end|left|right|center
textBaseLine = ltr|rtl|inherit
测量文本宽度
measureText(value)
获取更多文本细节
使用图像
功能:动态图像合成,或作为图形的背景。使用drawImage()方法将图片绘制到画布上。
scale(x,y)
缩放:增减图像在canvas中的像素数目slice(x,y)
切片
canvas状态保存和恢复
save()
保存画布所有状态restore()
恢复画布状态translate(x,y)
移动画布rotating(angle)
旋转scale(x,y)
缩放:增减图像在canvas中的像素数目transform(a,b,c,d,e,f)
对变形矩阵直接修改
组合
组合是将两个图像或选区组合在一起
globalCompositeOperation
可以修改绘制顺序clip
可以隐藏不需要的部分
基本动画流程
- 清空canvas
- 保存canvas状态
- 绘制图型
- 恢复canvas状态
总结
以上只是关于canvas相关的API的一些梳理,当然还有很多没有提到的api,利用这些API可以实现很多关于图像处理的内容,比如:蚂蚁线
,图像滤镜
,图像渐变
...等等
后面我将会结合一个具体的项目来梳理相关的知识点,并将开发期间遇到的问题一一分享出来...
上图是已经在开发中的内容,canvas中的图片已经实现了缩放,接下来可能是移动,新建图层...