+
95
-

回答

原理就是记录下购买按钮点击的位置x.y,然后通过新建小球组件来播放css的动画,结束后给父组件一个回调即可。

点击页面记录一下点击的位置并显示小球:

// 购买页面点击事件 buy.js
buy(event){
  this.setData({
    "position.startX": event.touches[0].clientX,
    "position.startY": event.touches[0].clientY,
    showBall: true
  });
}
// buy.wxml

新建一个组件 animationBall.wxml

// animationBall.wxml

<view bindanimationend="observeAnimation" class="ball-box animationBall" wx:if="{{showBall}}" style="{{style}}">
</view>

// animationBall.wxss
.ball-box {
  width: 20rpx;
  height: 20rpx;
  border-radius: 100%;
  position: fixed;
  z-index: 10;
  left: var(--startX);
  top: var(--startY);
}
//y轴位移:小球先有一小段的上升,上升到最高点,这一段y轴位移一直在增加,我们给它动画叫做throwTopY,接下来抛物线下降,这个过程y轴一直在减少,一直减少到我们终点为止,我们叫做throwDropY。
@keyframes throwTopY {
  0% {
    top: var(--startY);
  }
  100% {
    top: calc(var(--startY) - 120rpx);
  }
}
@keyframes throwDropY {
  0% {
    top: calc(var(--startY) - 120rpx);
  }
  100% {
    top: var(--endY);
  }
}
//x轴位移:小球x轴的位移在整个运动过程中都是从右向左变化的,我们认为一直是在线性变化的,我们动画称为throwX。

@keyframes throwX {
  0% {
    left: var(--startX);
  }
  100% {
    left: var(--endX);
  }
}
//小球大小:小球大小在整个过程中,上升阶段是变大的,我们称为scaleTop, 当下降的时候小球一直在变小,称为scaleDrop。

// animationBall.wxss
@keyframes scaleSize {
  0% {
    width: 20rpx;
    height: 20rpx;
  }
  100% {
    width: 10rpx;
    height: 10rpx;
  }
}
//小球透明度:小球的透明度在初始阶段时候是能看到的,然后再接下来的过程是慢慢变成透明,直到完全透明,我们称showAndHide

@keyframes showAndHide {
  0% {
    opacity: 1;
  }
  90% {
    opacity: 0.9;
  }
  100% {
    opacity: 0;
  }
}
.animationBall {
  animation-fill-mode: forwards;
  animation: throwTopY 0.2s cubic-bezier(0, 0.3, 0.3, 1) forwards, 
             scaleTop 0.2s cubic-bezier(0.48, 0.33, 0.24, 1.18) forwards, 
             throwDropY 0.3s cubic-bezier(0.7, 0, 1, 0.7) 0.2s forwards,
             scaleDrop 0.3s cubic-bezier(0.48, 0.33, 0.24, 1.18) 0.2s forwards, 
             throwX 0.46s linear forwards, 
             showAndHide 0.5s linear forwards;
}
// animationBall.js
Component({
  properties: {
    showBall: {
      type: Boolean,
      value: false
    },
    position: {
      type: Object,
      value: {
      }
    }
  },
  observers: {
    "position.startX, position.startY": function(startX, startY) {
      let style = `--startX:${startX}px;--startY:${startY}px;--endX: 15vw;--endY: 92vh`;
      this.setData({
        style
      });
    }
  },
 methods: {
    observeAnimation(res) {
    // 最后一组动画结束 抛出事件通知外部
     if (res.detail.animationName === "showAndHide") {
       this.triggerEvent("animationHasDone");
    }
  }
}
});

网友回复

我知道答案,我要回答