实现
实现逻辑:
- 点击添加购物车按钮时,获取当前点击位置
event
的clientX
、clientY
; - 动态创建移动的小球,动态计算小球需要移动到的位置(通过
ref
的getBoundingClientRect
获取统计元素按钮位置); - 计算小球最后的移动位置,并在移动到后移除元素
- 小球动画移动结束后,添加统计数字。
统计按钮
<el-button ref="lableBtnRef" @click="handleChangeStep('0')" :class="currentStep == '0' ? 'linear-btn' : ''" class="normal-btn " size="mini">
<i class="index-circle">1</i>标签选择
<el-badge :value="cartShopList.length" class="item">
<i class="lg-icon white-cart"></i>
</el-badge>
</el-button>
点击加入购物车
按钮:
//点击加入购物车事件
async hadnleSelect(event, item) {
const x = event.clientX - 20;
const y = event.clientY - 20;
await this.createBall(x, y)
//等动画执行完再添加个数
this.cartShopList.push(item)
},
//动态创建加入购物车的元素,和动画
createBall(left, top) {
return new Promise(reslove => {
const bar = document.createElement("ball");
let lableBtn = this.$refs.lableBtnRef.$el
let rect = lableBtn.getBoundingClientRect() //获取统计按钮位置
let size = [lableBtn.clientWidth, lableBtn.clientHeight] //统计按钮本身高、宽
const afterX = rect.x + size[0] / 2 //计算小球最后的位置x
const afterY = rect.y - (size[1] / 2)//计算小球最后的位置Y
bar.classList = ['cartBall']
bar.style.position = "fixed";
bar.style.left = left + "px";
bar.style.top = top + "px";
bar.style.zIndex = '9999'
bar.style.transition =
"left .6s linear, top .6s cubic-bezier(0.5, -0.5, 1, 1)";
document.body.appendChild(bar);
setTimeout(() => {
const x = afterX;
const y = afterY;
bar.style.top = y + "px";
bar.style.left = x + "px";
}, 0);
bar.ontransitionend = function () {
this.remove();
reslove()
};
})
}
//创建的小球的样式
<style>
.cartBall {
width: 20px;
height: 20px;
border-radius: 50%;
z-index: 99;
background: url(~@/assets/img/labelManage/sopCart.svg) center /100% no-repeat;
}
</style>