多段动画整合为一个动画的思路

更新日期: 2019-10-12 阅读: 2.9k 标签: 动画

需求

这是从一个项目中提取的需求。 大致的思路是: 通过获取后端的一系列人员的点位信息,在前端模拟人员的一段时间内的行动过程。

我们的开发人员首先想到的思路是,把获取的点位列表信息,每两个取取来,组成一条直线路径。然后基于每一条直线路径,创建一个动画Animate对象。(Animate是我们内部的一个管理/播放动画的类)。

其中创建每一个Animate动画的代码大致如下:

new Animate({
    from: p1,
    to : p2,
    dur : 30 * 1000,
    onUpdate(p){
       persion.setPosition(p)
    }
});

上述代码中,创建了一个动画对象,其参数表示如下:

  • from : p1, 动画开始的位置
  • to : p2,动画结束的位置
  • dur: 动画持续的时间
  • onUpdate函数,Animate对象内部更新处理每一帧数据的回调函数, Animate对象会根据from和 to以及dur的值,结合当前这一块的时间戳。计算出每一帧的插值数据p,并把p传递给回调函数onUpdate, 我们可以在onUpdate接收每一帧的数据值,并进行我们的更新动作,比如在本实例中会根据接收到的定向信息更新人员的位置信息。


问题

这个思路初期时没有问题的,只是到了实测的时候,发现性能有挺大的问题。因为获取一天的点位信息,点位的数量大概在几天条,这就意味这需要持续创建几千个Animate对象。这必然会造成性能问题。

在了解了这个问题之后,我建议我们的开发人员值只创建一个Animate对象,把所有直线路径的动画都整合到该Animate对象中。

要把所有的路径动画包含到一个Animate对象中,第一步是要改造from和to的值,此时不能直接使用点位信息来作为from和to的值。 实际上,我们可以通过百分比的方式来设置from和to,即from等于0,to等于1(相当于100%)。

为了简化问题,我们首先看只有一条直线的情况下,from和to设置位百分比是如何实现的。代码如下:

var p1, p2;
...
new Animate({
    from: 0,
    to : 1,
    dur : 30 * 1000,
    onUpdate(value){ 
       var p = lerpVectors(p1,p2,value);
       persion.setPosition(p)
    }
});

当把from和to设置位百分比时,Animate计算出来的每一帧的数值value是一个0~1之间的百分比值。此时,我们在onUpdate函数中,自己通过插值计算来计算点位信息p(其中lerpVectors函数完成此功能,此处不详述)。


整合思路

然后,我们在看多条直线的情况。 这种情况下的难点在于,要把一个动画分割成多段动画。然后对于分割的每一段,启动上面实例中的0~1的过程动画。其中涉及到两个问题

  1. Animate给定的value值,我们如何确定要执行的是那一段动画。
  2. 确定了那一段之后,如何把value值转换位这一段动画(从0~1)的动画值。


确定索引值

对于第一个问题,由需求有关。本文中,所有要执行动画的片段,其时间是一样的,这样就意外这,所有段的分配值是平均的。 举个例子,由10条直线组成动画,对于0~1之间的value值,由:

  • 0~0.1 执行第一条直线的动画
  • 0.1~0.2 执行第二条直线的动画
  • 依次类推。。。

因此我们可以通过循环变量和值比较来确定要执行动画直线的索引值,比如如下代码:

var index = 0;
for(var  i = 0;i < len;i ++){
  if(value > i / len && value < (i + 1) / len){
     index = i;
    break;
  }
}

上述代码中,首先启动以一个循环,循环的长度位片段的数量长度len。在循环体内,比较value值是否在索引i分片所对应的区间之内,如果在区间,就让index = i,以此确定要执行第index条直线的动画。

当然,如果通过数学公式,可以更加方便确定索引值index。怎么处理呢?

首先把0~1的范围扩展到0~len,此时把value值也乘以len,一样的道理,假设如果value * len的结果:

  • 在0~1之间,则value值对应的是第一分片的动画
  • 在1~2之间,则value值对应的是第二分片的动画
  • ...
  • 在len - 1 ~ len之间,则value值对应的是第二分片的动画

因此只要看value*len在那个整数区间即可,只是确定一个数值的整数区间,不在需要通过遍历,而只需要一个数学的函数即可:Math.floor。因此可以通过下述一行代码既可快速确定索引值:

var index = Math.floor(value * len);


确定每一段动画的帧数值

上面确定了索引值。 如何确定每段动画的的帧数值呢? 起始很简单,我们知道value * len一定在index ~ index + 1 之间。 那么可以通过平移把区间index ~ index + 1 平移到区间0~1即可。 平移只需要减去index即可。代码如下: ··· var valueOfSegment = value * len - index; ···

上代码

下面是比较完整的代码(伪代码):

var lines = [];// 要播放动画的一系列直线;
var len = lines.length;
new Animate({
    from: 0,
    to : 1,
    dur : 30 * 1000,
    onUpdate(value){ 
       var index = Math.floor(value * len);
       var valueOfSegment = value * len - index;
       var line = lines[index];
        var p1 = line.p1,p2 = line.p2;
       var p = lerpVectors(p1,p2,value);
       persion.setPosition(p)
    }
});


总结

把多个动画整合位一个,是在动画很多的时候,提高性能的一个有效手段。

善于利用数学公式,可以有效提高代码编写效率,本文中两个重要的公式如下, 具体作用见上面正文:

   var index = Math.floor(value * len);
   var valueOfSegment = value * len - index;

欢迎关注公众号“ITman彪叔”。


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/6810

相关推荐

css transition 实现滑入滑出

transition是css最简单的动画。 通常当一个div属性变化时,我们会立即看的变化,从旧样式到新样式是一瞬间的,嗖嗖嗖!!!但是,如果我希望是慢慢的从一种状态,转变成另外一种状态,怎么办? transition可以做到。

css3贝塞尔曲线(cubic-bezier)

css3 animation模块,其中animation-timing-function 和 transition-timing-function两个属性来控制动画速度分别提供了ease,liner,ease-in,ease-out

CSS动画@keyframes的用法

CSS动画允许大多数HTML元素的动画,而无需使用JavaScript或Flash!IE10+支持该属性的。其他低浏览器版本数字后跟-ms-, -webkit-,-moz-或-o-指定使用前缀的第一个版本。

css @keyframes属性 语法

@keyframes是CSS的一种规则,可以用来定义CSS动画的一个周期的行为,创建简单的动画。作用:通过 @keyframes 规则,您能够创建动画。

css3实现椭圆轨迹旋转

X轴Y轴在一个矩形内移动;设置动画延时设置Y轴延时为动画时长的一半, 运动轨迹变成菱形;设置三次贝塞尔曲线,为了看起来有立体感添加scale属性,scale动画应该是X轴和Y轴的时间总和

css环形滚动_内容加载的环形滚动动画效果

创建一个没有背景的圆,然后声明透明度为0.1的黑色边框(看起来是灰色),修改左侧边框颜色。此时会有一个静态的看起来只有左边框有颜色的空心圆。然后声明一个该元素逆时针旋转360度的动画,并让该动画无限播放(infinite)即可

Vue.js动画笔记_vue实现动画效果

Vue.js中的元素动画或页面跳转动画有多种实现方式比如:1、自己手动写CSS3动画来实现2、使用第三方CSS动画库如:Animate.css3、在构子函数中操作DOM4、使用第三方Js动画库如:Velocity.js。

动画函数的绘制及自定义动画函数

制作动画效果离不开动画运动函数,而我们用得最多的无疑就是Tween.js。根据不同的数学公式原理,Tween.js划分出了不同的动画类型,每种动画类型里面都包含以下的缓动类型:ease in 先慢后快、ease out 先块后慢、ease in out 先慢后快再慢

只用 CSS 就能做到的像素画/像素动画

这篇文章将会介绍只用 CSS 就能制作像素画·像素动画的方法。虽说纯 CSS 就能做到,但是为了更高的可维护性,也会顺便介绍使用 Sass 的制作方法。

css3 过渡和动画

在没有过渡属性的时候,当一个元素的属性值发生变化时,浏览器就会将个这个元素瞬间渲染成新属性值的样式。例如一个定位元素top:0,动态修改成top:100px,这个元素就瞬间跑到100px的位置,有时候我们为了达到某种视觉效果

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!