关于H5 移动端 动态添加购物车动画图 项目vue-ts

项目是关于门店购物商品相关的H5 移动端, 技术栈 vue + ts 项目框架,通过refs 获取dom 会有报错问题,本模块还是通过原生的方式获取dom ,绑定类名最好是ID 标签名。

1 添加动画模块封装:

/** 购物车添加动画效果
 * @param addBtn  开始-源添加按钮 dom对象
 * @param shopCar 目标-购物车库 dom 对象
 * @return controllPath
 */
import { Toast } from "vant";
export const addShopPath = (addBtn: Element | null, shopCar: Element | null, imgUrl?: string | null): void => {
    let addCartDom = addBtn,
        shopCarDom = shopCar;
    // dom类型提示
    if (addBtn instanceof HTMLElement) {
        addCartDom = addBtn;
    } else {
        Toast("第一个参数应为添加按钮的dom元素或该元素的选择器。");
        return;
    }

    if (shopCar instanceof HTMLElement) {
        shopCarDom = shopCar;
    } else {
        Toast("第二个参数应为购物车的dom元素或该元素的选择器。");
        return;
    }
    /*
     * 绘制动画购物车
     * */

    const drawBall = (): any => {
        const ballDom = document.createElement("div");
        ballDom.id = "ballDom";
        ballDom.style.width = "24px";
        ballDom.style.height = "24px";
        // ballDom.style.border = "2px solid pink";
        // ballDom.style.background = "red";
        ballDom.style.borderRadius = "50%";
        // 自定义购物车背景图片
        ballDom.innerHTML =
            '<img width= "100%"' +
            'src="' +
            require("@/assets/images/template/template1/same-city-product-list/cart-animation@2x.png") +
            '"/>';
        // ballDom.style.backgroundSize = "cover";
        // 用于隐藏
        ballDom.style.display = "block";
        ballDom.style.position = "absolute";
        ballDom.style.zIndex = "2300";
        console.log("imgUrl", imgUrl);

        return ballDom;
    };

    // 获取两个dom的位置
    const addCartDomPosition = addCartDom.getBoundingClientRect();
    const shopCartDomPosition = shopCarDom.getBoundingClientRect();
    // 25 目标元素距离边框距离优化 可自定义
    const addBtnDomCenterX = (addCartDomPosition.left + addCartDomPosition.right) / 2 - 25;
    const addBtnDomCenterY = (addCartDomPosition.top + addCartDomPosition.bottom) / 2;
    const shopCarCenterX = (shopCartDomPosition.left + shopCartDomPosition.right) / 2 - 25;
    const shopCarCenterY = (shopCartDomPosition.top + shopCartDomPosition.bottom) / 2;
    //计算增加按钮 是在 相对于购物车的 左边还是右边(用于控制后面的移动方向)
    const relativePosition = addBtnDomCenterX > shopCarCenterX ? -1 : 1;

    // 获取连个dom之间的距离  取正距离
    const xDistance = Math.abs(addBtnDomCenterX - shopCarCenterX);
    const yDistance = Math.abs(addBtnDomCenterY - shopCarCenterY);

    // 绘制小车并设置其位置
    const ballDom = drawBall();
    ballDom.style.top = addBtnDomCenterY + "px";
    ballDom.style.left = addBtnDomCenterX + "px";
    document.body.appendChild(ballDom);
    /*
     * 根据一元二次方程的轨迹求出对象的系数 y = ax^2 + bx + c
     *  var coefficientC = 0;
     *  var coefficientB = 0;
     *  var coefficientA = yDistance / Math.pow(xDistance, 2);
     */
    // 小车的横竖坐标
    let xAbscissa = 0,
        yAbscissa = 0;

    //设置移动路径
    const ballTimer = setInterval(() => {
        //每次重新坐标 pow() 方法表示的是 x 的 y 次幂的值
        xAbscissa += 5 * relativePosition;
        yAbscissa = (yDistance / Math.pow(xDistance, 2)) * Math.pow(xAbscissa, 2);
        ballDom.style.top = addBtnDomCenterY + yAbscissa + "px";
        ballDom.style.left = addBtnDomCenterX + xAbscissa + "px";
        //检查是否到达终点
        const surplusDistance = parseInt(ballDom.style.left) - shopCarCenterX;
        if (Math.abs(surplusDistance) <= 10) {
            clearInterval(ballTimer);
            // 开启隐藏动画图标
            ballDom.style.display = "none";
        }
        //     6 控制动画的响应快慢 ,具体根据实际动画效果修改
    }, 6);
};

2 htm 动态添加dom的id名, 做唯一标识

// 开始位置  
<div
           v-if="row.spec_type === 0"
           :id="`buy-cart${key}`"
           class="add-cart"
           @click.stop="addShopCart(row, key)"
            >
</div>



<div @click="openCard">
     // 目标位置
    <div id="shop-cart" class="left"></div>
 </div>

3 组件引入传参 方式:

    // 请求成功后 动态添加购物车
    addShopCartHandle(key: number | string): void {

        if (key== "true") return; // 其他规格操作无需动画

        // 获取目标对象  由于多个商品列表id名键名拼接 获取唯一对象
        let buyCartName = `#buy-cart${key}`;
        const addCartDom = document.querySelector(buyCartName);
        const shopCartDom = document.querySelector("#shop-cart");
        // 触发添加购物车动画
        addShopPath(addCartDom , shopCartDom );
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值