webgl 11.动画

animation.gif

动画需要循环绘制并在绘制的过程中不断改变位置,由于人眼的视觉停留看起来就像动画。

之前都用 setInterval 实现循环调用函数,但这个函数有个缺点是在 inactive 的 tab 中也会被调用影响性能。所以后来又加了一个新的方法 requestAnimationFrame(func) 这个方法会在浏览器 redraw(重绘) 页面的时候调用一次。

var tick = function () {
    draw();
    requestAnimationFrame(tick);
};
tick();

可以这样实现循环调用 tick 函数。一般显示器刷新频率是 60fps (frame per second), 意味着 1 秒钟刷新 60 次,1秒=1000毫秒, 1000毫秒/60 约等于 16.7毫秒 , 所以 tick 函数大约每隔 16.7 毫秒会调用一次。

// vertex shader
var VERTEX_SHADER_SOURCE =
    'attribute vec4 a_Position;\n' +
    'uniform mat4 u_ModelMatrix;\n' +
    'void main() {\n' +
    '   gl_Position = u_ModelMatrix * a_Position;\n' +
    '}\n';

// fragment shader
var FRAGMENT_SHADER_SOURCE =
    'void main() {\n' +
    '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n' +
    '}\n';

var canvas = document.getElementById("canvas");
var gl = canvas.getContext('webgl');
gl.clearColor(0.0, 0.0, 0.0, 1.0);

if (!initShaders(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)) {
    alert('Failed to init shaders');
}

var vertices = new Float32Array([
    0.0, 0.5,
    -0.5, -0.5,
    0.5, -0.5
]);

initVertexBuffers(gl, vertices);

var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');

var ANGLE_STEP = 45.0;
var currentAngle = 0.0;
var modelMatrix = new Matrix4();

var g_last = Date.now();
function animate(angle) {
    var now = Date.now();
    var elapsed = now - g_last;
    g_last = now;

    var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
    return newAngle %= 360;
}

function draw() {
    modelMatrix.setRotate(currentAngle, 0, 0, 1);
    gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);

    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLES, 0, 3);
}

var tick = function () {
    currentAngle = animate(currentAngle);
    draw();
    requestAnimationFrame(tick);
};
tick();

function initVertexBuffers(gl, vertices) {
    var vertexBuffer = gl.createBuffer();
    if (!vertexBuffer) {
        console.log('Failed to create buffer object');
        return -1;
    }

    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(a_Position);
}

animate 函数的意思 1 秒钟大约旋转 45 度,tick 中调用了 animate , animate 也是约 16.7 毫秒调用一次

查看源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 前言 本文主要参考w3c资料,从底层实现原理的角度介绍了requestAnimationFrame、cancelA...
    Bruce_zhuan阅读 5,426评论 0 3
  • 作为一只前端狗,我们的使命就是在满足产品需求、实现交互设计的基础上,将最好的体验呈现给用户爸爸们。在保证性能的同时...
    桂圆_noble阅读 9,622评论 5 14
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 5,248评论 0 2
  • 隐藏元素的hide方法 让页面上的元素不可见,一般可以通过设置css的display为none属性。但是通过css...
    老夫撩发少年狂阅读 4,785评论 0 2
  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 7,680评论 0 10

友情链接更多精彩内容