Canvas
# 什么是canvas
在 MDN 中是这样定义 <canvas> 的:
<canvas> 是 HTML5 新增的元素,可用于通过使用 JavaScript 中的脚本来绘制图形。例如,它可以用于绘制图形、制作照片、创建动画,甚至可以进行实时视频处理或渲染。
# svg 和 Canvas 的区别
我们先来看看MND怎么定义svg
svg(Scalable Vector Graphics,可缩放矢量图形)是基于 XML(可扩展标记语言,标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式。它由 W3C(万维网联盟)制定,是一个开放标准。
这样对比就很明显了svg 是一种使用 XML 描述 2D 图形的语言svg中通过创建n个dom通过css和js来控制dom,来实现图形的渲染,而且每次操作dom系统会自动进行 DOM 重绘,所以会造成性能损耗。
Canvas 通过 JavaScript 来绘制 2D 图形 Canvas知道单纯的一个html标签,所有的一些列渲染操作都是通过js在画布里面操作。在 Canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。
# Canvas 的应用场景
1.绘制图表
常见的如 ECharts、antv-x6等都是用canvas来做的
2.小游戏
如你画我猜,赛车,俄罗斯方块等
3.活动页面
如h5活动页面中的抽奖,刮刮乐,
4.炫酷特效
特效就很多了,在页面中一些很炫酷的视觉差,动态效果都可以很轻易的使用canvas来实现
# 使用事项
- 如果不设置宽高默认就是 300 * 150
- 使用 CSS 来设置宽高的话,画布就会按照 300 * 150 的比例进行缩放,也就是将 300 * 150 的页面显示在 400 * 400 的容器中,所以尽量使用js或者在html在设置宽高。
# 上下文类型(contextType)
通常在创建好一个 Canvas 标签的时候,我们要做的第一步就是要先获取到这个 Canvas 的上下文对象
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
2
- 2d(本小册所有的示例都是 2d 的):代表一个二维渲染上下文
- webgl(或"experimental-webgl"):代表一个三维渲染上下文
- webgl2(或"experimental-webgl2"):代表一个三维渲染上下文;这种情况下只能在浏览器中实现 WebGL 版本2 (OpenGL ES 3.0)。
# 绘制路径
方法 | 描述 |
---|---|
fill() | 填充路径 |
stroke() | 描边 |
arc() | 创建圆弧 |
rect() | 创建矩形 |
fillRect() | 绘制矩形路径区域 |
strokeRect() | 绘制矩形路径描边 |
clearRect() | 在给定的矩形内清除指定的像素 |
arcTo() | 创建两切线之间的弧/曲线 |
beginPath() | 起始一条路径,或重置当前路径 |
moveTo() | 把路径移动到画布中的指定点,不创建线条 |
lineTo() | 添加一个新点,然后在画布中创建从该点到最后指定点的线条 |
closePath() | 创建从当前点回到起始点的路径 |
clip() | 从原始画布剪切任意形状和尺寸的区域 |
quadraticCurveTo() | 创建二次方贝塞尔曲线 |
bezierCurveTo() | 创建三次方贝塞尔曲线 |
isPointInPath() | 如果指定的点位于当前路径中,则返回 true,否则返回 false |
# 绘制弧/曲线
arc()
方法创建弧/曲线(用于创建圆或部分圆)。
context.arc(x,y,r,sAngle,eAngle,counterclockwise);
- x:圆心的 x 坐标
- y:圆心的 y 坐标
- r:圆的半径
- sAngle:起始角,以弧度计(弧的圆形的三点钟位置是 0 度)
- eAngle:结束角,以弧度计
- counterclockwise:可选。规定应该逆时针还是顺时针绘图。false 为顺时针,true 为逆时针
如果需要画一个半圆可以:
context.beginPath();
context.arc(120, 100,100, 0, Math.PI*1, false);
context.strokeStyle = 'rgb(255,255,255)';
context.stroke();
2
3
4
# 绘制直线
- moveTo(x,y):把路径移动到画布中的指定点,不创建线条
- lineTo(x,y):添加一个新点,然后在画布中创建从该点到最后指定点的线条
# 需要注意的是
- 如果没有 moveTo,那么第一次 lineTo 的就视为 moveTo
- 每次 lineTo 后如果没有 moveTo,那么下次 lineTo 的开始点为前一次 lineTo 的结束点。
# 给直线添加样式
方法 | 描述 |
---|---|
lineCap | 设置或返回线条的结束端点样式 |
lineJoin | 设置或返回两条线相交时,所创建的拐角类型 |
lineWidth | 设置或返回当前的线条宽度 |
miterLimit | 设置或返回最大斜接长度 |
# 颜色、样式和阴影
方法 | 描述 |
---|---|
fillStyle | 设置或返回用于填充绘画的颜色、渐变或模式 |
strokeStyle | 设置或返回用于笔触的颜色、渐变或模式 |
shadowColor | 设置或返回用于阴影的颜色 |
shadowBlur | 设置或返回用于阴影的模糊级别 |
shadowOffsetX | 设置或返回阴影距形状的水平距离 |
shadowOffsetY | 设置或返回阴影距形状的垂直距离 |
# 设置渐变
方法 | 描述 |
---|---|
createLinearGradient(x0, y0, x1, y1) | 创建线性渐变(用在画布内容上) |
createPattern(image, repetition) | 在指定的方向上重复指定的元素 |
createRadialGradient(x0, y0, r0, x1, y1, r1) | 创建放射状/环形的渐变(用在画布内容上) |
addColorStop(offset, color) | 规定渐变对象中的颜色和停止位置 |
# 图形转换
方法 | 描述 |
---|---|
scale() | 缩放当前绘图至更大或更小 |
rotate(angle) | 旋转当前绘图 |
translate() | 重新映射画布上的 (0,0) 位置 |
transform() | 替换绘图的当前转换矩阵 |
setTransform() | 将当前转换重置为单位矩阵,然后运行 transform() |
需要注意的是rotate的传参angle旋转角度,以弧度计。 如需将角度转换为弧度,请使用 degreesMath.PI/180 公式进行计算。 举例:如需旋转 5 度,可规定下面的公式:5Math.PI/180。
# 图像绘制
方法 | 描述 |
---|---|
drawImage() | 向画布上绘制图像、画布或视频 |
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
- img:规定要使用的图像、画布或视频
- sx:可选。开始剪切的 x 坐标位置
- sy:可选。开始剪切的 y 坐标位置
- swidth:可选。被剪切图像的宽度
- sheight:可选。被剪切图像的高度
- x:在画布上放置图像的 x 坐标位置
- y:在画布上放置图像的 y 坐标位置
- width:可选。要使用的图像的宽度(伸展或缩小图像)
- height:可选。要使用的图像的高度(伸展或缩小图像)