美团加购动画(vue3)

在这里插入图片描述

重点:抛物线:父子盒子,父盒子x轴水平匀速运动,子盒子y轴贝塞尔曲线运动

html

<template>
  <div class="cart">
    <div v-for="(item,idx) in goodList" :key="idx" class="item">
      <img
        class="item-image"
        src="https://img0.baidu.com/it/u=2020518972,2077284106&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1702400400&t=2b15baf23601a38e228295ef16ef03c1"
       
      />
      <div class="item-content"> 
        <div class="item-content-title">{{ item.name }}d大家为吉德科娃监</div>
        <div class="item-content-btm">
          <div class="item-content-btm-quan">{{ item.quantity }}</div>
          <div class="item-content-btm-add" @click="handelAdd" >
            +
          </div>
        </div>
      </div>
    </div>
    <div class="cart-box">  
      <div class="cart-title" ref="cartRef">购物车</div>
    </div>
    <!-- <div class="add" style="--left:300px;--top:100px;--y:500px;--x:-200px">
            <div class="add-icon">+</div>  
          </div> -->
  </div>
</template>

js

<script setup>
import { reactive,ref } from "vue";

const goodList = reactive([{name:123,quantity:123},{name:123,quantity:123},{name:123,quantity:123},{name:123,quantity:123},])
const cartRef = ref(null)
function handelAdd(e){
  //创建icon
  const div = document.createElement('div')
  div.className = 'add'
  div.innerHTML = '<div class="add-icon">+</div>'
  //点击按键并获取icon初始化位置
  const target = e.target
  const btnRect = target.getBoundingClientRect()
  console.log(btnRect,e)
  const left = btnRect.left + btnRect.width / 2 - 10
  const top = btnRect.top  - 10
  div.style.setProperty('--left',left+'px')
  div.style.setProperty('--top',top+'px')
  // 获取icon的结束位置  
  const cartRect = cartRef.value.getBoundingClientRect()
  const x = cartRect.left + cartRect.width / 2 - 10 - left
  const y = cartRect.top - 10 - top
  div.style.setProperty('--x',x+'px')
  div.style.setProperty('--y',y+'px')
  //动画结束移除
  div.addEventListener('animationend',()=>{
    div.remove()
  })
  document.body.appendChild(div)

}
</script>

css

<style lang="scss" >
.cart{
  width: 100%;
  background: #f5f5f5;
  height: 100vh;
  padding: 16px;
  box-sizing: border-box;

}
.item{
width: 100%;
margin-bottom: 16px;
background: #fff;
border-radius: 10px;
padding: 8px;
box-sizing: border-box;
display: flex;
  &-image {
  width: 60px;
  height: 60px;border-radius: 12px;
  margin-right: 8px;
}
&-content{
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  &-title{
    font-size: 14px;
    color: #333;
    margin-bottom: 4px;
  }
  &-btm{
    display: flex;
    justify-content: space-between;
    &-quan{
      font-size: 14px;
      color: #333;
      }
      &-add{
        margin-right: 10px;
        font-size: 19px;
        border: #ccc 1px solid;
        color: #ccc;
        border-radius: 50%;
        width: 20px;
        height: 20px;
        text-align: center;
        line-height: 16px;
      }
  }
}

}
.cart-box{
  width: 100%;
  position: fixed;
  left: 0;right: 0;
  bottom: 0;
  background: #fff;
}
.cart-title{
  background: lightcoral;
  color: #333;
  font-size: 18px;
  font-weight: 600;
  padding: 20px;
  width: 60px;
  text-align: center;
}
.add{
  width: 30px;
  height: 30px;
  border-radius: 50%;
  position: fixed;
  left: var(--left);
  top:var(--top);
  // border: 2px solid #333;
  
}
.add-icon{
    color: #fff;
    width: 100%;
    height: 100%;
    text-align: center;
    line-height: 28px;
    background: orange;
    border-radius: 100%;
  }
@keyframes moveY {
  to{
    transform: translateY(var(--y));
  }
}

.add{
  --duration:0.8s;
  animation: moveX var(--duration) linear;
}

@keyframes moveX {
  to{
    transform: translateX(var(--x));
  }
}

.add-icon{
  animation: moveY var(--duration) cubic-bezier(0.5,-0.5,1,1);
}
</style>
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值