小程序购物车加购动效

二阶贝塞尔曲线 bezier(),在原作者的基础上加了从右向左的曲线计算
app.js

App({
  globalData:{

  },
  onLaunch: function (){

   },

   bezier: function (points, times) {
     // 0、以3个控制点为例,点A,B,C,AB上设置点D,BC上设置点E,DE连线上设置点F,则最终的贝塞尔曲线是点F的坐标轨迹。
     // 1、计算相邻控制点间距。
     // 2、根据完成时间,计算每次执行时D在AB方向上移动的距离,E在BC方向上移动的距离。
     // 3、时间每递增100ms,则D,E在指定方向上发生位移, F在DE上的位移则可通过AD/AB = DF/DE得出。
     // 4、根据DE的正余弦值和DE的值计算出F的坐标。

    // 从左到右,正向;从右到左,负向
    const DIRECTION = (points[2]['x'] - points[0]['x'])/Math.abs(points[2]['x'] - points[0]['x'])
     // 邻控制AB点间距
     var bezier_points = [];
     var points_D = [];
     var points_E = [];
     const DIST_AB = Math.sqrt(Math.pow(points[1]['x'] - points[0]['x'], 2) + Math.pow(points[1]['y'] - points[0]['y'], 2));
     // 邻控制BC点间距
     const DIST_BC = Math.sqrt(Math.pow(points[2]['x'] - points[1]['x'], 2) + Math.pow(points[2]['y'] - points[1]['y'], 2));
     // D每次在AB方向上移动的距离
     const EACH_MOVE_AD = DIST_AB / times * DIRECTION;
     // E每次在BC方向上移动的距离 
     const EACH_MOVE_BE = DIST_BC / times * DIRECTION;
     // 点AB的正切
     const TAN_AB = (points[1]['y'] - points[0]['y']) / (points[1]['x'] - points[0]['x']);
     // 点BC的正切
     const TAN_BC = (points[2]['y'] - points[1]['y']) / (points[2]['x'] - points[1]['x']);
     // 点AB的弧度值
     const RADIUS_AB = Math.atan(TAN_AB);
     // 点BC的弧度值
     const RADIUS_BC = Math.atan(TAN_BC);
     // 每次执行
     for (var i = 1; i <= times; i++) {
       // AD的距离
       var dist_AD = EACH_MOVE_AD * i;
       // BE的距离
       var dist_BE = EACH_MOVE_BE * i;
       // D点的坐标
       var point_D = {};
       point_D['x'] = dist_AD * Math.cos(RADIUS_AB) + points[0]['x'];
       point_D['y'] = dist_AD * Math.sin(RADIUS_AB) + points[0]['y'];
       points_D.push(point_D);
       // E点的坐标
       var point_E = {};
       point_E['x'] = dist_BE * Math.cos(RADIUS_BC) + points[1]['x'];
       point_E['y'] = dist_BE * Math.sin(RADIUS_BC) + points[1]['y'];
       points_E.push(point_E);
       // 此时线段DE的正切值
       var tan_DE = (point_E['y'] - point_D['y']) / (point_E['x'] - point_D['x']);
       // tan_DE的弧度值
       var radius_DE = Math.atan(tan_DE);
       // 此时DE的间距
       var dist_DE = Math.sqrt(Math.pow((point_E['x'] - point_D['x']), 2) + Math.pow((point_E['y'] - point_D['y']), 2));
       // 此时DF的距离
       var dist_DF = (dist_AD / DIST_AB) * dist_DE;
       // 此时F点的坐标
       var point_F = {};
       point_F['x'] = dist_DF * Math.cos(radius_DE) + point_D['x'];
       point_F['y'] = dist_DF * Math.sin(radius_DE) + point_D['y'];
       bezier_points.push(point_F);
     }
     console.log('bezier_points',bezier_points);
     return {
       'bezier_points': bezier_points
     };
   },

})

index.js

//方便引用自身
const app = getApp()
var that
Page({
    data: {
        //购物车x坐标
        animationx: 0,
        //购物车y坐标
        animationy: 0,
        //是否显示飞行物,默认不显示
        showdot: false,
        //动画对象
        ani: {},
        //商品记数
        count: 0
    },
    onLoad(options) {
        that = this
    },
    onReady() {
        //页面渲染完后获取购物车在页面中的坐标
        const query = wx.createSelectorQuery()
        query.select('#shopcar').boundingClientRect()
        query.selectViewport().scrollOffset()
        query.exec(function (res) {
            let point = res[0]
            //坐标修正,让飞行物可以正好落在购物车正中心,20是飞行物宽度一半然后转化成px
            var xtemp = (point.left + point.right) / 2 - 20 / 750 * wx.getSystemInfoSync().windowWidth
            var ytemp = (point.top + point.bottom) / 2 - 20 / 750 * wx.getSystemInfoSync().windowWidth
            console.log('xtemp : ' + xtemp + ' ytemp : ' + ytemp)
            that.setData({
                //获取修正后坐标
                animationx: xtemp,
                animationy: ytemp
            })
        })
    },
    addshopcar(e) {
        // if(that.data.showdot == true){
        //   return
        // }
        //获取点击点坐标
        var touches = e.touches[0]
        //坐标修正,同上,这么做是为了让飞行点落到点击的中心
        let toptemp = touches.clientY - 20 / 750 * wx.getSystemInfoSync().windowWidth
        let lefttemp = touches.clientX - 20 / 750 * wx.getSystemInfoSync().windowWidth
        var animation1 = wx.createAnimation({
            duration: 1,
            timingFunction: 'ease'
        })
        //通过极短的时间让飞行点移动到手指点击位置,同时让飞行点显示出来
        animation1.left(lefttemp).top(toptemp).step()
        // 新方法
        // that.animate('#dot', [
        //     {left:lefttemp+'px',top:toptemp+'px'}
        // ], 1, function () {
        //     that.clearAnimation('#dot', { opacity: true, rotate: true }, function () {
        //       console.log("清除了#container上的动画属性")
        //     })
        // }.bind(that))
        that.setData({
            ani: animation1.export(),
            showdot: true
        })
        let points = [
            {
                x: lefttemp,
                y: toptemp
            },
            {
                x: (lefttemp + this.data.animationx) / 2,
                y: 100
            },
            {
                x: this.data.animationx,
                y: this.data.animationy
            },
        ]
        this.linePos1 = app.bezier(points, 30)['bezier_points'];
        setTimeout(() => {
            this.startAnimation()
        }, 100)

    },
    //开始动画
    startAnimation: function () {
        var index = 0,
            that = this,
            bezier_points = that.linePos1;
        const animation = wx.createAnimation({
            duration: 1,
            timingFunction: 'ease'
        }, )
        let arr = []
        //通过Animation的left和top这两个API,将飞行点移动到购物车坐标处
        bezier_points.forEach(item => {
            animation.left(item.x).top(item.y).step()
            // arr.push({left:item.x+'px',top:item.y+'px'})
        })
        // 新方法
        // that.animate('#dot', arr, 1, function () {
        //     that.clearAnimation('#dot', { opacity: 0, rotate: true }, function () {
        //         console.log("清除了#container上的动画属性")
        //         that.setData({showdot:false})
        //       })
        //   }.bind(that))
        that.setData({
            ani: animation.export()
        })
    },
    animationend(e) {
        console.log(e);
    }


})

index.wxml

<view class="container">
  <view wx:for='12345678901234567' class="item" bindtap="addshopcar" hover-class="hover">商品{{index}}</view>
</view>
<view class="dot" id="dot" animation='{{ani}}' bind:animationend="animationend" hidden="{{!showdot}}">+1</view>
<view class="shopcar" id="shopcar">
  <image src="https://oss.suning.com/nscmfs/nsimg/68205d3e2c084547b5cac8710ffdb094/super-vip.png" class="shopcarimg"></image>
</view>

index.wxss

.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
} 

.item {
  width: 720rpx;
  height: 100rpx;
  display: flex;
  flex-direction: row;
  align-items: center;
  font-weight: bold;
  padding-left: 30rpx;
  border-bottom: 1rpx solid #efeff4;
}

.hover {
  background: #d9d9db;
}

.dot {
  top: 0;
  left: 0;
  position: fixed;
  width: 40rpx;
  height: 40rpx;
  border-radius: 50%;
  background: #1dae01;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  font-size: 24rpx;
  color: white;
}

.shopcar {
  position: fixed;
  right: 200rpx;
  bottom: 100rpx;
}

.shopcarimg {
  width: 48rpx;
  height: 48rpx;
}

.count {
  color: red;
  position: fixed;
  font-weight: bold;
  right: 300rpx;
  bottom: 100rpx;
}

参考文档:https://blog.csdn.net/weixin_43106777/article/details/100693543?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-5.baidujs&dist_request_id=1619682401770_11184&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-5.baidujs

参考文档https://blog.csdn.net/abs625/article/details/105783166/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
js加入购物车抛物线动画购物车效果特效,亲测可用, 当您在电商购物网站浏览中意的商品时,您可以点击页面中的“加入购物车”按钮即可将商品加入的购物车中。本文介绍借助一款基于jQuery的动画插件,点击加入购物车按钮时,实现商品将飞入到右侧的购物车中的效果。 HTML 首先载入jQuery库文件和jquery.fly.min.js插件。 复制代码 代码如下: 接着,将商品信息html结构布置好,本例中,我们用四个商品并排布置,每个商品box中包括有商品图片、价格、名称以及加入购物车按钮等信息。 复制代码 代码如下: ¥3499.00 LG 49LF5400-CA 49寸IPS硬屏富贵招财铜钱设计 加入购物车 ¥3799.00 Hisense/海信 LED50T1A 海信电视官方旗舰店 加入购物车 ¥¥3999.00 Skyworth/创维 50E8EUS 8核4Kj极清酷开系统智能液晶电视 加入购物车 ¥6969.00 乐视TV Letv X60S 4核1080P高清3D安卓智能超级电视 加入购物车 然后,我们还需要在页面的右侧加上购物车以及提示信息。 复制代码 代码如下: 购物车 已成功加入购物车! CSS 我们使用CSS先将商品排列美化,然后设置右侧购物车样式,具体请看代码: 复制代码 代码如下: .box{float:left; width:198px; height:320px; margin-left:5px; border:1px solid #e0e0e0; text-align:center} .box p{line-height:20px; padding:4px 4px 10px 4px; text-align:left} .box:hover{border:1px solid #f90} .box h4{line-height:32px; font-size:14px; color:#f30;font-weight:500} .box h4 span{font-size:20px} .u-flyer{display: block;width: 50px;height: 50px;border-radius: 50px;position: fixed;z-index: 9999;} .m-sidebar{position: fixed;top: 0;right: 0;background: #000;z-index: 2000;width: 35px;height: 100%;font-size: 12px;color: #fff;} .cart{color: #fff;t

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值