JavaScript学习笔记(四十五)动画与Canvas图形(一)
使用requestAnimationFrame
1、早期定时动画
- 早期使用setInterval()控制动画的执行。
- 存在的问题:
- 无法准确知晓循环之间的延时。
- 不能保证时间精度。
1 | (function() { |
2、requestAnimationFrame
requestAnimationFrame()
- 方法接收一个参数:要在重绘屏幕前调用的函数。这个函数就是修改DOM样式以反映下一次重绘有什么变化的地方。
- 为了实现动画循环,可以串联调用。
1
2
3
4
5
6
7
8function updateProgress() {
var div = document.getElementById("status");
div.style.width = (parseInt(div.style.width, 10) + 5) + "%";
if (div.style.left != "100%") {
requestAnimationFrame(updateProgress);
}
}
requestAnimationFrame(updateProgress);
因为requestAnimationFrame()只会调用一次传入的函数,所以每次更新用户界面时需要再手动调用它一次。同样,也需要控制动画何时停止。
传给requestAnimationFrame()的函数实际上可以接收一个参数,此参数是一个 DOMHighResTimestamp 的实例(比如performance.now()返回的值),表示下次重绘的时间。
3、cancelAnimationFrame
- 与setTimeout类似,requestAnimationFrame()返回一个请求ID;
- cancelAnimationFrame()来取消重绘任务。
1 | let requestID = window.requestAnimationFrame(() => { |
4、通过requestAnimationFrame节流
- 支持该方法的浏览器会暴露作为钩子的回调队列。
- 钩子就是浏览器在执行下一次重绘前的一个点。
- 通过requestAnimationFrame ()递归地向队列中加入回调函数,可以保证每次重绘最多只调用一次回调函数。
基本的画布功能
- 创建
<canvas>
元素时至少需要width和height属性。 - getContext()方法可以获取对绘图上下文的引用。
- 对于平面图形,需要传入参数:2d。
- toDataURL()方法可以导出
<canvas>
元素上的图像。- 方法接收一个参数:要生成图像的MIME类型。
1 | let drawing = document.getElementById("drawing"); |
2D绘图上下文
1、填充和描边
- 两个属性:fillStyle和strokeStyle。
- 可以是字符串】渐变对象或图案对象;
- 默认值为”#000000”;
- 字符串表示颜色值,可以是CSS支持的任意格式:名称、十六进制代码、rgb、rgba、hsl或hsla。
2、绘制矩形
- fillRect()、strokeRect()、clearRect():
- 方法都接收4个参数:矩形x坐标、矩形y坐标、矩形宽度和矩形高度(单位均为像素)。
- fillRect()方法用于以指定颜色在画布上绘制并填充矩形;填充颜色使用fillStyle属性指定(实心矩形)。
- strokeRect()方法可以通过strokeStyle属性指定的颜色绘制举行轮廓(绘制边框,内部空心)。
- clearRect()方法可以擦除画布中某个区域
- 方法用于把绘图上下文种的某个区域变透明。
1 | let drawing = document.getElementById("drawing"); |
3、绘制路径
- beginPath()方法是开始绘制新路径必须首先调用的方法。
- 再用以下方法来绘制路径:
- 创建路径之后,可以使用closePath()方法绘制一条返回起点的线。如果路径已经完成,则既可以指定fillstyle 属性并调用fill ()方法来填充路径,也可以指定strokeStyle 属性并调用stroke ()方法来描画路径,还可以调用clip()方法基于已有路径创建一 个新剪切区域。
- isPointInPath()方法用于确定指定的点是否在路径上,可以在关闭路径前随时调用
- 接收x轴和y轴坐标作为参数。
1 | let drawing = document.getElementById("drawing"); |
4、绘制文本
- fillText()和strokeText()用于绘制文本。
- 两个方法接收4个参数:字符串、x坐标、y坐标和可选的最大像素宽度。
- fillText()方法使用fillStyle属性绘制文本;
- strokeText()方法使用strokeStyle属性;
- 两个方法最终绘制的结果都取决于以下3个属性:
- measureText()方法
- 接收一个参数:要绘制的文本;
- 返回一个TextMetrics对象;
- 使用font、textAlign和textBaseline属性当前的值计算绘制指定文本后的大小。
1 | let fontSize = 100; |
5、变换
- 以下方法可用于改变绘制上下文的变换矩阵:
- 所有这些变换,包括fillstyle和strokestyle属性,会一直保留在上下文中,直到再次修改它们。
6、绘制图像
- drawImage()方法用于把现有图像绘制到画布上。
- 方法可以接收3组不同的参数:
1、 传入HTML种img元素/canvas元素、绘制目标的x和y坐标;(直接绘制)
2、 传入HTML img元素、绘制目标的x、y坐标、目标宽度、目标高度;(可用于改变图像大小)
3、 要绘制的图像、源图像x坐标、源图像y坐标、源图像宽度、源图像高度、目标区域x坐标、目标区域y坐标、目标区域宽度、目标区域高度。(只把图像绘制到上下文中的一个区域)
7、阴影
- 2D上下文可以根据以下属性的值自动为已有形状或路径生成阴影:
- 这些属性都可以通过context对象读写。
1 | let context = drawing.getContext("2d"); |
8、渐变
- 渐变通过CanvasGradient的实例表示,在2D上下文中创建和修改都非常简单。
- createLinearGradient()方法用于创建线性渐变。
- 接收4个参数:起点x坐标、起点y坐标、终点x坐标和终点y坐标。
- 调用之后,该方法会以指定大小创建一个新的CanvasGradient对象并返回实例。
- addColorStop()方法为渐变指定色标。
- 方法接收两个参数:色标位置和CSS颜色字符串。
- 色标位置通过0~1范围的值表示,0是第一种颜色,1是最后一种颜色。
1
2
3
4
5
6
7
8
9let gradient = context.createLinearGradient(30, 30, 70, 70);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
// 绘制红色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
// 绘制渐变矩形
context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);
9、图案
- createPattern()方法。
- 接收两个参数:一个HTML
<img>
和一个表示该如何重复图像的字符串。 - 第二个参数的值与CSS的background-repeat属性,包括”repeat”、”repeat-x”、”repeat-y”和”no-repeat”。
- 第一个参数也可以是
<video>
元素或者另一个<canvas>
元素。
- 接收两个参数:一个HTML
1 | let image = document.images[0], |
10、图像数据
- getImageData()方法获取原始图像数据。
- 方法接收4个参数:要取得数据中第一个像素的左上角坐标和要取得的像素宽度及高度。
- 返回的对象是一个ImageData的实例。每个对象都包含3个属性:
- width:图像宽;
- height:图像高;
- data:包含图像的原始像素信息的数组。每个data中的元素都由4个值表示,分别代表红、绿、蓝和透明度。
11、合成
- globalAlpha属性是一个范围在0~1的值(包括0和1),用于指定所有绘制内容的透明度,默认值为0。
- globalCompositionOperation属性表示新绘制的形状如何与上下文中已有的形状融合。该属性为一个字符串,可以取下列值:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 姚永坤的小窝!
评论