ソースを参照

fix: 修改红包雨动画

Before 7 ヶ月 前
コミット
3158d70bc2

+ 0 - 287
src/app/[locale]/(TabBar)/promo/Popup.tsx

@@ -1,287 +0,0 @@
-"use client";
-
-import { Mask } from "antd-mobile";
-import clsx from "clsx";
-import Image from "next/image";
-import { Fragment, useEffect, useRef, useState } from "react";
-import styles from "./style.module.scss";
-
-const randomX = (len: number) => {
-    return Math.floor(Math.random() * len);
-};
-const mockData = Array(500)
-    .fill(0)
-    .map((item) => {
-        return {
-            phone: `55****${(randomX(99) + "").padEnd(2, "0")}`,
-            num: `${(Math.random() * 20).toFixed(2)}`,
-            time: "11:00",
-        };
-    });
-function getRandom(min: number, max: number) {
-    const floatRandom = Math.random();
-
-    const difference = max - min;
-
-    // 介于 0 和差值之间的随机数
-    const random = Math.round(difference * floatRandom);
-
-    return random + min;
-}
-/**
- * @description 描述
- */
-type DescProps = {
-    onClose: () => void;
-};
-const Desc = (props: DescProps) => {
-    const { onClose } = props;
-    const [activeTab, setActiveTab] = useState(0);
-    const tabs = [{ text: "Vezes de evento participado" }, { text: "Consulta de registo levado" }];
-    return (
-        <div className={"absolute top-[30%] w-[100%]"}>
-            <div className={"absolute -top-[1.3rem] left-1/2 w-[3.3rem] -translate-x-1/2"}>
-                <img src="/9f/red-header.png" alt="" />
-                <div
-                    className={
-                        "h-[0.2rem] w-[0.2rem] " + " absolute bottom-[20px] right-[30px]" + " "
-                    }
-                    onClick={onClose}
-                >
-                    <Image src={"/9f/close.png"} alt={"close"} width={25} height={25} />
-                </div>
-            </div>
-            <div
-                className={"mx-auto w-[2.9rem] bg-[#ff9417] px-[0.16rem] pb-[0.12rem] pt-[0.44rem]"}
-            >
-                <img src="/9f/red-title.png" alt="" className={"mx-auto w-[90%]"} />
-                <div className={"mt-[0.0694rem] rounded-[3px] bg-primary-color"}>
-                    <div className={"flex h-[0.54rem] justify-between text-center text-[0.15rem]"}>
-                        {tabs.map((item, index) => {
-                            return (
-                                <Fragment key={index}>
-                                    <span
-                                        onClick={() => setActiveTab(index)}
-                                        className={`flex h-[100%] items-center ${index === activeTab ? "bg-[#8b3500] text-[#5f2600]" : ""}`}
-                                    >
-                                        {item.text}
-                                    </span>
-                                </Fragment>
-                            );
-                        })}
-                    </div>
-                    {/*  动态内容 */}
-                    <div className={"h-[3rem] overflow-y-scroll p-[0.1rem]"}>
-                        <div
-                            className={
-                                "flex items-center rounded-[0.1rem] bg-[#d45300] p-[10px] font-bold"
-                            }
-                        >
-                            <Image
-                                className={"h-[0.43rem] w-[0.7rem]"}
-                                width={80}
-                                height={40}
-                                src="/9f/wallet.png"
-                                alt=""
-                            />
-                            <div className={"text-center"}>
-                                <h2> Tempo regressivo </h2>
-                                <p className={"text-[#fe0]"}>Começa amanhã às 11:00</p>
-                            </div>
-                        </div>
-
-                        {!activeTab ? (
-                            <>
-                                <Image
-                                    src={"/9f/6xtime.png"}
-                                    className={"mt-[0.1rem] h-[0.7rem] w-[100%] rounded-[0.1rem]"}
-                                    width={600}
-                                    height={100}
-                                    alt={"time"}
-                                ></Image>
-
-                                <Image
-                                    src={"/9f/3xtime.png"}
-                                    className={"mt-[0.1rem] h-[0.55rem] w-[100%] rounded-[0.1rem]"}
-                                    width={600}
-                                    height={80}
-                                    alt={"time"}
-                                ></Image>
-                            </>
-                        ) : (
-                            <>
-                                <div
-                                    className={"mt-[0.1rem] rounded-[0.1rem] bg-[#d45300] p-[10px]"}
-                                >
-                                    <p className={"text-[#fe0]"}>Registro persoal</p>
-                                    <div
-                                        className={
-                                            "grid grid-cols-3 text-center" +
-                                            " items-center text-[0.1rem]"
-                                        }
-                                    >
-                                        <span>Nome do jogo</span>
-                                        <span>Coleta cumulativa</span>
-                                        <span>Participação total</span>
-                                    </div>
-
-                                    <div
-                                        className={
-                                            "grid grid-cols-3 text-center" +
-                                            " items-center text-[0.12rem] font-bold"
-                                        }
-                                    >
-                                        <span>55****26</span>
-                                        <span>R$ 100.00</span>
-                                        <span>1</span>
-                                    </div>
-                                </div>
-                                <div
-                                    className={"mt-[0.1rem] rounded-[0.1rem] bg-[#d45300] p-[10px]"}
-                                >
-                                    <p className={"text-[#fe0]"}>Lista dos vencedores</p>
-                                    <div
-                                        className={
-                                            "grid grid-cols-3 text-center" +
-                                            " items-center text-[0.1rem]"
-                                        }
-                                    >
-                                        <span>ID do papel</span>
-                                        <span>Valor obtido</span>
-                                        <span>Hora obtida</span>
-                                    </div>
-                                    <div className={`h-[1rem] overflow-hidden`}>
-                                        {mockData.map((item, index) => {
-                                            return (
-                                                <div
-                                                    key={index}
-                                                    className={`grid grid-cols-3 items-center text-center text-[0.12rem] font-bold ${styles.scrollAnimation}`}
-                                                >
-                                                    <span>{item.phone}</span>
-                                                    <span>R$ {item.num}</span>
-                                                    <span>{item.time}</span>
-                                                </div>
-                                            );
-                                        })}
-                                    </div>
-                                </div>
-                            </>
-                        )}
-
-                        <ul className={"mt-[0.1rem] text-[0.1rem]"}>
-                            <li>
-                                ·Cada sessão de chuva de dinheiro é distribuída gratuitamente por
-                                R$100.000.
-                            </li>
-                            <li>
-                                ·Valor máximo de queda em dinheiro: Cada sessão de chuva de dinheiro
-                                é distribuída gratuitamente.
-                            </li>
-                            <li>·Membros recarregados podem reivindicar gratuitamente.</li>
-                            <li>
-                                ·O dinheiro recebido pode ser utilizado para jogar ou sacar
-                                diretamente.
-                            </li>
-                            <li>
-                                ·Quanto for maior o nível de associação VIP, será maior o valor
-                                recebido.
-                            </li>
-                        </ul>
-                    </div>
-                </div>
-            </div>
-        </div>
-    );
-};
-/**
- * @description 可领取红包
- */
-const ReceivePackage = () => {
-    const [visible, setVisible] = useState(false);
-    const cardClass = clsx(visible ? styles.cardReverse : "", styles.cardBack);
-    return (
-        <div className={"absolute left-1/2 top-[40%] -translate-x-1/2"}>
-            <div className={styles.card}>
-                <div className={styles.cardInner}>
-                    <div className={styles.cardFront}>
-                        <p onClick={() => setVisible(true)}>Front Side</p>
-                    </div>
-                    <div className={cardClass}>
-                        <p>Back Side</p>
-                    </div>
-                </div>
-            </div>
-        </div>
-    );
-};
-
-const images = Array(10)
-    .fill(0)
-    .map(() => ({ src: `/9f/money${Math.floor(Math.random() * 3) + 1}.png` }));
-
-const FallAnimation = () => {
-    const fallContentRef = useRef<HTMLDivElement>(null);
-
-    const totalPackets = 200;
-    const timer = useRef<NodeJS.Timer>(null);
-    const total = useRef(0);
-    const createPacket = (xPoint: number) => {
-        const packetWrapperEl = document.createElement("div");
-        packetWrapperEl.classList.add(styles.packetWrapper);
-        packetWrapperEl.style.left = xPoint + "px";
-        packetWrapperEl.style.width = `77px`;
-        packetWrapperEl.style.height = `44px`;
-        packetWrapperEl.style.transform = `scale(0.8) `;
-
-        const packetEl = document.createElement("img");
-        packetEl.classList.add(styles.packet);
-
-        packetEl.style.width = `${getRandom(44, 77)}`;
-        packetEl.style.height = `${getRandom(44, 77)}`;
-
-        packetEl.src = `/9f/money${Math.floor(Math.random() * 3) + 1}.png`;
-
-        setInterval(() => {
-            packetEl.style.transform = `rotate(${getRandom(0, 180)}deg) translateX(${Math.random() > 0.5 ? getRandom(0, 180) : -getRandom(0, 180)}px) scale(${getRandom(0.4, 1.2)}) `;
-        }, 1000);
-
-        packetWrapperEl.appendChild(packetEl);
-        fallContentRef.current?.appendChild(packetWrapperEl);
-    };
-
-    useEffect(() => {
-        // @ts-ignore
-        timer.current = setInterval(() => {
-            if (total.current >= totalPackets - 1) {
-                clearInterval(Number(timer.current));
-                return;
-            }
-            total.current += 1;
-            createPacket(Math.random() * fallContentRef.current?.clientWidth! || 500);
-        }, 200);
-        return () => {
-            clearInterval(Number(timer.current));
-        };
-    }, []);
-    return (
-        <div
-            ref={fallContentRef}
-            style={{ height: "100dvh" }}
-            className={"h-dvh overflow-hidden"}
-        ></div>
-    );
-};
-const Popup = () => {
-    const [maskVisible, setMaskVisible] = useState(true);
-    return (
-        <Mask visible={maskVisible}>
-            <FallAnimation />
-
-            <Desc onClose={() => setMaskVisible(false)} />
-
-            {/*<ReceivePackage />*/}
-        </Mask>
-    );
-};
-
-export default Popup;

+ 0 - 493
src/app/[locale]/(TabBar)/promo/PopupHby.tsx

@@ -1,493 +0,0 @@
-"use client";
-
-import { lredPacketApi, receiveRedPacketApi, redPacketApi } from "@/api/promo";
-import { getToken } from "@/utils/Cookies";
-import { Mask } from "antd-mobile";
-import clsx from "clsx";
-import Image from "next/image";
-import { Fragment, useEffect, useRef, useState } from "react";
-import styles from "./style.module.scss";
-
-const randomX = (len: number) => {
-    return Math.floor(Math.random() * len);
-};
-const mockData = Array(500)
-    .fill(0)
-    .map((item) => {
-        return {
-            phone: `55****${(randomX(99) + "").padEnd(2, "0")}`,
-            num: `${(Math.random() * 20).toFixed(2)}`,
-            time: "11:00",
-        };
-    });
-function getRandom(min: number, max: number) {
-    const floatRandom = Math.random();
-
-    const difference = max - min;
-
-    // 介于 0 和差值之间的随机数
-    const random = Math.round(difference * floatRandom);
-
-    return random + min;
-}
-/**
- * @description 描述
- */
-type DescProps = {
-    onClose: () => void;
-};
-const Desc = (props: DescProps) => {
-    const { onClose } = props;
-    const [activeTab, setActiveTab] = useState(0);
-    const tabs = [{ text: "Vezes de evento participado" }, { text: "Consulta de registo levado" }];
-    return (
-        <div className={"absolute top-[30%] w-[100%]"}>
-            <div className={"absolute -top-[1.3rem] left-1/2 w-[3.3rem] -translate-x-1/2"}>
-                <img src="/9f/red-header.png" alt="" />
-                <div
-                    className={
-                        "h-[0.2rem] w-[0.2rem] " + " absolute bottom-[20px] right-[30px]" + " "
-                    }
-                    onClick={onClose}
-                >
-                    <Image src={"/9f/close.png"} alt={"close"} width={25} height={25} />
-                </div>
-            </div>
-            <div
-                className={"mx-auto w-[2.9rem] bg-[#ff9417] px-[0.16rem] pb-[0.12rem] pt-[0.44rem]"}
-            >
-                <img src="/9f/red-title.png" alt="" className={"mx-auto w-[90%]"} />
-                <div className={"mt-[0.0694rem] rounded-[3px] bg-primary-color"}>
-                    <div className={"flex h-[0.54rem] justify-between text-center text-[0.15rem]"}>
-                        {tabs.map((item, index) => {
-                            return (
-                                <Fragment key={index}>
-                                    <span
-                                        onClick={() => setActiveTab(index)}
-                                        className={`flex h-[100%] items-center ${index === activeTab ? "bg-[#8b3500] text-[#5f2600]" : ""}`}
-                                    >
-                                        {item.text}
-                                    </span>
-                                </Fragment>
-                            );
-                        })}
-                    </div>
-                    {/*  动态内容 */}
-                    <div className={"h-[3rem] overflow-y-scroll p-[0.1rem]"}>
-                        <div
-                            className={
-                                "flex items-center rounded-[0.1rem] bg-[#d45300] p-[10px] font-bold"
-                            }
-                        >
-                            <Image
-                                className={"h-[0.43rem] w-[0.7rem]"}
-                                width={80}
-                                height={40}
-                                src="/9f/wallet.png"
-                                alt=""
-                            />
-                            <div className={"text-center"}>
-                                <h2> Tempo regressivo </h2>
-                                <p className={"text-[#fe0]"}>Começa amanhã às 11:00</p>
-                            </div>
-                        </div>
-
-                        {!activeTab ? (
-                            <>
-                                <Image
-                                    src={"/9f/6xtime.png"}
-                                    className={"mt-[0.1rem] h-[0.7rem] w-[100%] rounded-[0.1rem]"}
-                                    width={600}
-                                    height={100}
-                                    alt={"time"}
-                                ></Image>
-
-                                <Image
-                                    src={"/9f/3xtime.png"}
-                                    className={"mt-[0.1rem] h-[0.55rem] w-[100%] rounded-[0.1rem]"}
-                                    width={600}
-                                    height={80}
-                                    alt={"time"}
-                                ></Image>
-                            </>
-                        ) : (
-                            <>
-                                <div
-                                    className={"mt-[0.1rem] rounded-[0.1rem] bg-[#d45300] p-[10px]"}
-                                >
-                                    <p className={"text-[#fe0]"}>Registro persoal</p>
-                                    <div
-                                        className={
-                                            "grid grid-cols-3 text-center" +
-                                            " items-center text-[0.1rem]"
-                                        }
-                                    >
-                                        <span>Nome do jogo</span>
-                                        <span>Coleta cumulativa</span>
-                                        <span>Participação total</span>
-                                    </div>
-
-                                    <div
-                                        className={
-                                            "grid grid-cols-3 text-center" +
-                                            " items-center text-[0.12rem] font-bold"
-                                        }
-                                    >
-                                        <span>55****26</span>
-                                        <span>R$ 100.00</span>
-                                        <span>1</span>
-                                    </div>
-                                </div>
-                                <div
-                                    className={"mt-[0.1rem] rounded-[0.1rem] bg-[#d45300] p-[10px]"}
-                                >
-                                    <p className={"text-[#fe0]"}>Lista dos vencedores</p>
-                                    <div
-                                        className={
-                                            "grid grid-cols-3 text-center" +
-                                            " items-center text-[0.1rem]"
-                                        }
-                                    >
-                                        <span>ID do papel</span>
-                                        <span>Valor obtido</span>
-                                        <span>Hora obtida</span>
-                                    </div>
-                                    <div className={`h-[1rem] overflow-hidden`}>
-                                        {mockData.map((item, index) => {
-                                            return (
-                                                <div
-                                                    key={index}
-                                                    className={`grid grid-cols-3 items-center text-center text-[0.12rem] font-bold ${styles.scrollAnimation}`}
-                                                >
-                                                    <span>{item.phone}</span>
-                                                    <span>R$ {item.num}</span>
-                                                    <span>{item.time}</span>
-                                                </div>
-                                            );
-                                        })}
-                                    </div>
-                                </div>
-                            </>
-                        )}
-
-                        <ul className={"mt-[0.1rem] text-[0.1rem]"}>
-                            <li>
-                                ·Cada sessão de chuva de dinheiro é distribuída gratuitamente por
-                                R$100.000.
-                            </li>
-                            <li>
-                                ·Valor máximo de queda em dinheiro: Cada sessão de chuva de dinheiro
-                                é distribuída gratuitamente.
-                            </li>
-                            <li>·Membros recarregados podem reivindicar gratuitamente.</li>
-                            <li>
-                                ·O dinheiro recebido pode ser utilizado para jogar ou sacar
-                                diretamente.
-                            </li>
-                            <li>
-                                ·Quanto for maior o nível de associação VIP, será maior o valor
-                                recebido.
-                            </li>
-                        </ul>
-                    </div>
-                </div>
-            </div>
-        </div>
-    );
-};
-/**
- * @description 可领取红包
- */
-const ReceivePackage = () => {
-    const [visible, setVisible] = useState(false);
-    const cardClass = clsx(visible ? styles.cardReverse : "", styles.cardBack);
-    return (
-        <div className={"absolute left-1/2 top-[40%] -translate-x-1/2"}>
-            <div className={styles.card}>
-                <div className={styles.cardInner}>
-                    <div className={styles.cardFront}>
-                        <p onClick={() => setVisible(true)}>Front Side</p>
-                    </div>
-                    <div className={cardClass}>
-                        <p>Back Side</p>
-                    </div>
-                </div>
-            </div>
-        </div>
-    );
-};
-
-const images = Array(10)
-    .fill(0)
-    .map(() => ({ src: `/9f/money${Math.floor(Math.random() * 3) + 1}.png` }));
-
-const FallAnimation = (props: any) => {
-    const { onClose } = props;
-    const fallContentRef = useRef<HTMLDivElement>(null);
-
-    const totalPackets = 200;
-    const timer = useRef<NodeJS.Timer>(null);
-    const total = useRef(0);
-    const createPacket = (xPoint: number) => {
-        const packetWrapperEl = document.createElement("div");
-        packetWrapperEl.classList.add(styles.packetWrapper);
-        packetWrapperEl.style.left = xPoint + "px";
-        packetWrapperEl.style.width = `77px`;
-        packetWrapperEl.style.height = `44px`;
-        packetWrapperEl.style.transform = `scale(0.8) `;
-
-        const packetEl = document.createElement("img");
-        packetEl.classList.add(styles.packet);
-
-        packetEl.style.width = `${getRandom(44, 77)}`;
-        packetEl.style.height = `${getRandom(44, 77)}`;
-
-        packetEl.src = `/9f/money${Math.floor(Math.random() * 3) + 1}.png`;
-
-        setInterval(() => {
-            packetEl.style.transform = `rotate(${getRandom(0, 180)}deg) translateX(${Math.random() > 0.5 ? getRandom(0, 180) : -getRandom(0, 180)}px) scale(${getRandom(0.4, 1.2)}) `;
-        }, 1000);
-
-        packetWrapperEl.appendChild(packetEl);
-        fallContentRef.current?.appendChild(packetWrapperEl);
-    };
-
-    useEffect(() => {
-        // @ts-ignore
-        timer.current = setInterval(() => {
-            if (total.current >= totalPackets - 1) {
-                clearInterval(Number(timer.current));
-                return;
-            }
-            total.current += 1;
-            createPacket(Math.random() * fallContentRef.current?.clientWidth! || 500);
-        }, 200);
-        return () => {
-            clearInterval(Number(timer.current));
-        };
-    }, []);
-    return (
-        <div
-            ref={fallContentRef}
-            style={{ height: "100dvh" }}
-            className={"h-dvh overflow-hidden"}
-            onClick={onClose}
-        ></div>
-    );
-};
-
-const HbyInfoDetail = (props: any) => {
-    const { iconImg, onCloseHby } = props;
-    return (
-        <div
-            className={`absolute left-1/2 top-[50%] w-[90%] -translate-x-1/2 -translate-y-1/2 ${styles.promoRules}`}
-        >
-            {/* <Image src={"/hby/close.png"} alt={"close"} width={25} height={25} onClick={onCloseHby} className={styles.closeIcon}/> */}
-            <div onClick={onCloseHby} className={styles.closeIcon}></div>
-            <Image src={iconImg} alt={"detail"} width={672} height={1044} />
-            {/* <div className={`h-[0.15rem] text-[#ffd800] text-[0.20rem] text-center ${styles.promoTitle}`}>Dinheiro como chuva</div>
-      <div className={styles.titleWrap}>
-          <span>R$200.00</span>
-          <span> por vez, </span>
-          <span>Máx queda </span>
-          <span>R$7.777</span>
-      </div>
-      <div className={styles.tips}>
-        <img src="/hby/tip-icon.png" alt="tips"  className={styles.tipsIcon}/>
-        <div className={styles.tipsTime}>Começa às 23:00</div>
-      </div>
-      <div className={styles.times1}>
-        <img src="/hby/time1.png"/>
-      </div>
-      <div className={styles.times2}>
-        <img src="/hby/time2.png"/>
-      </div>
-      <ul className={styles.rulelist}>
-        <li className={styles.ruleItem}>
-          Cada sessão de chuva de dinheiro é distribuída gratuitamente com <span>R$200.000</span>
-        </li>
-        <li className={styles.ruleItem}>
-          Valor máximo de queda em dinheiro:Cada sessäo de chuva de dinheiro é distribuida gratuitamente com
-        </li>
-        <li className={styles.ruleItem}>
-          Membros recarregados podem reivindicar gratuitamente
-        </li>
-        <li className={styles.ruleItem}>
-          O dinheiro recebido pode ser utilizado para jogar ou sacado diretamente
-        </li>
-        <li className={styles.ruleItem}>
-          Quanto maior o nivel de associacäo VP, maior o valor recebido
-        </li>
-      </ul> */}
-        </div>
-    );
-};
-
-const HbyInfo = (props: any) => {
-    const { iconImg, onCloseHby, onReciveRed } = props;
-    if (!iconImg) return;
-    return (
-        <div
-            className={`absolute left-1/2 top-[50%] -translate-x-1/2 -translate-y-1/2 ${styles.redclose}`}
-        >
-            {/* <Image src={"/hby/close.png"} alt={"close"} width={20} height={20} onClick={onCloseHby} className={styles.closeIcon}/> */}
-            <div onClick={onCloseHby} className={styles.closeIcon}></div>
-            <img
-                src={iconImg}
-                alt={"icon"}
-                width={559}
-                height={687}
-                onClick={onReciveRed}
-                className={styles.redIcon}
-            />
-            {/* <div className={styles.title}>Chuva de dinheiro</div>
-      <div className={styles.desc}>
-        <ul className={styles.desclist}>
-          <li className={styles.descitem}>  Membros recarregados podem reivindicar gratuitamente. </li>
-          <div className={styles.line}></div>
-          <li className={styles.descitem}> Valor máximo de queda em dinheiro: R$7.777 </li>
-        </ul>
-      </div>
-      <div className={styles.openBtn} onClick={onReciveRed}>AGARRAR</div> */}
-        </div>
-        // <div data-v-f333135e="" className={`absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 ${styles.redopen}`}>
-        //   <Image src={"/hby/close.png"} alt={"close"} width={20} height={20} onClick={onCloseHby} className={styles.closeIcon}/>
-        //   <div className={styles.title}>Chuva de dinheiro</div>
-        //   <div className={styles.cash}>1.96</div>
-        //   <div className={styles.tips}>Valor máximo de queda em dinheiro:Cada sessäo de chuva de dinheiro é </div>
-        // </div>
-    );
-};
-
-const HbyInfo2 = (props: any) => {
-    const { iconImg, onCloseHby, redAmount } = props;
-    console.log(`🚀🚀🚀🚀🚀-> in PopupHby.tsx on 364`, iconImg);
-    return (
-        <div
-            className={`absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 ${styles.redopen}`}
-        >
-            <Image
-                src={"/hby/close.png"}
-                alt={"close"}
-                width={30}
-                height={30}
-                onClick={onCloseHby}
-                className={styles.closeIcon}
-            />
-            {/* <div onClick={onCloseHby} className={styles.closeIcon}></div> */}
-            <Image src={iconImg} alt={"icon"} width={559} height={687} />
-            <div className={styles.cash}>{redAmount}</div>
-            {/* <div className={styles.title}>Chuva de dinheiro</div>
-      <div className={styles.cash}>{redAmount}</div>
-      <div className={styles.tips}>Valor máximo de queda em dinheiro:Cada sessäo de chuva de dinheiro é </div> */}
-        </div>
-    );
-};
-
-const Popup = (props: any) => {
-    const { onClose } = props;
-    const [maskVisible, setMaskVisible] = useState(true);
-
-    const [iconLists, setIconLists] = useState<any>([]);
-    const [isShowRed, setIsShowRed] = useState(false);
-    const [isShowReciveRed, setIsShowReciveRed] = useState(false);
-    const [isShowRedDetail, setIsShowRedDetail] = useState(false);
-    const [redPacketInfo, setRedPacketInfo] = useState<any>({});
-    const [redAmount, setRedAmount] = useState<any>(0);
-    const token = getToken();
-
-    useEffect(() => {
-        getRedPacketInfo();
-    }, []);
-
-    const getRedPacketInfo = async () => {
-        try {
-            let actList: any = [];
-            if (token) {
-                let redPacketInfo = await lredPacketApi();
-                actList = redPacketInfo.data?.red_packets || [];
-            } else {
-                let redPacketInfo = await redPacketApi();
-                actList = redPacketInfo.data;
-            }
-            // 是否有已开始但是没领过的红包
-            let isHasStartAct = actList.filter((aItem: any) => {
-                return aItem.can_receive && aItem.is_start && !aItem.is_receive;
-            });
-
-            let isShowRed = isHasStartAct.length > 0;
-            let isShowRedDetail = isHasStartAct.length === 0;
-            let redInfo = isShowRed ? isHasStartAct[0] : {};
-            let curAct = !!isShowRedDetail ? findCurrentActivity(actList) : actList[0];
-            let iconList = JSON.parse(curAct.icon);
-
-            setIconLists(iconList);
-            setIsShowRed(isShowRed);
-            setIsShowRedDetail(isShowRedDetail);
-            setRedPacketInfo(redInfo);
-        } catch (error) {
-            console.log("redPacketInfo===>error:", error);
-        }
-    };
-
-    // 筛选出离当前时间最近的活动
-    const findCurrentActivity = (activities: any) => {
-        const now = Math.floor(Date.now() / 1000); // 获取当前时间的时间戳(单位:秒)
-        let closestActivity = null;
-        let isInRange = false;
-
-        // 遍历活动数据
-        for (let i = 0; i < activities.length; i++) {
-            const activity = activities[i];
-
-            // 检查当前时间是否在活动的时间范围内
-            if (now >= activity.start_time && now <= activity.end_time) {
-                isInRange = true;
-                return activity; // 如果在范围内,直接返回当前活动
-            }
-
-            // 如果不在范围内,记录离当前时间最近的活动
-            if (
-                !closestActivity ||
-                Math.abs(now - activity.end_time) < Math.abs(now - closestActivity.end_time)
-            ) {
-                closestActivity = activity;
-            }
-        }
-
-        // 如果不在任何活动范围内,返回离当前时间最近的活动
-        return closestActivity;
-    };
-
-    const onReciveRed = async () => {
-        try {
-            let paramsData = {
-                id: redPacketInfo?.id,
-                index: redPacketInfo?.index,
-            };
-            let receiveRedPacketInfo = await receiveRedPacketApi(paramsData);
-            let redNum = receiveRedPacketInfo.data;
-            setIsShowRed(false);
-            setIsShowReciveRed(true);
-            setRedAmount(redNum?.amount);
-        } catch (error) {
-            console.log("redPacketInfo===>error:", error);
-        }
-    };
-
-    return (
-        <Mask>
-            <FallAnimation onClose={onClose} />
-
-            {!!isShowRed && (
-                <HbyInfo onCloseHby={onClose} onReciveRed={onReciveRed} iconImg={iconLists[1]} />
-            )}
-            {!!isShowReciveRed && (
-                <HbyInfo2 onCloseHby={onClose} redAmount={redAmount} iconImg={iconLists[2]} />
-            )}
-            {!!isShowRedDetail && <HbyInfoDetail onCloseHby={onClose} iconImg={iconLists[0]} />}
-        </Mask>
-    );
-};
-
-export default Popup;

+ 0 - 44
src/app/[locale]/(TabBar)/promo/PromoClient.tsx

@@ -1,44 +0,0 @@
-"use client";
-import Box from "@/components/Box";
-import { useState } from "react";
-import PopupHby from "./PopupHby";
-
-const Promo = ({ promotion }: any) => {
-    const [isShowRedPacket, setIsShowRedPacket] = useState<any>(false);
-
-    const onGoPromo = (e: any, item: any) => {
-        e.stopPropagation();
-        console.log("onGoPromo", item);
-        // 4:跳转弹窗,action_params==>red_packet:代表红包雨弹窗
-        if (item.action_type === 4 && item.action_params === "red_packet") {
-            setIsShowRedPacket(true);
-        }
-    };
-
-    return (
-        <>
-            {promotion.map((item: any, index: number) => (
-                <Box key={item.id} action={item.action_type} actionData={item.action_params}>
-                    <img
-                        width={0}
-                        height={0}
-                        src={item.content!}
-                        alt={"Image"}
-                        className={"h-[1.16rem] w-[100%] rounded-[0.0833rem]"}
-                        onClick={(e) => onGoPromo(e, item)}
-                    />
-                </Box>
-            ))}
-            {/* 红包弹窗 */}
-            {isShowRedPacket && (
-                <PopupHby
-                    onClose={() => {
-                        setIsShowRedPacket(false);
-                    }}
-                />
-            )}
-        </>
-    );
-};
-
-export default Promo;

+ 0 - 1
src/app/[locale]/(TabBar)/promo/page.tsx

@@ -30,7 +30,6 @@ const Promo = async () => {
                     />
                 </Box>
             ))}
-            {/*<Popup />*/}
         </>
     );
 };

+ 111 - 41
src/components/Box/RedPacketModal.tsx

@@ -206,58 +206,127 @@ const Desc = (props: DescProps) => {
     );
 };
 
-const FallAnimation = (props: any) => {
+// 红包掉落动画像下雨
+const FallAnimation1 = (props: any) => {
     const { onClose } = props;
     const fallContentRef = useRef<HTMLDivElement>(null);
+    const isActive = useRef(true);
 
-    const totalPackets = 200;
-    const timer = useRef<NodeJS.Timer>(null);
-    const total = useRef(0);
-    const createPacket = (xPoint: number) => {
-        const packetWrapperEl = document.createElement("div");
-        packetWrapperEl.classList.add(styles.packetWrapper);
-        packetWrapperEl.style.left = xPoint + "px";
-        packetWrapperEl.style.width = `77px`;
-        packetWrapperEl.style.height = `44px`;
-        packetWrapperEl.style.transform = `scale(0.8) `;
-
-        const packetEl = document.createElement("img");
-        packetEl.classList.add(styles.packet);
-
-        packetEl.style.width = `${getRandom(44, 77)}`;
-        packetEl.style.height = `${getRandom(44, 77)}`;
-
-        packetEl.src = `/9f/money${Math.floor(Math.random() * 3) + 1}.png`;
+    const getRandom = (min: number, max: number) => {
+        return Math.random() * (max - min) + min;
+    };
 
+    const createMoneyElement = (xPos: number) => {
+        if (!fallContentRef.current || !isActive.current) return;
+
+        const money = document.createElement('div');
+        
+        // 基础样式
+        money.style.cssText = `
+            position: fixed;
+            left: ${xPos}px;
+            top: -100px;
+            width: 60px;
+            height: 60px;
+            pointer-events: none;
+        `;
+
+        // 创建图片
+        const img = document.createElement('img');
+        img.src = `/9f/money${Math.floor(Math.random() * 3) + 1}.png`;
+        img.style.cssText = `
+            width: 100%;
+            height: 100%;
+            object-fit: contain;
+        `;
+        
+        money.appendChild(img);
+        fallContentRef.current.appendChild(money);
+
+        // 使用 requestAnimationFrame 确保元素已添加到 DOM 后再添加动画
+        requestAnimationFrame(() => {
+            const scale = getRandom(0.4, 1);
+            const duration = getRandom(8, 12);
+            const delay = getRandom(0, 5);
+            
+            money.style.cssText += `
+                transform: scale(${scale});
+                z-index: ${Math.floor(scale * 100)};
+                animation: ${styles.fall} ${duration}s linear infinite,
+                          ${styles.sway} ${duration/2}s ease-in-out infinite alternate;
+                animation-delay: ${delay}s;
+            `;
+        });
+
+        // 当动画完成一次循环后,重新设置位置
         setInterval(() => {
-            packetEl.style.transform = `rotate(${getRandom(0, 180)}deg) translateX(${Math.random() > 0.5 ? getRandom(0, 180) : -getRandom(0, 180)}px) scale(${getRandom(0.4, 1.2)}) `;
-        }, 1000);
-
-        packetWrapperEl.appendChild(packetEl);
-        fallContentRef.current?.appendChild(packetWrapperEl);
+            if (isActive.current) {
+                money.style.left = `${getRandom(0, window.innerWidth)}px`;
+            }
+        }, 12000);
     };
 
     useEffect(() => {
-        // @ts-ignore
-        timer.current = setInterval(() => {
-            if (total.current >= totalPackets - 1) {
-                clearInterval(Number(timer.current));
-                return;
+        console.log('FallAnimation1 mounted'); // 调试日志
+
+        if (!fallContentRef.current) return;
+
+        // 设置容器样式
+        fallContentRef.current.style.cssText = `
+            position: fixed;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100vh;
+            z-index: 1000;
+            pointer-events: none;
+            overflow: hidden;
+            background: transparent;
+        `;
+
+        // 分批创建元素
+        const totalElements = 300;
+        const batchSize = 20;
+        let created = 0;
+
+        const createBatch = () => {
+            if (!isActive.current) return;
+
+            for (let i = 0; i < batchSize && created < totalElements; i++) {
+                const xPos = getRandom(0, window.innerWidth);
+                createMoneyElement(xPos);
+                created++;
             }
-            total.current += 1;
-            createPacket(Math.random() * fallContentRef.current?.clientWidth! || 500);
-        }, 200);
+
+            if (created < totalElements) {
+                setTimeout(createBatch, 200);
+            }
+        };
+
+        createBatch();
+
         return () => {
-            clearInterval(Number(timer.current));
+            console.log('FallAnimation1 unmounting'); // 调试日志
+            isActive.current = false;
         };
     }, []);
+
     return (
         <div
             ref={fallContentRef}
-            style={{ height: "100dvh" }}
-            className={"h-dvh overflow-hidden"}
-            onClick={onClose}
-        ></div>
+            style={{
+                position: 'fixed',
+                top: 0,
+                left: 0,
+                width: '100%',
+                height: '100vh',
+                zIndex: 1000,
+            }}
+            onClick={(e) => {
+                e.stopPropagation();
+                onClose?.();
+            }}
+        />
     );
 };
 
@@ -392,8 +461,8 @@ export type RedPacketModalProps = {
 /**
  * @description 红包的三种状态
  * is_start 可领取 展示红包领取组件
- * is_receive 已领取 展示领取情组件
- * is_end 可展示 展示明页
+ * is_receive 已领取 展示领取情组件
+ * is_end 可展示 展示���明页
  */
 enum Status {
     is_start,
@@ -433,7 +502,7 @@ const RedPacketModal = forwardRef<RedPacketModalProps, Props>(function RedPacket
     const getRedPacketInfo = async () => {
         try {
             let actList = packets.current;
-            // 是否有已开始但是没领过的红包
+            // 是否开始但是没领过的红包
             let packetsFilter = actList
                 .filter((aItem: any) => {
                     return aItem.can_receive && aItem.is_start && !aItem.is_receive;
@@ -490,7 +559,8 @@ const RedPacketModal = forwardRef<RedPacketModalProps, Props>(function RedPacket
     }, []);
     return (
         <Mask visible={visible} destroyOnClose={true} getContainer={element.current}>
-            <FallAnimation onClose={() => setVisible(false)} />
+            <FallAnimation1 onClose={() => setVisible(false)} />
+            {/*<FallAnimation1 onClose={() => setVisible(false)} />*/}
 
             {status === Status.is_start ? (
                 <HbyInfo

+ 20 - 24
src/components/Box/redpacked.module.scss

@@ -1,11 +1,22 @@
-@keyframes smoothscroll {
-  0% {
-    transform: translateY(0);
-  }
+@keyframes fall {
+    0% {
+        transform: translateY(-100px);
+    }
+    100% {
+        transform: translateY(120vh);
+    }
+}
 
-  100% {
-    transform: translateY(-20rem);
-  }
+@keyframes sway {
+    0% {
+        transform: translateX(-100px) rotate(-20deg);
+    }
+    50% {
+        transform: translateX(100px) rotate(20deg);
+    }
+    100% {
+        transform: translateX(-100px) rotate(-20deg);
+    }
 }
 
 .scrollAnimation {
@@ -66,12 +77,8 @@
 }
 
 .packetWrapper {
-  position: absolute;
-  top: 0;
-  left: 0;
-  transform: translateY(-100%);
-  animation: down 8s linear infinite;
-  font-size: 0;
+  will-change: transform;
+  pointer-events: none;
 }
 
 .packet{
@@ -82,17 +89,6 @@
   transform: rotate(0);
 }
 
-@keyframes down {
-  0% {
-    transform: translateY(-100%);
-  }
-
-  100% {
-    transform: translateY(100vh);
-  }
-}
-
-
 .promoRules{
   // background:url('/hby/hby_bg.png') no-repeat;
   background-size: 100% 100%;