原生webgl学习(八) WebGL实现动画:平移、缩放和旋转

笔者在前面的文章主要是针对二维的静态图形进行开发;但有时候我们需要模型动起来,就像真实世界中的一切运动变化一样。场景如果不是动态的,那么可想而知,我们的世界是多么枯燥乏味。为了让我们开发的图形应用看上去更加高大上,这一节笔者将和大家一起做一个动画的例子;本节的内容用到了前面文章提到过的平移、缩放和旋转变换,如果对这方面还不是很熟悉的同学,可以参考这篇文章:原生webgl学习(三) WebGL中的矩阵运算:平移、旋转和缩放。图形动画的根本在于改变图形顶点的位置,打个比方,例如现在的你坐或站在一个位置,咱以这个位置为坐标系原点,下一刻你起身走动,你所处的位置也就发生了变化,跟着组成你身体的顶点位置也相对于坐标系发生了偏移,这种偏移并不是说你身上少了一块肉或者多了一块肉,这只是你在世界坐标系的位置发生了变化而已,如果你持续不断的在走动,就构成了我们所认知的动画,所以动画的本质还是顶点在某个坐标系内位置发生了变化,这种变化是持续不断的。如下图所示:

原生webgl学习(八) WebGL实现动画:平移、缩放和旋转_第1张图片

 如果对笔者的博客上的代码编写方式还不是很熟悉请参考笔者其他的博文:原生 WebGL开发文章目录(持续更新),里面的文章对代码有详细注释和原理解释。说到这里,相信大家已经期待看见动画的效果,笔者只做了一个gif图,呈现了本文demo的动画实现过程,忽略上面的网址(一个录屏软件生成的水印)。

原生webgl学习(八) WebGL实现动画:平移、缩放和旋转_第2张图片

接下来我们一起来看一下代码,我们主要看关键功能实现的代码,如果需要完整代码,读者可以自行下载:https://gitee.com/babyogl/learnWebGL,本例代码在文件夹chapter-04中的animate-rotating.html。首先,我们先定义一些与动画相关的变量:

let translate = [100, 400];//初始平移
const TRANSLATE_STEP = 100;//平移幅度
let angle = 0;//旋转角
const ANGLE_STEP = 1.0;//旋转幅度
let scale = [1, 1];//缩放比例

其次,要将定义的平移、旋转和缩放的值传递给着色器:

  let tMatrix = m3.translation(translate[0], translate[1]);
  let rMatrix = m3.rotation(angle);
  let sMatrix = m3.scaling(scale[0],scale[1]);
  var matrix = m3.multiply(tMatrix, rMatrix);
  matrix = m3.multiply(matrix, sMatrix);

 接下来,实现图形旋转、平移和缩放动画的功能:

//实现旋转
let r_last = Date.now();//记录开始时间
function updateAngle(angle) {
    let now = Date.now();
    let elapsed = now - r_last;
    r_last = now;
    let newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;

    return newAngle %= 360;
 }

  //实现平移
  let t_last = Date.now();//记录开始时间
  function updateTranslate(x, y) {
     let now = Date.now();
     let elapsed = now - t_last;
     t_last = now;

     let dx = x + elapsed * TRANSLATE_STEP / 1000;
     let tx = dx;

     if (tx > 800) {
        tx = tx - dx;
        scale[0] = 1;
        scale[1] = 1;
      }
      let translate =[tx, y];

      return translate;
   }

        //实现缩放
    function updateSale(sx, sy) {
       sx += Math.random() / 200;
       sy += Math.random() / 200;
       return [sx, sy];

     }

最后我们通过resquestAnimationFrame功能实现持续不断的渲染功能,使场景看起来一直在动:

let animate = function() {
       angle = updateAngle(angle);
       translate = updateTranslate(translate[0], translate[1]);
       scale = updateSale(scale[0], scale[1]);
       drawScene(gl, program);
       requestAnimationFrame(animate);
 };

 整个domo代码码:




    
    旋转动画
    


    
    
    
    
    
    

 

你可能感兴趣的:(原生WebGL基础学习,原生webgl学习)