先来看下效果图:
实现起来也不算麻烦,只是其中有些需要仔细思考的地方——必要时要拿到console里打印一下看看!
需要一个“盒子”——包裹“运动的小球”,或者说:固定小球(最终&初始)位置。
则其HTML结构应如下:
<cube-scroll class="rightpanels">
<ul>
<li v-for="(tag,index) in tags" :key="index">
<img :src="tag.image" alt="" />
<i class="cubeic-add" @click="addtocart($event,tag)"></i>
</li>
</ul>
</cube-scroll>
<div class="ball-wrap">
<transition
@before-enter="beforeEnter"
@enter="enter"
@afterEnter="afterEnter"
>
<div class="ball" v-if="ball.show">
<div class="inner">
<i class="cubeic-add"></i> <!-- 添加的小球图标 -->
</div>
</div>
</transition>
</div>
其JS实现“小球的运动”以及“是否显示”:
export default{
data(){
return{
ball:{
show:false,
el:''
}
}
},
methods:{
addtocart(e,tag){
//必须触发“重绘”
document.body.offsetHeight
//...
this.ball.show=true
this.ball.el=e.target
},
beforeEnter(el){
const dom=this.ball.el
const rect=dom.getBoundingClientRect() //获取点击的dom位置
const x=rect.left-window.innerWidth*0.7
const y=-(window.innerHeight-rect.top) //x和y都是负的
//el明显是指“运动的小球”——这三个函数都是绑定在“小球”上的
el.style.display='block'
el.style.transform=`translate3d(0,${y}px,0)`
const inner=el.querySelector('.inner')
inner.style.transform=`translate3d(${x}px,0,0)`
},
enter(el,done){
el.style.transfoem=`translate3d(0,0,0)`
const inner=el.querySelector('.inner')
inner.style.transform=`translate3d(0,0,0)`
//过渡完成后执行的事件
el.addEventListener('transitionend',done)
},
afterEnter(el){
this.ball.show=false
el.style.display='none'
}
}
}