<template>
<div class="shopcart">
<div class="content">
<div class="content-left">
<div class="logo-wrapper">
<div class="logo" :class="{'highLight':totalCount > 0}">
<i class="icon-shopping_cart" :class="{'highLight':totalCount > 0}"></i>
</div>
<div class="num" v-if="totalCount>0">{{totalCount}}</div>
</div>
<div class="price" :class="{'highLight':totalCount > 0}">¥{{totalPrice}}</div>
<div class="desc"> 另需配送费¥ {{deliveryPrice}}元</div>
</div>
<div class="content-right">
<div class="pay" :class="payClass">
{{payDesc}}
</div>
</div>
</div>
<div class="ball-container">
<transition-group name="drop" tag="div"
v-on:before-enter="beforeEnter"
v-on:enter="dropEnter"
v-on:after-enter="afterEnter"
>
<div class="ball" v-for="(ball,i) in balls" :key="i" v-show="ball.show">
<div class="inner inner-hook"></div>
</div>
</transition-group>
</div>
</div>
</template>
<script type="text/ecmascript-6">
export default {
name: "shopcart",
props:{
selectFoods:{
type:Array,
default(){
return [
{
price:10,
count:5
}
];
}
},
deliveryPrice:{
type: Number,
default: 0
},
minPrice:{
type: Number,
default: 0
},
},
data(){
return{
balls:[{
show:false
}, {
show:false
},{
show:false
},{
show:false
},{
show:false
},
],
dropBalls:[]
}
},
computed:{
totalPrice(){
let total = 0;
this.selectFoods.forEach((food)=>{
total+=food.price * food.count
});
return total;
},
totalCount(){
let count = 0;
this.selectFoods.forEach(food =>{
count += food.count;
});
return count
},
payDesc(){
if(this.totalPrice === 0){
return ` ¥${this.minPrice}元起送`
}else if(this.totalPrice<this.minPrice){
return `还差${this.minPrice-this.totalPrice}元起送`
}else{
return '去结算'
}
},
payClass(){
if(this.totalPrice<this.minPrice)
return 'not-enough';
else
return 'enough'
}
},
methods:{
drop(el){
for(let i=0;i<this.balls.length;i++){
let ball=this.balls[i];
if(!ball.show){
ball.show=true;
ball.el=el;
this.dropBalls.push(ball);
return;
}
}
},
beforeEnter(el,done){
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);debugger
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)`;
}
}
},
dropEnter(el,done){//球动画完成
debugger
/* eslint-disable no-unused-vars*/
let rf = el.offsetHeight;
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)';
el.addEventListener('transitionend', done);
})
},
afterEnter(el){
debugger
el.style.display='none';
let ball=this.dropBalls.shift();
if(ball){
ball.show=false;
ball.el=null;
}
debugger
}
},
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.shopcart
position: fixed
left: 0
bottom: 0
z-index: 50
width :100%
height: 48px
.content
display: flex
background: #141d27
font-size: 0
color: rgba(255,255,255,0.4)
.content-left
flex: 1
.logo-wrapper
display: inline-block
position: relative
top: -10px
margin: 0 12px
padding: 6px
width: 56px
height: 56px
box-sizing: border-box
vertical-align: top
border-radius: 50%
background: #141d27
.logo
width: 100%
height: 100%
border-radius: 50%
background: #2b343c
text-align: center
&.highLight
background: #00a0dc
.icon-shopping_cart
line-height: 44px
font-size: 24px
color: #80858a
&.highLight
color: white
.num
position: absolute
top: 0
right: 0
width: 24px
height: 16px
line-height: 16px
text-align: center
border-radius: 16px
font-size: 9px
font-weight: 700
color: #fff
background: rgb(240,20,20)
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.4)
.price
display: inline-block
vertical-align: top
line-height: 24px
margin-top: 12px
padding-right: 12px
box-sizing: border-box
border-right: 1px solid rgba(255,255,255,0.1)
font-size: 16px
font-weight: 700
&.highLight
color: white
.desc
display: inline-block
vertical-align: top;
line-height: 24px
margin: 12px 0 0 12px
font-size: 10px
.content-right
flex: 0 0 105px
width: 105px
.pay
height: 48px
line-height: 48px
text-align: center
font-size: 12px
font-weight: 700
&.not-enough
background: #2b333b
&.enough
background: #00b43c
color: #fff
.ball-container
.ball
position: fixed
left: 32px
bottom: 22px
z-index: 200
.inner
width: 16px
height: 16px
border-radius: 50%
background: rgb(0,160,220)
transition: all 1s linear
&.drop-enter-active
transition: all 1s cubic-bezier(0.49,-0.29,0.75,0.41);
/* &.drop-enter
transform: translate3d(0,-400px,0)
.inner
transform: translate3d(300px,0,0)
&.drop-enter-to
transform: translate3d(0,0,0)
.inner
transform: translate3d(0,0,0)
*/
</style>
vue 高仿饿了么 小球动画
最新推荐文章于 2020-06-23 17:50:18 发布