我们都是架构师!
架构师订阅号,关注获取更多技术分享
现已开通多个微信群,有兴趣交流学习的同学
可加若飞微信:1321113940进群
合作邮箱:[email protected]
前言
淘宝玩法平台的版头动画,是由我们的视觉设计师 @鲍龙 设计,由我实现的。 点击 Demo 观看实际效果。 版头动画中,跑着一列小火车。这销魂的路线,确实能给人「眼前一亮」的感觉,也有一些同学询问我实现的原理。其实,真的很简单,就是一点小技巧而已。 采集数据首先,我沿着轨道采集了一些点的坐标。平滑的地方可以稀疏一些,曲率较大的地方需要采集得密一些。采集好的点,画出来大概是这样的: 确定位置动画的基本原理,就是在每一帧的时候进行重绘。我们需要知道,某一帧 时,小火车的位置(坐标)是多少? 假设小火车是匀速的,速度为 train.speed = 10; train.L = 0; setInterval(function(){ var inter = 50; train.L = inter * trans.speed; // 根据 train.L 算出 train 的位置 // 在那个位置上画出 train }, 50) 有了小火车当前帧已经行进的距离 假设小火车在第 i 个点 p[i] 和第 i 1 个点 p[i 1] 之间,而且在比例为 q 的位置上,如何确定小火车的位置呢。 简单的线性内插,求得: train.x = (1-q) * p[i].x q * p[i 1].x train.y = (1-q) * p[i].y q * p[i 1].y 这样就能够算出小火车每一帧的位置坐标,我们只需要在 (train.x , train.y) 位置绘制出火车即可。 确定角度现在,小火车已经能开动了。但遗憾的是,它永远只保持着一个方向,但显然的是,沿着轨道方向的小火车更加真实。我们可以通过轨道上任意相邻两点的坐标(比如下图的 A B 两点),求出这两点间线段的角度。然后在对小火车平移之后,先不急着绘制,再旋转这个角度绘制,小火车就能沿着轨道了。 看上去不错,但是还不够,因为采样点不够密集,所以在每个采样点处,小火车的旋转角度都会「骤变」一下,动画看起来就会不流畅。所以,对于每一帧的旋转角度,我们再进行一次内插。 首先,为每个点确定一个「切线」法向量,如 A 点的 theta_A,B 点的 theta_B,B 点的 theta_C。确定的过程,可以取前后两点连线的法线,比如 theta_B 就是 AC 两点的法线。然后对于任意一帧,根据小火车的位置,内插出火车的角度。 train.theta = (1-q) * p[i].theta q * p[i 1].theta 这样,小火车跑动就不会再一卡一卡的了。 速度问题之前,我们把小火车的速度设置为了常量,但是如果它的速度是合理变化的,那就会更加逼真了。对于过山车而言,简单的能量守恒定律告诉我们,速度的平方与小火车的高度存在某种线性关系。稍加推理,不难写出: // 在每一帧 train.speed = Math.sqrt(C1 - C2 * train.y) 适当地调节两个常量 总结动画的原理很简单,最关键的就是「内插」而已。每一帧中,不管是小火车的位置还是角度,都是通过内插得来的。这样,位置和角度的值就会是连续变化的。其实,这种情况,也许把曲线拟合成若干条贝塞尔曲线互相连接,会更加「完美」,但是经验告诉我,拟合贝塞尔曲线也许没那么轻松,而适当的采样点也蕴含了足够的信息,足以使我完成这个动画。 来源:淘宝前端团队(FED) 原文:http://taobaofed.org/blog/2015/12/28/anim-train/ 转载文章,向原作者致敬!如有侵权或不周之处,敬请劳烦联系若飞(微信:1321113940)马上删除,谢谢! END 我们都是架构师! 架构师订阅号,关注获取更多技术分享 现已开通多个微信群,有兴趣交流学习的同学 可加若飞微信:1321113940进群 合作邮箱:[email protected] 本文转载自:微信公众账号 - 架构师,版权归原作者所有! |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|