动画工作流
CSS 的问题
CSS 试图利用关键帧来解决复杂动画序列:
@keyframes myAnimation {
0% { opacity: 0; transform: scale(0, 0); }
25% { opacity: 1; transform: scale(1, 1); }
50% { transform: translate(100px, 0); }
100% { transform: translate(100px, 100px); }
}
#box { animation: myAnimation 2.75s; }
如果要把不透明度 opacity 动画时长增加1秒,但其他属性的动画持续时间不变,必须重新进行运算,才能使各百分比处的属性值与增加1秒后的时长匹配。
代码技巧:将样式与逻辑分离
一般做法
使用 addClass()
和 removeClass()
切换样式
.fadeInAndMove {
opacity: 1;
top: 50px;
}
// 设置.fadeInAndMove类的属性的动画,持续时间为1000毫秒
$element.addClass("fadeInAndMove", 1000);
使用 $.animate()
$element.animate({ opacity: 1, top: 50 }, 1000);
第一种做法将样式规则写在CSS样式表中(推荐这种做法); 第二种做法将样式规则和负责触发动画的 JavaScript 逻辑混在了一起。
优化做法
定义一个 js 对象,对象内容是动画的 CSS 属性,然后将同一个对象作为第一个参数传到 Velocity。
var fadeIn = {
// p代表“属性(properties)”
p: {
opacity: 1,
top: "50px"
},
// o代表“选项(options)”
o: {
duration: 1000,
easing: "linear"
}
};
// 将动画对象传入Velocity函数
$element.velocity(fadeIn.p, fadeIn.o);
代码技巧:组织排序动画
一般做法:回调地狱
// 设置element1的动画,紧接着设置element2的动画,紧接着设置element3的动画
$element1.velocity({ translateX: 100, opacity: 1 }, 1000, function() {
$element2.velocity({ translateX: 200, opacity: 1 }, 1000, function() {
$element3.velocity({ translateX: 300, opacity: 1 }, 1000);
});
});
优化做法
Velocity 有一个名为 UI pack 的小插件,顺序运行 sequence running。
<script src="velocity.js"></script>
<script src="velocity.ui.js"></script>
// 创建 Velocity 调用的数组
var loadingSequence = [
{ e: $element1, p: { translateX: 100, opacity: 1 }, o: { duration: 1000 } },
{ e: $element2, p: { translateX: 200, opacity: 1 }, o: { duration: 1000 } },
{ e: $element3, p: { translateX: 300, opacity: 1 }, o: { duration: 1000 } }
];
// 将数组传入 $.Velocity.RunSequence 函数中以启动序列
$.Velocity.RunSequence(loadingSequence);
代码技巧:打包你的效果
一般做法
$element
.velocity({ opacity: 1, scale: 1 }, { duration: 500, easing: "ease-in-out" })
.velocity({ borderWidth: "1rem" }, { delay: 200, easing: "spring", duration: 400 });
不够简洁优雅:velocity 重复调用
优化做法
velocity 的 UI pack 能注册效果,重用代码
模板
$.Velocity.RegisterEffect(name, {
// 未将duration值传入到调用中时,将使用的默认duration值
defaultDuration: duration,
// 以下Velocity调用一个接一个发生,每个所用的时间等于效果的总时间乘以预定的比例
calls: [
[ propertiesObject, durationPercentage, optionsObject ] ,
[ propertiesObject, durationPercentage, optionsObject ]
],
reset: resetPropertiesObject
});
示例
$.Velocity
.RegisterEffect("shadowIn", {
defaultDuration: 1000,
calls: [
[ { opacity: 1, scale: 1 }, 0.4 ] ,
[ { boxShadowBlur: 50 }, 0.6 ]
]
})
.RegisterEffect("shadowOut", {
defaultDuration: 800,
calls: [
// 我们反转顺序,以镜像"In"方向
[ { boxShadowBlur: 50 }, 0.2 ],
[ { opacity: 0, scale: 0 }, 0.8 ]
]
});
设计技巧
定时乘数
var M = 1;
$element1.animate({ opacity: 1 }, { duration: 1000 * M });
$element2.velocity({ opacity: 1 }, { delay: 250 * M });
好处:
- 将动画的速度减慢,有助于在复杂动画序列中完善单个动画的调用时间
- 将动画的速度加快,有助于执行重复性UI测试
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 动效设计理论
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论