小程序实现购物车商品飞入效果-贝塞尔曲线动画

本文介绍了一种使用CSS3 cubic-bezier()函数和JavaScript在小程序中实现购物车图标上小球抛物线运动的方法。通过封装函数处理点击事件,结合定时器控制动画频率,并详细给出了WXML、CSS和JS代码示例,适用于原生小程序环境。
摘要由CSDN通过智能技术生成

看过很多文章,几乎都是JS计算,控制三个点实现,对我菜鸟的我来说太难了,我这边是用来position+CSS3 cubic-bezier() 函数,既然是分享,我会尽量贴完整代码,害,有的博客,没头没尾,不适合我这种菜鸡,希望能帮到需要的小伙伴

1、我这边不实现可以连续点击球体抛物线效果,通过定时器控制点击的频率,这个代码可以通用,没什么限制,不考虑IE啥的兼容鬼问题。
2、我是原生小程序,里面调用了 wx.createSelectorQuery().in(this).select(cls).boundingClientRect(rect => { }).exec();获取底部购物车的位置,如果是vue或者react 可以通过ref获取组件实例信息,这个具体看自己怎么调用了

WXML

 <!-- 购物车添加-加号 -->
<view class="addImg_box" bindtap="handleAddFood" data-food="{{item}}">
 <image class="img-add " src="{{fileUrl+'banner/details/add.png' }}" lazy-load="{{true}}"></image></view>

<!-- 购物车贝塞尔曲线运动,球体 -->
<view wx:if="{{ballDisplay}}" id="ball" style="top:{{ballTop}};left:{{ballLeft}}"></view>

<!-- tabbar栏 -->
  <view class="position-tab">
    <view class="tab-icon">
      <view class="tab-icon-box">
        <view class="tab-icon-item" bindtap="handleTabEvent" data-index="1">
          <van-icon name="service" color="#515151" size="20px" />
          <text class="text">客服</text>
        </view>
        <view class="tab-icon-item"  id="tab-cart" bindtap="handleTabEvent" data-index="2">
        <!-- 这是我的购物车图标位置,fiexd-cart-animate是购物车放大动画 -->
          <van-icon class="{{cartScale?'fiexd-cart-animate':'' }}" name="cart" wx:if="{{!popupShow}}" color="#383637" size="20px" info="{{allIFoodNum}}" />
          
          <van-icon name="cart" wx:else="{{popupShow}}" color="#ffd027" size="20px" info="{{allIFoodNum}}" />
          <text class="text {{ popupShow?'tab_active':''}}">已选</text>
        </view>
      </view>
    </view>
    <view class="tab-subscribe">立即预约
      <view class="tab-bottom">
        <button hover-class="button-active" class="tab-bottom-btn" open-type="getUserInfo" bindgetuserinfo="handlePurchase"></button>
      </view>
    </view>
  </view>

CSS

/* 购物车抛物线  这里只涉及球体的css,贝塞尔曲线动画的css,还有购物车放大的效果,其他布局自由发挥 */
#ball{
  position: fixed;
  width:30rpx;
  height:30rpx;
  background-color: red;
  border-radius: 50%;
  z-index:99999 !important;
  /* cubic-bezier(.27,-.27,.36,1.04) 这个是关键css代码,第二个值是负数,实现回弹效果,具体自己调试 */
  transition: 0.5s top cubic-bezier(.27,-.27,.36,1.04), 0.5s left cubic-bezier(.29,.68,.64,1);
}
.fiexd-cart-animate{
  animation: aCartScale 300ms cubic-bezier(.17,.67,.83,.67);
  animation-fill-mode: backwards;
}

@keyframes aCartScale{
  0%{
    -webkit-transform: scale(1.15);
  }
  100% {
    -webkit-transform: scale(1);
  }
}

JS部分

data:{
    ballDisplay: false,//控制球体显示
    ballTop: 100,//球体的top值
    ballLeft: 0,//球体的left值
    originTop: 0,//保留原位置top,其实可以简化掉,暂时不操作,小伙伴看着来
    originLeft: 0,//保留原位置left
    start: false,//控制点击购物的频率
    cartScale: false,//控制点击购物车的放大效果
}

//购物车添加事件,部分JS是我的业务逻辑
  handleAddItemFood(e) {
    console.log(e, '添加事件对象');
    //传入当前点击位置的 x y值,起点,封装的函数里面通过wx.createSelectorQuery()获取 购物车图标的重点位置
    let eObj = {
      x: e.touches["0"].clientX,//相对于可视区域的值
      y: e.touches["0"].clientY
    }
    // 禁止动画多次触发
    if (this.data.start) {
      return;
    }
    //当执行完动画效果,再实现购物车图标角标的值计算,当调用完 this.setAnimationBall(eObj),说明动画已经执行完毕
    this.setAnimationBall(eObj).then(() => {
      let obj = e.currentTarget.dataset.food;
      let arr = this.data.checkFoodsItem;
      if (arr.length > 0) {
        let index = this.data.checkFoodsItem.findIndex(v => v.ID === obj.ID);
        if (index == -1) {
          arr.push(obj)
        } else {
          arr[index].num++
        }
      } else {
        arr.push(obj)
      }
      this.setData({
        checkFoodsItem: arr
      })
      this.chcekComputed()
    })
  },



// 购物车抛物线事件封装--------------
  // 获取节点信息-原生小程序的api
  getRects(cls) {
    return new Promise((resolve, reject) => {
      wx.createSelectorQuery().in(this).select(cls).boundingClientRect(rect => {
        resolve(rect);
      }).exec();
    });
  },
  // 初始化球体的位置
  initBallPos() {
    this.setData({
      ballTop: `${100}px`,
      ballLeft: `${270}px`,
      originTop: `${100}px`,
      originLeft: `${270}px`
    });
  },
  //购物车添加事件的球体动画,promise封装是为了球体到了购物车再实现角标数量添加的效果
  setAnimationBall(parmas) {
    return new Promise((resolve, reject) => {
      //防止多次触发
      this.data.start = true;
      //再次初始化 球体点击的当前位置,具体自己根据情况修改值
      this.setData({
        ballTop: `${parmas.y - 10}px`,
        ballLeft: `${parmas.x - 5}px`,
        originTop: `${parmas.y - 10}px`,
        originLeft: `${parmas.x -5}px`,
        cartScale: false,
        ballDisplay: true
      });
      // 获取小球终点位置
      this.getRects("#tab-cart").then(rect => {
        console.log(rect, '小球终点位置');
        let left = Math.floor(rect.left) + Math.floor(rect.width / 2) - 5;
        let top = Math.ceil(rect.top)
        this.setData({
          ballTop: `${top +5}px`,
          ballLeft: `${left}px`
        });
        // 定时器延时跟动画时长一致,飞完隐藏掉,再把小球重置到初始位置。
        let {
          originLeft,
          originTop
        } = this.data;
        setTimeout(() => {
          this.setData({
            ballDisplay: false,
            ballTop: originTop,
            ballLeft: originLeft,
            start: false,//放开频率
            cartScale: true,//球体到购物车图标时,图标放大效果
          });
          resolve()
        }, 500);
      });


    })
  },
//初始化球体的位置
  onReady: function () {
    this.initBallPos()
  },

效果图,小弟不会搞gif。。然后就是这样效果
在这里插入图片描述

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实现加入购物车飞入动画,可以使用贝塞尔曲线来控制动画路径。具体实现步骤如下: 1. 在购买按钮点击事件中,获取购买按钮的位置和购物车图标的位置,并计算出两者之间的距离。 2. 创建一个贝塞尔曲线,控制点设置为购买按钮位置和购物车图标位置的中心点,终点设置为购物车图标位置。 3. 使用CSS3动画或JavaScript来实现动画效果,让购买按钮沿着贝塞尔曲线飞入购物车。 下面是一个简单的实现示例: ```html <template> <div> <button @click="addToCart">加入购物车</button> <div class="cart-icon"></div> <div class="ball"></div> </div> </template> <script> export default { methods: { addToCart() { const button = document.querySelector('button') const cartIcon = document.querySelector('.cart-icon') const ball = document.querySelector('.ball') const buttonRect = button.getBoundingClientRect() const cartIconRect = cartIcon.getBoundingClientRect() const deltaX = cartIconRect.left - buttonRect.left const deltaY = cartIconRect.top - buttonRect.top const controlPointX = (buttonRect.left + cartIconRect.left) / 2 const controlPointY = buttonRect.top - 100 ball.style.left = buttonRect.left + 'px' ball.style.top = buttonRect.top + 'px' const bezierPath = `M${buttonRect.left},${buttonRect.top} Q${controlPointX},${controlPointY} ${cartIconRect.left},${cartIconRect.top}` ball.animate( [ { transform: `translate(0,0)` }, { transform: `translate(${deltaX}px, ${deltaY}px)` } ], { duration: 500, easing: 'ease-out', fill: 'forwards' } ) ball.animate( [ { transform: `translate(${deltaX}px, ${deltaY}px)` }, { transform: `translate(0,0)` } ], { duration: 500, easing: 'ease-in', fill: 'forwards', delay: 500 } ) ball.animate( [ { opacity: 1 }, { opacity: 0 } ], { duration: 500, fill: 'forwards', delay: 1000 } ) const path = document.createElementNS('http://www.w3.org/2000/svg', 'path') path.setAttribute('d', bezierPath) path.setAttribute('fill', 'none') path.setAttribute('stroke', 'red') path.setAttribute('stroke-width', '2') document.querySelector('.container').appendChild(path) } } } </script> <style> .cart-icon { position: absolute; top: 20px; right: 20px; width: 50px; height: 50px; background: url('cart.png'); background-size: cover; } .ball { position: absolute; width: 20px; height: 20px; border-radius: 50%; background: red; } .container { position: relative; } </style> ``` 这里使用了CSS3动画和JavaScript动画结合的方式来实现购买按钮飞入购物车效果。在addToCart方法中,首先获取购买按钮和购物车图标的位置,并计算出两者之间的距离。然后根据贝塞尔曲线的控制点计算出贝塞尔曲线路径,并创建一个SVG path元素来显示路径。最后使用CSS3动画和JavaScript动画实现购买按钮沿着贝塞尔曲线飞入购物车效果
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值