Canvas是什么,可以用来做什么
- HTML中的
<canvas>
元素通常用于中Web页面上绘图 -
<canvas>
是一个容器,其中的图像需要使用JavaScript来绘制 - 我们可以在
<canvas>
上绘制路径、矩形、图形、文本等 - 目前几乎所有浏览器都支持
<canvas>
坐标系统
基本功能
<canvas id="myCanvas" width="300" height="200"></canvas>
// 1. 找到canvas画布
let canvas = document.getElementById("myCanvas");
// 2. 得到画布的上下文,上下文有两个,2d & 3d
// 所有的图像绘制都是通过ctx属性或方法进行设置的,跟canvas标签没有关系了
let ctx = canvas.getContext('2d');
// 3. 描述要绘制都图形
ctx.fillStyle = "pink";
// 4. 绘制 填充矩形
// 参数分别是 左上角坐标(x, y)、x轴长度、 y轴长度
ctx.fillRect(0, 0, 150, 75);
// 矩形边框
ctx.strokeStyle = "red";
ctx.strokeRect(100, 100, 30, 30);
// 绘制直线
ctx.moveTo(10,10);
ctx.lineTo(100, 100);
ctx.stroke();
// 绘制不规则图形
ctx.beginPath();
ctx.moveTo(200,200);
ctx.lineTo(400,180);
ctx.lineTo(30, 50);
ctx.closePath();
// 圆心坐标(x, y)、半径、起始角度、结束角度、是否逆时针,
ctx.arc(60, 60, 50, 0, 2 * Math.PI, false);
// 描边
ctx.stroke();
// 填充
ctx.fill();
Canvas的像素化
使用canvas绘制一个图形,一旦绘制成功,canvas就将其像素化,canvas没有能力从画布上再次获得这个图形,也就是说我们没有能力去修改已经在画布上的内容。这就是canvas比较轻量的原因。
如果想让canvas上的图形移动,必须按照 清屏--更新--渲染 的逻辑进行编程,清屏最简单的做法就是 clearRect()
方法
如何使用JavaScript使绘制的图形动起来
为了执行动画,我们需要一些可以定时执行重绘的方法,JS中一般用以下三个:setInterval()
、setTimeout()
、requestAnimationFrame()
requestAnimationFrame()
该方法需要传入一个回调函数作为参数,当准备更新动画时调用此方法,使浏览器在下次重绘之前调用指定的回调函数。
注意:若想在浏览器每次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用requestAnimationFrame()
function animate () {
//清空所有的内容
ctx.clearRect(0, 0, 300, 300);
// 进行update操作
// ...
requestAnimationFrame(animate);
}
animate();
回调函数执行次数通常是每秒60次,但在大多数遵循W3C建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。为了提高性能和电池寿命,在大多数浏览器里,当requestAnimationFrame()
运行在后台标签页或者隐藏的<iframe>
里时,requestAnimationFrame()
会被暂停调用
与 setTimeout
setInterval
相比,requestAnimationFrame
最大的优势是 由系统来决定回调函数的执行时机。具体一点讲就是,系统每次绘制之前会主动调用 requestAnimationFrame
中的回调函数,如果系统绘制率是 60Hz,那么回调函数就每16.7ms 被执行一次,如果绘制频率是75Hz,那么这个间隔时间就变成了 1000/75=13.3ms。requestAnimationFrame
的执行步伐跟着系统的绘制频率走,它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。
一个栗子
https://codepen.io/qlcola/pen/GRrMEBW?editors=1010
canvas应用
canvas技术目前在很多领域中被广泛应用,每个领域也有众多成熟的框架
数据可视化
echarts、highcharts3D开发
ThreeJS、playcanvas图像处理
canvas可以对图像进行像素级的处理,getImageData(x,y,w,h)
可以获取画布中的图片对应的所有像素的RGBA值,然后通过一些算法给图像加滤镜效果
CamanJS
其他框架:heatmap.js、createjs 、PixiJS、spritejs等等