关于小球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 去找,用一个队列存储,先进先出的方式,就避免这个坑了。
 

0
0

Vue.js2.5+cube-ui重构饿了么App(经典再升级)

掌握Vue1.0到2.0再到2.5最全版本应用与迭代,打造极致流畅的WebApp

9868 学习 · 4162 问题

查看课程