动画
实现动画的关键就是:不断擦除并重绘动画图形,并且在每次重绘时轻微的改变动画属性。
Rotating Triangle
RotatingTriangle Code
1 |
|
1 | let VSHADER_SOURCE = |
步骤分解
反复调用绘制函数 tick()
tick中实现了关键的2个步骤:
- 更新角度
- 重绘
下图的基本步骤可以用来实现各种动画,是3D图形编程的关键技术。
按照指定旋转角度绘制三角形 draw()
draw一共有四步操作:
step1
设置旋转矩阵。
1 | modelMatrix.setRotate(currentAngle,0,0,1); |
step2
将旋转矩阵传入Vertex_Shader。
1 | gl.uniformMatrix4fv(u_ModelMatrix,false,modelMatrix.elements); |
step3
清除canvas。
1 | gl.clear(gl.COLOR_BUFFER_BIT); |
step4
开始绘制。
1 | gl.drawArrays(gl.TRIANGLES,0,n); |
请求再次被调用 requestAnimationFrame()
为什么不用setInterval?
如果要实现 重复执行某个特定的任务,
setInterval 是比较常用的方法,
但是它存在一个弊端:
不管其被调用的标签页是否被激活,其中的setInterval()函数都会反复调用。
这会增加浏览器的负荷,
requestAnimation只有在标签页激活时才生效。
也可以通过 cancelAnimationFrame 取消请求:
更新旋转角 aniamte()
要注意的是:调用requestAnimationFrame(),
只是请求浏览器在适当的时机调用参数函数,
因此不能保证每次调用间隔的时间相同,
需要计算时间间隔,并由时间间隔计算这一帧中三角形的旋转角度。
g_last = 上一帧开始的时间
elapsed = 两帧之间时间间隔 = 这一帧开始的时间 - g_last
ANGLE_STEP/1000.0 = 每毫秒旋转度数
旋转变化度数 = ANGLE_STEP / 1000.0 * elapsed
1 | let newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0; |
Rotating Translated Triangle
结合本章内容的小动画