对应《WebGL编程指南》代码:15-RotatingTriangle
要点:矩阵变换库(cuon-matrix.js 本书专用)、Matrix4对象、setRotate方法
tips:当前页含有动画示例,Tag Cloud可能会失效。
知识点
一、动画原理
基本原理:不断擦除和重绘三角形,并且每次重绘时轻微改变其角度
为了生成动画,需要两个关键机制:
机制一:在规定时刻反复调用同一个函数来绘制三角形。
机制二:在每次绘制之前,清除上次绘制的内容,并使三角形旋转相应的角度
另外:由于程序需要反复绘制三角形,所有提前指定背景色,而不是在进行绘制之前(设置好的背景色在重设之前一直有效)
二、反复调用绘制函数(tick())
1 | var tick = function () { |
三、按照指定的旋转角度绘制三角形(draw())
参数 | |
---|---|
gl | 绘制三角形的上下文 |
n | 顶点个数 |
currentAngle | 当前的旋转角度 |
modelMatrix | 根据当前的旋转角度计算出的旋转矩阵,存储在matrix4对象中 |
u_ModelMatrix | 顶点着色器中同名的uniform变量的存储位置,modelMatrix变量将被传递至此处 |
1 | function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) |
四、请求再次被调用(requestAnimationFrame(tick))
按传统习惯,JavaScript想要重复执行某个任务可以使用setInterval()函数。
现代浏览器都支持多个标签页,每个标签页具有单独JavaScript环境,但是自setInterval()诞生之初,浏览器还没有支持多标签页,所以现代浏览器中,不管标签页是否被激活,其中的setInterval()函数都会反复调用func,如果标签页过多,就会增加浏览器负荷。于是引入了requestAnimationFrame()方法,该方法只有当标签页激活时才触发。注意,该函数无法指定重复调用的间隔,传入的函数func会在浏览器需要网页的某个元素重绘时被调用,其机制更像setTimeOut,想要再次调用就必须重新发起一次请求
五、更新旋转角(animate())
函数逻辑:根据本次调用与上次调用之间的时间间隔来决定这一帧的旋转角度比上一帧大出多少。
why?requestAnimationFrame只是请求浏览器在适当的时机调用参数函数,那么浏览器就会根据自身状态决定每次调用的时刻,在不同浏览器上,或在同一浏览器不同状态下,都有所不同。既然调用tick函数的间隔不恒定,那么每次调用时简单的向currentAngle加上一个固定角度值(度/秒)就会导致不可控的加速或减速的旋转效果。
currentAngle: 三角形当前旋转角度,即从初始位置算起,当前三角形旋转了多少度。
1 | // 记录上一次调用函数的时刻 |
实例
1 |
|
1 | //RotatingTriangle.js |
示例
Tips: Please indicate the source and original author when reprinting or quoting this article.