加入购物车动画(贝塞尔曲线)

此文乃搬运后整理,如有侵权立删.

原文为一个小球,但存在连续点击时小球的运动重新开始,所以我在搞懂原理后 改为五个小球循环使用,这样在连续点击时小球的运动不会终止

index.vue

<template>
        //五个小球循环使用,可连续点击
        <view class="cart-item-elc" :style="{item..left+'px',item..top+'px'}" v-show="item.isCartIcon" :key="index" v-for="(item,index) in carIconList "></view>
</template>

<script>
    import utils from "../../static/js/utils";
    var carIconData=uni.getStorageSync('carIconData')
    var carIconIndex=0
    export default {
        data(){
            return {
               carIconList : [
                  {isAnimate: true,isCartIcon: false, timer: null,left: 0, top: 0, bezierPos: null},
                  {isAnimate: true,isCartIcon: false, timer: null,left: 0, top: 0, bezierPos : null},
                  {isAnimate: true, isCartIcon: false, timer: null,left: 0, top: 0, bezierPos : null},
                  {isAnimate: true,isCartIcon: false, timer : null,left: 0, top: 0, bezierPos : null},
                  {isAnimate: true,isCartIcon: false, timer: null,left: 0,top: 0, bezierPos : null}
                ]
            }
        },
        onshow(){
           //isEmpty是一个判断非空的函数
            if (utils.isEmpty(cartlconData)){
                 uni.createSelectorQuery().select(".count").boundingClientRect(res =>{
                    cartIconData= [res.left, res.top]
                    uni.setStorageSync('cartIconData', cartIconData)
                }).exec()
            }
        },
        methods:{
            //加入增加数量并加入购物车
            incAmount(e,index,index2,gid){
               if (carIconindex == 5) {
                  carIconIndex = 1
              } else {
                  carIconIndex++
              }
              var index = carIconIndex - 1
              this.carIconList[index].left = e.detail.x; 
              this.carIconList[index].top = e.detail.y;
              this.carIconList[index].bezierPos = util.bezier([{
                x: this.carIconList[index].left, y: this.carIconList[index].top}, { x: this.carIconList[index].left - 100, y: 120 },{x: carticonData[o],y: cartIconData[1]}], 8);
              this.carIconList[index].isCartIcon = true; 
              this.startAnimation(index);
            },
            //开始动画
            startAnimation(){
               let bezier_points = this.carIconList[index].bezierPos['bezier_points']; let indexs = 0;
               this.cartIconAni = true
               this.carIconList[index].timer = setInterval(() => {
                    indexs++;
                    this.carIconList[index].left = bezier_points[indexs]["x"];             
                    this.carIconList[index].top = bezier_points[indexs]["y"];
                  //动画完成
                  if (indexs >= 7) {
                     clearInterval(this.carIconList[index].timer);                 
                     this.carIconList[index].isAnimate = true;
                     this.carIconList[index].isCartIcon = false;
                     this.cartIconAni = false
                  }
               }, 8)
            },
        }
    }
</script>

<style scoped>
    .cart-item-elc{width:20rpx;height:20rpx;background-color:#ff2400;position:absolute;left:0px;top:0px;border-radius: 100%;z-index:100;}
</style>

utils.js

function bezier(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的坐标。
    // 邻控制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);
    // E每次在BC方向上移动的距离
    const EACH_MOVE_BE = -(DIST_BC / times);
    // 点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;
        // 此时DF点的坐标
        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);
    }
    return {
        'bezier_points': bezier_points
    };
}
export default {
    bezier
}
  • 1
    点赞
  • 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、付费专栏及课程。

余额充值