开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
Canvas
github地址
优缺点
优点:Canvas用于绘制2D图形 适合图像密集型的游戏开发
只能通过JS来绘图
Canvas是由像素点构成的图形 放大会使图像模糊
Canvas Grid坐标空间
坐标原点可以通过移动、旋转、缩放改变 后续就基于最新的坐标系
canvas元素默认被网格(坐标空间) 覆盖
绘制矩形:
-
矩形方法
- fillRect(x,y,w,h) 绘填充矩形
- strokeRect 绘制一个矩形边框
-
路径方法
概念:路径就是点列表 由线段连接
-
创建路径起始点beginPath()
-
使用绘图命令画出路径
- moveTo 移动画笔
- lineTo 移动到 开始点和之前绘制的路径有关,如果路径没有闭合,之前路径结束点就是接下来的开始点
- arc画圆弧
// 绘制圆 x,y,半径,起始弧度,结束弧度 ctx.arc(30, 30, 20, 0, Math.PI * 2);弧度=(Math.PI/180)*角度 1角度=Math.PI/180个弧度
旋转360°:Math.PI * 2
-
把路径闭合closePath()
-
路径生成后需要通过stoke() 描边或fill() 填充来渲染图像
fill会自动闭合路径
-
绘制圆弧或者圆
色彩Color
填充颜色 fillStyle = color
描边颜色 strokeStyle = color
属于绘图状态 需要在fill stroke函数前调用
一旦设置了strokeStyle ,strokeStyle 后面没有再设置strokeStyle 就会继续原来的strokeStyle
fillStyle 同理
透明度
-
方式1
strokeStyle 和 fillStyle属性结合rgba:
ctx.strokeStyle = "rgba(255,0,0,0.3)";
-
方式2
globalAlpha 属性,这个会影响到canvas所有图形的透明度
ctx.globalAlpha = 0.8;
线宽
基于路径左右延伸,即路径的两边各绘制线宽的一半
// 真正的1像素 就是线条刚刚好在像素边界内
ctx.moveTo(10.5, 10);
ctx.lineTo(10.5, 100);
ctx.lineWidth = 1;
ctx.stroke()
lineCap线条端点的样式
- butt 截断,默认是 butt。
- round 圆形
- square 正方形
lineJoin线条连接处的样式
- round 圆形
- bevel 斜角
- miter 斜槽规,默认是 miter。
绘制文本
2种方法
- fillText(指定的文本,x,y) 在(x,y ) 位置,填充指定的文本
- strokeText(指定的文本,x,y) 在(x,y ) 位置,绘制文本边框
要设置字体大小和字体类型
ctx.font = "40px serif";
ctx.textAlign = "center";//文本对齐选项
ctx.textBaseline = "middle"//基线对齐选项
ctx.fillText("Ay", 100, 100)
绘制图片
drawImage方法
drawImage(image, x, y)
其中image可以是image也可以是canvas对象 x和y是其在目标canvas里的起始坐标
先绘制图片再绘制折线
绘画状态
绘画状态可以用save和restore来保存到栈和恢复 没有参数 成对存在
绘画状态:移动旋转缩放 线条的样式(strokeStyle、fillStyle、globalAlpha、lineCap..) 字体样式(font, textAlign, textBaseline ...)
Canvas的形变
- 平移
- 旋转
- 缩放
步骤:
- 保存状态 ctx.save();
- 形变
- 绘制图形
- 恢复状态 ctx.restore()
ctx.save();
ctx.lineWidth = 5
ctx.lineCap = "round"
ctx.translate(150, 150)
ctx.rotate(
Math.PI * 2 / 12 * hours + Math.PI * 2 / 12 / 60 * min + Math.PI * 2 / 12 / 60 / 60 * second
)
ctx.beginPath();
ctx.moveTo(0, 0)
ctx.lineTo(0, -50)
ctx.stroke()
ctx.restore()
平移
基于最新的坐标原点 移动坐标
translate移动画布
旋转
rotate(angle):以坐标原点为中心旋转canvas
旋转360°:Math.PI*2
缩放
scale(x, y)会对xy轴放大缩小
ctx.scale(0.5, 0.5);
动画
对画布上所有的图形一帧一帧重绘
定时重绘:requestAnimationFrame
绘制一帧的步骤
- 用clearRect(x,y,w,h) 清空canvas
- 保存状态
- 修改canvas状态(样式,移动坐标,旋转)
- 绘制动画中的一帧
- 恢复canvas状态
requestAnimationFrame: 浏览器会下一次重绘之前调用requestAnimationFrame的回调函数
2个案例