整体思路
- 设置触发动画效果的点击元素,点击将
$event
传递过去,方便得到target
- 添加多个小球
ball
,且定义小球的运动函数。
样例实现
-
添加小球
<div class="ball-container"> <div v-for="ball in balls"> <!--用了两种方式的动画,css和js钩子--> <transition name="drop" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"> <!--外层动画--> <div class="ball" v-show="ball.show"> <!--内层动画--> <div class="inner inner-hook"></div> </div> </transition> </div> </div>
-
小球动画样式和贝塞尔曲线
.ball-container .ball { position: fixed; left: 32px; bottom: 22px; z-index: 200; transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41); } .ball-container .inner { width: 16px; height: 16px; border-radius: 50%; background: rgb(0, 160, 220); transition: all 0.4s linear; }
-
添加触发小球运动的点击元素
<img src="#" alt="" @click="shopPlus($event)"/>
-
小球运动的函数
// el 为第三步点击传递的元素 event drop(el) { //触发一次事件就会将所有小球进行遍历 for (let i = 0; i{y}px, 0)` el.style.transform = `translate3d(0, {y}px, 0)` // 处理内层动画 let inner = el.getElementsByClassName('inner-hook')[0] // 使用inner-hook类来单纯被js操作 inner.style.webkitTransform = `translate3d({x}px, 0, 0)` inner.style.transform = `translate3d({x}px, 0, 0)` } } }, enter(el, done) { let rf = el.offsetHeight; //触发重绘html this.nextTick(() => { //让动画效果异步执行,提高性能 el.style.webkitTransform = 'translate3d(0,0,0)'; el.style.transform = 'translate3d(0,0,0)'; //处理内层动画 let inner = el.getElementsByClassName('inner-hook')[0]; //使用inner-hook类来单纯被js操作 inner.style.webkitTransform = `translate3d(0,0,0)`; inner.style.transform = `translate3d(${145}px,0,0)`; el.addEventListener('transitionend', done); //Vue为了知道过渡的完成,必须设置相应的事件监听器。 }); }, afterEnter(el) { let ball = this.dropBalls.shift(); //完成一次动画就删除一个dropBalls的小球 if (ball) { ball.show = false; el.style.display = 'none'; //隐藏小球 } },
参考文档:
https://www.jianshu.com/p/c5e4b49b4f2d