关于小球drop动画的三个问题,期待老师的回答。感谢!
来源:17-17 cartcontrol组件(3)

5942
2019-07-22
老师,您好,跟着您敲了一遍代码,觉得很有收获。关于小球掉落的动画,我有三个问题想请教下老师。先贴上老师的布局代码。
<div class="ball-container">
<div v-for="(ball,index) in balls" :key="index">
<transition
@before-enter="beforeDrop"
@enter="dropping"
@after-enter="afterDrop">
<div class="ball" v-show="ball.show">
<div class="inner inner-hook"></div>
</div>
</transition>
</div>
</div>
第一个问题。每个小球由沿纵轴动画的ball层及沿横轴动画的inner层。在每次动画开始时,ball层translate3d(0,${y}px,0)
,inner层translate3d(${x}px,0,0)
,效果是,ball层往纵轴上移动y个px,inner层在ball纵轴上移动y个px的基础上,在横轴上移动x个px,效果如下图。
按照老师的代码完成后的效果如下图。
其中ball层会沿纵轴运动。老师的项目中没有该现象是因为menu-wrapper盖住了ball层。我想请问下老师,如果该项目中没有menu-wrapper层怎么解决该问题(隐藏运动中的ball层)?
第二个问题。老师在一期的代码中beforeDrop是如下实现的。
beforeDrop(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)`;
}
}
}
我的理解是在快速点击的情况下,每次调用beforeDrop时都会把还没有运动完的小球遍历一遍,然后将其tranform置到(0, 0, 0)的位置,这样做为什么没有问题呢?(后来老师在二期的代码中重构了这段代码,找到dropBalls的最后一个小球做操作,这个很好理解)
3.关于afterDrop中的逻辑
老师的代码是这么做的,我能理解没有问题。
afterDrop(el) {
const ball = this.dropBalls.shift();
if (ball) {
el.style.display = 'none';
ball.show = false;
}
}
但是我在自己重写时没有采用老师的方式,而是按照自己的想法实现(找到所有小球中,第一个show===true,重置为false,为下次准备),如下。
afterDrop(el) {
for (let i = 0; i < this.balls.length; i++) {
const ball = this.balls[i];
if (ball.show) {
el.style.display = 'none';
ball.show = false;
break;
}
}
}
结果在连续快速点击的时候会出现下面的问题。我自己认为逻辑上没有问题,请教下老师,为什么会出现这样的问题。
不好意思,问得太多了,希望老师能有空帮我解释下。再次表示万分感谢!
1回答
-
ustbhuangyi
2019-07-22
1. ball 和 inner 是父子关系,是在一起的,他们表示一个球,纵轴和横轴的移动只是让它有一个抛物线效果。建议你看看这个问题,感觉和你这个类似,里面有我的解决方案
http://coding.imooc.com/learn/questiondetail/129720.html
2. 参考二期重构的代码。
3.连续点击,假设你连续点了四次,前 3 次都是从 balls 中找了前 3 个 show 为 false 的,然后修改为 true,但是第四次的之前,第一个球回来了,这个时候 afterDrop,按你的逻辑,第一个 ball 的 show 变为 false,这个时候点第四次,因为第一个球的 ball 的 show 已经变为 false 了,然后找的第一个球,show 变成了 true,而这个时候第二个球回来了,它本应该找第二个球,但你的逻辑又找到了第一个球,所以逻辑就乱了。而我每次都从 dropBalls 去找,用一个队列存储,先进先出的方式,就避免这个坑了。
00
相似问题