网上非常多的案列,在这里我就抄过来,能用基本就达到目的了
CartAnim.vue ,直接就是这个组件,我都复制好了
<template>
<div class="ball-container">
<transition-group
name="drop"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
>
<div class="ball" v-for="(ball,index) in balls" v-show="ball.show" :key="index">
<div class="inner inner-hook"></div>
</div>
</transition-group>
</div>
</template>
<script>
export default {
name: "cartAnim",
data() {
return {
// 使用balls存放5个小球,这些小球的默认状态都是不显示
// 为什么是5个 不是3个 4个
// 这里的意思是在一瞬间可以点多少次'+'号,5个差不多就够了,3个太少了,作为多年的程序员来说瞬间点3下轻而易举
balls: [
{ show: false },
{ show: false },
{ show: false },
{ show: false },
{ show: false }
],
dropBalls: [] // 存放掉落的小球
};
},
methods: {
drop(el) {
// console.log(el);
//遍历小球,找到show为false的小球
for (let i = 0; i < this.balls.length; i++) {
let ball = this.balls[i];
if (!ball.show) {
ball.show = true;
ball.el = el; //用小球的el对象保留这个element
this.dropBalls.push(ball);
return;
}
}
},
beforeEnter: function(el) {
/*el是小球;
遍历所有show为true的小球*/
let count = this.balls.length;
while (count--) {
let ball = this.balls[count];
if (ball.show) {
let rect = ball.el.getBoundingClientRect(); //获得该元素(加号)相对于视口的位置的偏移(left,top)
// 在这里我要去掉屏幕路宽度50%;
let x = rect.left - window.innerWidth / 2;
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: function(el) {
let rf = el.offsetHeight; //必须重绘,再进行transform才有用
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)";
});
},
afterEnter: function(el) {
let ball = this.dropBalls.shift();
if (ball) {
ball.show = false;
el.style.display = "none";
}
}
}
};
</script>
<style scoped lang="scss">
.ball-container {
.ball {
position: fixed;
left: 50%;
// 这个不变,减去22px;
bottom: 22px;
width: 16px;
height: 16px;
z-index: 200;
.inner {
width: 16px;
height: 16px;
border-radius: 50%;
// background: rgb(0, 160, 220);
background: red;
}
&.drop-enter-active,
&.drop-leave-active {
transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41);
.inner {
transition: all 0.4s linear;
}
}
}
}
</style>
About.vue(在这里我用到了一个全局的辅助函数)
<template>
<div class="about">
<div id="nav">
<router-link to="/">Home</router-link>|
<router-link to="/about">About</router-link>
<p>create ....</p>
<el-button id="c1" @click="add($event)">++</el-button>
</div>
</div>
</template>
<script>
import CartAnim from "@/components/CartAnim";
import createApi from "@/utils/createApi";
export default {
components: {
CartAnim
},
methods: {
add(event) {
// 动态的create CartAnim
this.$nextTick(() => {
var comp = createApi(CartAnim);
comp.drop(event.target);
});
}
}
};
</script>
<style >
.hello {
display: block;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
font-size: 16px;
right: 0;
top: 30px;
position: fixed;
}
#c1 {
display: block;
position: fixed;
right: 20px;
}
</style>
运行结果:
我们可以看到小球动了,没多大问题,假如我们想修改小球位置
1 和2 处要分别修改
我给大家修改到左下角
行,运行如下:
行,要用到小球动画,你就复制copy 改改就行了