小程序商品飞入购物车组件

wxml

<view class="fly-ball"
      hidden="{{ hidden }}"
      animation="{{ animation }}"
      style="top:{{ top }}px;left:{{ left }}px"></view>

wxss

.fly-ball {
    width: 30rpx;
    height: 30rpx;
    position: fixed;
    border-radius: 100%;
    z-index: 100;
    background: red;
    top: 200px;
    left: 10px;
    display: block;
    box-shadow: 0 1px 1px #000, 0 0 3px #fff inset;
}

JS

import { bezier } from "../../utils/util";

const app = getApp()

Component({
    /**
     * 组件的属性列表
     */
    properties: {},

    /**
     * 组件的初始数据
     */
    data: {
        loading: false,  // 动画是否进行中
        animation: {},
        hidden: true,
        top: 0,
        left: 0
    },

    /**
     * 组件的方法列表
     */
    methods: {

        // 动画
        ballAnimation(e) {

            // 节流
            if (this.data.loading) {
                return
            }

            let topPoint = {},
                finger = {},
                busPos = {
                    x: 250,
                    y: app.globalData.screenHeight
                }

            finger.x = e.touches[0].clientX  // 点击的位置
            finger.y = e.touches[0].clientY

            this.setData({
                top: finger.y,
                left: finger.x,
                hidden: false,
                loading: true
            })

            // 控制点y值定在低的点上方250px处
            if (finger.y < busPos.y) {
                topPoint.y = finger.y - 250
            } else {
                topPoint.y = busPos.y - 250
            }

            // 控制点确保x在点击点和购物车间
            if (finger.x > busPos.x) {
                topPoint.x = (finger.x - busPos.x) / 2 + busPos.x
            } else {
                topPoint.x = (busPos.x - finger.x) / 2 + finger.x
            }

            let linePos = bezier([busPos, topPoint, finger], 10),
                startPoint = linePos[linePos.length - 1]

            let animation = wx.createAnimation({
                duration: 40
            })

            for (let i = linePos.length - 1; i >= 0; i--) {

                // 根据坐标值逐个计算各点的translate
                let startPointX = startPoint.x,
                    startPointY = startPoint.y,
                    nextPointX = linePos[i].x,
                    nextPointY = linePos[i].y,
                    x = nextPointX - startPointX,
                    y = nextPointY - startPointY,
                    scale = 1

                if (i < 2) {
                    scale = 0.6
                }

                animation.translateX(x).translateY(y).scale(scale).step()
            }

            this.setData({
                animation: animation.export()
            })

            setTimeout(() => {

                this.setData({
                    loading: false,
                    animation: {
                        actions: [{
                            animates: [{ type: "translateX", args: [0] }, {
                                type: "translateY",
                                args: [0]
                            }, { type: "scale", args: [0, 0] }],
                            option: {
                                transition: { duration: 0 }
                            }
                        }]
                    }
                })
            }, 800)
        }
    }
})

小程序商品飞入购物车组件

上一篇:OrchardCore Headless建站


下一篇:Python::OS 模块 -- 简介