Canvas学习
canvas 读音 /ˈkænvəs/,
学习的目的主要是为了网状关系拓扑图形的绘制.
推荐文档:Canvas - Web API 接口参考 | MDN
一、 Canvas概述
canvas是用来绘制图形的.它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
长久以来, web上的动画都是Flash. 比如动画广告\ 游戏等等, 基本都是Flash 实现的. Flash目前都被禁用了, 而且漏洞很多, 重量很大, 需要安装Adobe Flash Player, 而且也会卡顿和不流畅等等.
canvas是HTML5提出的新标签,彻底颠覆了Flash的主导地位。无论是广告、游戏都可以使用canvas实现。
Canvas 是一个轻量级的画布, 我们使用Canvas进行JS的编程,不需要增加额外的组件,性能也很好,不卡顿,在手机中也很流畅。
1.1 Hello world
我们可以在页面中设置一个canvas标签
| | <canvas width="500" height="500">
| | 当前的浏览器版本不支持,请升级浏览器
| | <canvas/>
canvas的标签属性只有两个,width和height,表示的是canvas画布的宽度和高度,不要用css来设置,而是用属性来设置,画布会失真变形。
标签的innerContent是用来提示低版本浏览器(IE6、7、8)并不能正常使用canvas,高版本的浏览器是看不到canvas标签内部的文字的。
//得到canvas的画布 并 获取上下文
let ctx = document.querySelector('canvas').getContext('2d')
// 设置颜色
ctx.fillStyle = 'pink'
// 定义y轴
let y = 0
setInterval(() => {
ctx.clearRect(0, 0, 800, 600)
y++
if (y > 600) {
y = 0
}
ctx.fillRect(300, y, 100, 100)
}, 10);
通过上面的代码我们发下canvas本质上就是利用代码在浏览器的页面上进行画画,比如上面的代码fillRect就代表在页面中绘制矩形,一共四个属性,前两个300,0代表(x, y), 即填充起始位置,后两个(第一个表示宽,第二个表示高)100代表宽,100代表高,单位都是px。
1.2 Canvas的像素化
我们用canvas绘制了一个图形,一旦绘制成功了,canvas就像素化了他们。canvas没有能力,从画布上再次得到这个图形,也就是我们没有能力去修改已经在画布上的内容,这个就是canvas比较轻量的原因,Flash重的原因之一就有它可以通过对应的api得到已经上“画布”的内容然后再次绘制
如果我们想要这个canvas图形移动,必须按照:清屏——更新——渲染的逻辑进行编程。总之,就是重新再画一次
1.3 Canvas的动画思想
要使用面向对象的思想来创建动画。
canvas上画布的元素,就被像素化了,所以不能通过style.left方法进行修改,而且必须要重新绘制。
//得到canvas的画布 并 获取上下文
let ctx = document.querySelector('canvas').getContext('2d')
// 设置颜色
ctx.fillStyle = 'pink'
// 定义y轴
let y = 0
// 动画过程
setInterval(() => {
// 清除动画,0,0 代表从什么位置开始, 800 600 代表清除的宽度和高度
ctx.clearRect(0, 0, 800, 600)
// 更新信号量
y++
// 如果已经走出画布,则更新信号量为初始位置
if (y > 600) {
y = 0
}
ctx.fillRect(300, y, 100, 100)
}, 10);
实际上,动画的生成就是相关静态画面连续播放,这个就是动画的过程。我们把每一次绘制的静态话面叫做一帧,时间的间隔(定时器的间隔)就是表示的是帧的间隔。
二、Canvas的绘制功能
2.1 绘制矩形
填充一个矩形:
//得到canvas的画布
let canvas = document.querySelector('canvas')
let ctx = canvas.getContext('2d')
console.log(ctx); //得到一个实例对象
// 绘制一个填充满的盒子
ctx.fillStyle = 'green'
ctx.fillRect(100, 100, 200, 200)
参数含义:分别代表填充坐标x、填充坐标y、矩形的高度和宽度。
绘制矩形边框,和填充不同的是绘制使用的是strokeRect, 和strokeStyle实现的
// 绘制一个边框
ctx.strokeStyle = 'skyblue'
ctx.strokeRect(50, 50, 100, 100)
参数含义:分别代表绘制坐标x、绘制坐标y、矩形的高度和宽度。
清除画布,使用clearRect
// 绘制一个填充满的盒子
ctx.fillStyle = 'green'
ctx.fillRect(100, 100, 200, 200)
// 清除某一部分区域
ctx.clearRect(100, 100, 100, 100)
2.2 绘制路径
绘制路径的作用是为了设置一个不规则的多边形状态
路径都是闭合的,使用路径进行绘制的时候需要既定的步骤:
-
需要设置路径的起点
-
使用绘制命令画出路径
-
封闭路径
-
填充或者绘制已经封闭路径的形状
// 创建一个路径
ctx.beginPath()
// 1. 移动绘制点
ctx.moveTo(100, 100)
// 2. 描述行进路径
ctx.lineTo(200, 200)
ctx.lineTo(400, 180)
ctx.lineTo(380, 50)
// 3. 封闭路径
ctx.closePath();
// 4. 绘制这个不规则的图形
ctx.strokeStyle = 'red'
ctx.stroke()
ctx.fillStyle = 'orange'
ctx.fill()
总结我们要绘制一个图形,要按照顺序
开始路径ctx.beginPath()
移动绘制点ctx.moveTo(x, y)
描述绘制路径ctx.lineTo(x, y)
多次描述绘制路径ctx.lineTo(x, y)
闭合路径ctx.closePath()
描边ctx.stroke()
填充ctx.fill()
此时我们发现之前我们在学习绘制矩形的时候使用的是fillRect和strokeRect,但是实际上fill和stroke也是具有绘制填充功能的
stroke(): 通过线条来绘制图形轮廓。
fill(): 通过填充路径的内容区域生成实心的图形。
我们在绘制路径的时候选择不关闭路径(closePath),这个时候会实现自封闭现象(只针对fill,stroke不生效)
2.3 绘制两条不同颜色的路径
// 获取节点
let canvas = document.querySelector('canvas')
// 获取执行上下文
let ctx = canvas.getContext('2d')
ctx.beginPath() // 开始路径
ctx.moveTo(100, 100) // 移动起点
ctx.lineTo(200, 200) // 终点位置
ctx.strokeStyle = 'red' //红色的直线
ctx.lineWidth = 5 // 路径宽度
ctx.stroke() // 描边效果
ctx.beginPath()
ctx.moveTo(200, 200)
ctx.lineTo(300, 100)
ctx.strokeStyle = 'green' //绿色的直线
ctx.lineWidth = 5
ctx.stroke()
ctx.beginPath()
ctx.moveTo(300, 100)
ctx.lineTo(100, 100)
ctx.strokeStyle = 'skyblue' //浅蓝色的直线
ctx.lineWidth = 5
ctx.stroke()
2.4 绘制圆弧
arc(x, y, radius, startAngle, endAngle, anticlockwise)
画一个以(x, y)为圆心的以radius为半径的圆弧(圆), 从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针false, true为逆时针)来生成。
// 创建一个路径
ctx.beginPath()
// 移动绘制点
// ctx.arc(200, 200, 100, 0, 2 * Math.PI, false)
ctx.arc(200, 200, 100, 0, 2 * 3.14, false)
ctx.stroke() //描边
圆弧也是绘制路径的一种,也需要beginPath和stroke.
参数的含义:200, 200代表的是起始x,y坐标,100代表的是圆心半径,0和1代表的是开始和结束位置,单位如果是数字,代表的是一个圆弧的弧度(一个圆的弧度是Math.PI * 2, 约等于7个弧度),所以在顺时针的情况下,如果如果两个参数的差为7,则代表绘制一个圆。
2.5 绘制笑脸
let canvas = document.querySelector('canvas')
let ctx = canvas.getContext('2d')
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // 绘制
ctx.moveTo(110, 75);
ctx.arc(75, 75, 35, 0, Math.PI, false); // 口 (顺时针)
ctx.moveTo(65, 65);
ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // 左眼
ctx.moveTo(95, 65);
ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // 右眼
ctx.stroke();
2.6 线型
lineWidth
我们可以利用lineWidth设置线的粗细,属性值为number型,默认为1,没有单位
ctx.lineWidth = 1.0 //线宽为 1px
2.7 文本
我们可以在画布上绘制文字:
// 空格前为文字大小,空格后为字体类型
ctx.font = "30px 微软雅黑"
// 第一个参数为文字内容,第二和第三个参数为文字绘制坐标,
// 第四个参数是可选参数,代表文字的最大宽度,如果字体宽度超过该值则压缩字体宽度
ctx.fillText("你好,世界!", 100, 100)
我们可以使用textAlign来设置文本的对齐选项。可选的值包括:start, end, left, right or center。默认值是 start。该对齐是基于fillText方法的x的值。
ctx.textAlign = "left" || "right" || "center" || "start" || "end";
-
left : 文本左对齐。
-
right: 文本右对齐。
-
center: 文本居中对齐。
-
start: 文本对齐界线开始的地方 (左对齐指本地从左向右,右对齐指本地从右向左)。
-
end: 文本对齐界线结束的地方 (左对齐指本地从左向右,右对齐指本地从右向左)。
三、总结
在这里只是一部分 后续会陆续完善一下
Canvas链接 Canvas - Web API 接口参考 | MDN