微信小程序加入购物车动画

最近在做的一个小程序项目,需要一个加入购物车动画,倒腾了一下总算实现了想要的效果。

代码如下(用的是wepy2.x语法):

//wxml
//通过点击事件对象 获取到点击的位置


//红点

//wxss
.good_box {
  width: 30rpx;
  height: 30rpx;
  position: absolute;
  border-radius: 50%;
  overflow: hidden;
  left: 50%;
  top: 50%;
  z-index: 9999;
  background: #fe3c53;
}
//js
data: {
  linePos: null,
  hh: '',
  animation: null,
  bus_x: '',
  bus_y: '',
},
onLoad() {
   this.getContentHeight()
},

onShow() {
    //首先计算购物车的位置
    this.busPos = {};
    this.busPos['x'] = 240; //x轴坐标是固定的
    this.busPos['y'] = this.hh - 19; 
},

methods: {
  getContentHeight() {
    let systemInfo = wx.getSystemInfoSync();
    this.hh = systemInfo.windowHeight;
 },

 onCartAmountChange(goods, index, event) {
  this.tapEvent = event;
  //把事件对象先保存起来,后期加入购物车成功后再用来实现动画
}

//加入购物车成功诗调用
this.touchOnGoods(this.tapEvent)


/*加入购物车动效*/
    touchOnGoods: function(e) {
      this.finger = {};
      var topPoint = {};
      this.finger['x'] = e.touches['0'].clientX; //点击的位置
      this.finger['y'] = e.touches['0'].clientY;

      if (this.finger['y'] < this.busPos['y']) {
        topPoint['y'] = this.finger['y'] - 150;
      } else {
        topPoint['y'] = this.busPos['y'] - 150;
      }
      topPoint['x'] = Math.abs(this.finger['x'] - this.busPos['x']) / 2;

      if (this.finger['x'] > this.busPos['x']) {
        topPoint['x'] =
          (this.finger['x'] - this.busPos['x']) / 2 + this.busPos['x'];
      } else {
        //
        topPoint['x'] =
          (this.busPos['x'] - this.finger['x']) / 2 + this.finger['x'];
      }

      this.linePos = this.bezier([this.busPos, topPoint, this.finger], 30);
      this.startAnimation(e);
    },
    startAnimation: function(e) {
      var index = 0,
        that = this,
        bezier_points = that.linePos['bezier_points'];
      that.hide_good_box = false;
      that.bus_x = that.finger['x'];
      that.bus_y = that.finger['y'];
      var len = bezier_points.length;
      index = len;
      let animation = wx.createAnimation({
        duration: 33,
        timingFunction: 'ease-out'
      });
      animation.opacity(1).step();
      for (let i = index - 1; i > -1; i--) {
        let deltX = bezier_points[i]['x'] - that.finger['x'];
        let deltY = bezier_points[i]['y'] - that.finger['y'];
        animation.translate(deltX, deltY).step();
      }
      animation.opacity(0).step();
      this.animation = animation.export();
    },
//获得了从点击到购物车之间轨迹的点的位置
    bezier: function(pots, amount) {
      var pot;
      var lines;
      var ret = [];
      var points;
      for (var i = 0; i <= amount; i++) {
        points = pots.slice(0);
        lines = [];
        while ((pot = points.shift())) {
          if (points.length) {
            lines.push(pointLine([pot, points[0]], i / amount));
          } else if (lines.length > 1) {
            points = lines;
            lines = [];
          } else {
            break;
          }
        }
        ret.push(lines[0]);
      }
      function pointLine(points, rate) {
        var pointA,
          pointB,
          pointDistance,
          xDistance,
          yDistance,
          tan,
          radian,
          tmpPointDistance;
        var ret = [];
        pointA = points[0]; //点击
        pointB = points[1]; //中间
        xDistance = pointB.x - pointA.x;
        yDistance = pointB.y - pointA.y;
        pointDistance = Math.pow(
          Math.pow(xDistance, 2) + Math.pow(yDistance, 2),
          1 / 2
        );
        tan = yDistance / xDistance;
        radian = Math.atan(tan);
        tmpPointDistance = pointDistance * rate;
        ret = {
          x: pointA.x + tmpPointDistance * Math.cos(radian),
          y: pointA.y + tmpPointDistance * Math.sin(radian)
        };
        return ret;
      }
      return {
        bezier_points: ret
      };
    }
}

实现代码主要参考自这篇文章,主要两点不同。

1.原文中实现动画原理:通过不断去改变fixed定位红点的 top和left值,其中用了setTimeout和setInterval定时器,我拿来用的时候,在安卓中是正常的,IOS没有效果。所以我采用了微信小程序自带的动画API。

2.原文中红点的显示隐藏是通过标签的hidden属性来控制。我用小程序动画API的时候好像有点冲突,所以换成了opacity的值来显示隐藏红点。

你可能感兴趣的:(wepy2.0,微信小程序)