The opening

As a 2C order small program, the product manager said to make an animation to add to the shopping cart, the first habit is to find a solution online: Bessel algorithm +setInterval=>setData.

The body of the

A small pit

A short time after the launch, there was a negative calculation of the total price added to the shopping cart, as well as inaccurate calculation, HMM. These include the loss of key action setData during frequent setData animations and the addition of duplicate goods.

Official animation support from applets

  • Simple interface animation:
    • Use CSS gradients and CSS animations to create simple interface animations.
    • Wx. createAnimation interface to dynamically create simple animation effects
  • Advanced animation
    • WXS response events (Note: Base library requirements above 2.4.4)

The WXS base library for responding to events was somewhat demanding and was abandoned.

Online community

Bessel curve algorithm + setInterval=>setData


function bezier(points, part) {
  let sx = points[0] ['x'];
  let sy = points[0] ['y'];
  let cx = points[1] ['x'];
  let cy = points[1] ['y'];
  let ex = points[2] ['x'];
  let ey = points[2] ['y'];
  var bezier_points = [];
  // Each increment of x and y from the starting point to the control point
  var changeX1 = (cx - sx) / part;
  var changeY1 = (cy - sy) / part;
  // Each increment of x and y from control point to end point
  var changeX2 = (ex - cx) / part;
  var changeY2 = (ey - cy) / part;
  // loop calculation
  for (var i = 0; i <= part; i++) {
    // Compute the coordinates of the two moving points
    var qx1 = sx + changeX1 * i;
    var qy1 = sy + changeY1 * i;
    var qx2 = cx + changeX2 * i;
    var qy2 = cy + changeY2 * i;
    // Compute a point on the Bezier curve at this point
    var lastX = qx1 + ((qx2 - qx1) * i) / part;
    var lastY = qy1 + ((qy2 - qy1) * i) / part;
    // Save the point coordinates
    var point = {};
    point['x'] = lastX;
    point['y'] = lastY;
    bezier_points.push(point);
  }
  //console.log(bezier_points)
  return {
    bezier_points
  };
}

Copy the code

And then setInterval

Optimization scheme

Synthesize Bezier curve and Wx. createAnimation

method:{
   touchOnGoods(e) {
      // If good_box is moving
      if (!this.data.hide_good_box) return;
      const { touches } = e;
      const topPoint = {};

      this.finger = {
        x: touches[0].clientX,
        y: touches[0].clientY
      };

      topPoint['y'] =
        this.finger['y'] < this.busPos['y']?this.finger['y'] - 150
          : this.busPos['y'] - 150;

      topPoint['x'] =
        this.finger['x'] > this.busPos['x']? (this.finger['x'] - this.busPos['x') /2 + this.busPos['x']
          : (this.busPos['x'] - this.finger['x') /2 + this.finger['x'];

      const result = bezier([this.finger, topPoint, this.busPos], 25);
      this.startAnimation(result);
    },
    startAnimation(linePos) {
      const { bezier_points } = linePos;
      const len = bezier_points.length - 1;
      const first = bezier_points.shift();
    // Prevent animation from not working
    // The same button animation, the animation starts before the element position
      this.setData(
        {
          hide_good_box: false.initLeft:first.x,
          initTop:first.y,
          animationData: this.animation.export()
        },
        () => {
          bezier_points.forEach((i, idx) = > {
            this.animation
              .left(i.x)
              .top(i.y)
              .rotate(50)
              .step({ duration: 25 });
          });
          this.setData({
            animationData: this.animation.export() }); });// There is a bug where the animation does not come out after continuous clicking
      setTimeout((a)= > {
        this.setData({ hide_good_box: true });
      }, len * 20 + 100);
    }
  },
  ready() {
    this.busPos = { x: 50.y: 601 };
    // There was a problem with calling the synchronization interface
    this.busPos.y = util.getSysInfo().windowHeight - 66;

    this.animation = wx.createAnimation({
      timingFunction: 'ease-in'.delay: 0.duration: 1000
    });
  }
// A little lazy, directly paste source code
Copy the code
<view class="good_box" hidden="{{hide_good_box}}" style="left:{{initLeft}}px; top:{{initTop}}px" animation="{{animationData}}"></view>
<view bindtap="touchOnGoods">
  <slot></slot>
</view>
Copy the code

At the end

In fact, a good solution would be to exclude low-end phones, especially Android phones, to enable animation. I have no other good idea for the time being, because I seldom engage in animation and lack experience. There are many friends in the same company.