基本完成了IFE的动画库任务(一),内心是崩溃的。JS补间动画的原理的确很简单,但在实现过程中,才意识到以前用的成熟的动画库,做了多少的工作。
对于多数成熟的动画库,你只需要提供动画的末状态 end 与动画时长 duration,它就能帮你绘制一段缓动动画,其原理很是单纯,大体可以拆成以下几步:
但就是这简单的5步,在实现的过程中有无数的坑啊......。
PS: 缓动函数的用法,无耻的贴上如何使用Tween.js各类原生动画运动缓动算法,这次的重点不是这个。
为了便于使用,传入的属性值是简单的CSS属性,如:
{
width: "12px",
height: "12px"
}
为了将其作为末状态,我们需要提取出
我们可以用正则表达式来匹配12px
中的px
,将匹配结果保存即可得到单位,再将匹配到的px
换成''
,即可得到数值的字符串形式。这里要对transform
系列的属性值做特别处理,由于transform
的属性值是rotate(30deg)
这种形式,所以无法直接处理,于是参考其他动画库,对于transform
的属性值特别传入,如:
{
width: "12px",
height: "12px",
rotateZ: "30deg",
translateX: "20px"
}
然后对其的单位提取步骤便可以统一。
初始状态的获得主要依靠getComputedStyle(el, null).getPropertyValue(propertyName)
方法,由于要传入属性名,所以肯定要依据添加的动画末状态来找到对应的属性名。这里依然是要特别处理transform
系列的属性值,可以用一个正则来匹配末状态传入的属性名,如果是rotateZ
这样的,就将transform
作为参数传入上面的方法,来获得初始状态的属性...................?结果是返回了matrix(a,b,c,d,e,f)
这样的属性值,这其中缘由可见理解CSS3 transform中的Matrix(矩阵),总之我们可以方便的从rotate
值计算出matrix
值,但是想要反过来(主要是获得rotate值,涉及到三角函数)却很不精确,暂时不考虑这种方法。事实上我们希望能像获取元素的style
属性一样,直接得到rotate
属性值,但对于设置在CSS样式表里的属性,的确无法直接得到。so目前的一个很坑的地方——对于一个在样式表里设置了transform
属性的元素,在第一次进行动画时,无法获得其初状态......这个问题在当前的velocityJs中也仍然存在,会直接从0的值开始动画,这里的解决方法暂时还没有寻得。但至少,之后的动画我们还是有办法掌控的。
非transform
系的没什么好讲的,直接style = 数值 + 单位
即可。但是由于transform的属性值很有可能不止一个,如果直接给style赋新值,将会覆盖所有transform属性。解决方法:定义一个transformCache对象,如果有transform属性需要设置,就在transformCache查找是否存在该属性:不存在便定义该属性与对应属性值,如果存在就更新属性值;然后遍历所有的属性,拼接出完整的transform
属性。
由于transform
有关的很多地方都要特殊处理,所以设计模式的运用得当在该情形下尤为重要,我自己写的似乎就有些混乱了......而且初始状态的transform获取还没有解决,待更新......