动画控制
在页面中添加动画可以使页面得到更好的交互效果和用户体验,所以可以使用action指令来轻松实现元素的创建和移除或显示和隐藏时的动画效果。
动画的两个状态
动画会在插入(显示)和移除(隐藏)这两个状态时触发,所以drunk定义了created和removed两个状态类型,当元素插入DOM树后或设置成显示时,会触发created状态的动画,当元素即将移除或设置成隐藏时会触发removed状态的动画。
action指令需配合if,show或repeat指令使用时才能触发效果。
js动画
使用drunk.Action定义一个js动画:
drunk.Action.register('fade', {
created(element, done) {
element.style.opacity = 0;
var timerid = setInterval(function () {
var opacity = Number(getComputedStyle(element, null).opacity);
if (opacity >= 1) {
cancel();
return done();
}
element.style.opacity = opacity + 0.3;
}, 50);
function cancel() {
clearInterval(timerid);
}
return cancel;
},
removed(element, done) {
element.style.opacity = 1;
var timerid = setInterval(function () {
var opacity = Number(getComputedStyle(element, null).opacity);
if (opacity <= 0) {
cancel();
return done();
}
element.style.opacity = opacity - 0.3;
}, 50);
function cancel() {
clearInterval(timerid);
}
return cancel;
}
});
<div drunk-if="visible" drunk-action="fade"></div>
当元素插入(或显示)时,触发created状态的action,drunk内部会先查找是否存在名为fade的js动画,如何存在,调用该action的created方法,把当前的元素和一个内置的确认动画结束的回调函数(done)传进去,created方法要在动画执行完毕后调用这个回调方法,不然这个动画永远在pending状态,同时created方法要返回一个cancel方法用于在需要取消该动画时调用的取消函数。
css动画
<div drunk-if="visible" class="transition-base" drunk-action="slide-left"></div>
当visible为时,该元素被插入DOM树中,会触发created类型的action,drunk会优先查找名为slide-left的js动画,如果不存在,drunk会对该元素添加一个类名为slide-left-create(${actionName}-created,actionName在这里为slide-left)的样式,所以基于这个原理,我们可以这样定义css样式:
.transition-base {
width: 100px;
height: 100px;
transition: all 0.5s linear;
transform: translateX(100px);
}
.slide-left-created {
transform: translateX(0);
}
.slide-left-removed {
transform: translateX(100px);
}
插入DOM树时,元素在x轴上向右偏移了100px,当添加.slide-left-created样式时会触发transition动画,这样效果就出来了。
removed状态的动画原理也是相同
动画队列
action指令表达式可以接收多个动画指令。
<div drunk-show="visible" drunk-action="slide-left debounce rotate"></div>
当触发created状态的action时,drunk会把表达式解析成一个action列表,会一个个按顺序执行action,这样就可以形成一个动画队列。
当触发removed状态的action时,drunk会倒序执行这个action列表,动画就会反着播放。
添加动画延时
<div drunk-show="visible" drunk-action="slide-left 0.5 debounce 0.5 rotate"></div>
0.5这个数值表示当前一个action执行完毕后会等待0.5秒的延时,再执行下一个action。可以使用如下方式实现列表的所有item按顺序排队进入页面
<div class="transition-base" drunk-repeat="i in 10" drunk-action="{{0.1 * i}} slide-left"></div>
单个不具名css动画
当只有一个css动画时,可以使用如下写法
<style>
.slide-left {
width: 100px;
height: 100px;
transition: all 0.5s linear;
transform: translateX(100px);
}
.slide-left.drunk-created {
transform: translateX(0);
}
.slide-left.drunk-removed {
transform: translateX(100px);
}
</style>
<div drunk-show="visible" class="slide-left" drunk-action></div>
当触发created状态的action时,drunk解析得到的action列表为空,则直接忽略js动画的判断,添加一个类名为.drunk-created的样式(removed状态则为.drunk-removed),这样也同样是可以触发动画的。