separateValue
这次我们先来讨论如何正确分离属性值与单位,假设要实现下面的动画,
点击动画按钮,同时改变透明度、宽度以及旋转角度。
1 |
|
由于在
velocity
中旋转不是使用transform
而必须使用rotateZ
,少了Z
也不行。
由于rotateZ
这样的动画存在,所以不能单纯从值中提取出单位,还要根据属性名来获取,比如rotateZ
是无法获取到开始值的,所以就额外处理一次,使用getUnitType
返回预期的值。
1 | function separateValue (property, value) { |
多个属性值变化
之前使用全局变量保存property
、startValue
、endValue
和unitType
,如果要改变多个属性,就必须使用到对象了,对象上每一个属性都有这些值。
1 | let propertiesContainer = {} |
接下来就简单了,只要在tick
函数内遍历propertiesContainer
获取不同属性的开始值与结束值计算得到当前值即可。
1 | // 核心动画函数 |
透明度与宽度能够正确处理,但是角度却没有正确处理,因为并没有对rotateZ
做特殊处理,实际并不能够直接给 DOM 设置rotateZ
属性而需要设置transform
属性。
改变角度
在调用setPropertyValue
时,传入了(element, 'rotateZ', 'xxdeg')
,为了职责分明,不在调用该函数前将rotateZ
改变为transform
,而是在setPropertyValue
函数内部根据属性来判断究竟该怎么设置元素的属性值。
1 | function setPropertyValue(element, property, value) { |
有哪些属性是使用transform
设置的呢,在源码 499 行附近
- rotate(X|Y|Z)
- scale(X|Y|Z)
- skew(X|Y)
- translate(X|Y|Z)
1 | function setPropertyValue (element, property, value) { |
能够正确动画,但是却很卡。。不过只需要将判断是否终止动画tick
的判断拿到for..in
循环外即可。
最终代码
1 | ;(function (window) { |
总结
这次主要是实现了分割值与单位,同时简单的实现了同时改变多个属性的动画。仍存在很大缺陷,下篇笔记主要解决颜色值的改变与开始值结束值单位不一致这两个问题。