Vue项目实战之改动饿了吗购物小球动画
html:没有写v-on: afterEnter函数了,因为执行不到,原因是enter的done;
<div class=”ball-container”>
<transition-group
name=”drop”
v-on:before-enter=”beforeEnter”
v-on:enter=”enter”
>
<div v-for=”(ball, index) in balls” v-show=”ball.show” class=”ball” :key=”index+1″>
<div class=”inner inner-hook”></div>
</div>
</transition-group>
</div>
js:
data() {
return {
balls: [
{show: false}, {show: false}, {show: false}, {show: false}, {show: false}
],
dropBalls: []
};
},
methods: {
drop(el) {
for (let i = 0; i < this.balls.length; i++) {
let ball = this.balls[i];
if (!ball.show) {
ball.show = true;
ball.el = el;
this.dropBalls.push(ball);
return;
}
}
},
beforeEnter(el) {
let count = this.balls.length;
while (count–) {
let ball = this.balls[count];
if (ball.show) {
let rect = ball.el.getBoundingClientRect();
let x = rect.left – 32;
let y = -(window.innerHeight – rect.top – 22);
el.style.display = ”;
el.style.webkitTransform = `translate3d(0,${y}px,0)`;
el.style.transform = `translate3d(0,${y}px,0)`;
let inner = el.getElementsByClassName(‘inner-hook’)[0];
inner.style.webkitTransform = `translate3d(${x}px,0,0)`;
inner.style.transform = `translate3d(${x}px,0,0)`;
}
}
},
enter(el, done) {
/* eslint-disable no-unused-vars */
let rf = el.offsetHeight;
this.$nextTick(() => {
el.style.webkitTransform = ‘translate3d(0, 0, 0)’;
el.style.transform = ‘translate3d(0, 0, 0)’;
let inner = el.getElementsByClassName(‘inner-hook’)[0];
inner.style.webkitTransform = `translate3d(0,0,0)`;
inner.style.transform = `translate3d(0,0,0)`;
setTimeout(() => {//原本afterEnter函数里的代码搬到这里执行,算好动画结束后setTimeout执行就可以了
let ball = this.dropBalls.shift();
if (ball) {
ball.show = false;
el.style.display = ‘none’;
}
clearTimeout();
}, 400);
});
}
}
css:
.ball-container
.ball
position: fixed;
left: 32px;
bottom: 32px;
z-index: 200;
// y轴 贝塞尔曲线
&.drop-enter-active
transition: all 0.4s cubic-bezier(0.5, -0.3, 0.8, 0.3);
// 内层做横向运动
.inner
width: 16px;
height: 16px;
border-radius: 50%;
background-color: rgb(0, 160, 220);
// x轴只要线性缓动
transition: all 0.4s linea