|
@@ -1,94 +1,286 @@
|
|
|
"use client";
|
|
|
-import Money1 from "/public/9f/money1.png";
|
|
|
-
|
|
|
-console.log(`🚀🚀🚀🚀🚀-> in Popup.tsx on 5`, Money1.src);
|
|
|
-class CanvasDrawer {
|
|
|
- private element: HTMLCanvasElement;
|
|
|
- private context: CanvasRenderingContext2D;
|
|
|
- private img = new Image();
|
|
|
-
|
|
|
- width = 77;
|
|
|
- height = 47;
|
|
|
-
|
|
|
- redpackId = 1; // 红包标识
|
|
|
- x = 100; // 红包的横坐标
|
|
|
- y = 200; // 红包的竖坐标
|
|
|
- speed = 10; // 下降的速度,创建后则确定
|
|
|
- angle = 2; // 渲染的角度
|
|
|
- ratio = 0.8; // 放大的系数
|
|
|
-
|
|
|
- constructor(element: HTMLCanvasElement) {
|
|
|
- this.element = element;
|
|
|
- this.context = element.getContext("2d")!;
|
|
|
- this.element.width = document.getElementById("app")!.clientWidth;
|
|
|
- this.element.height = document.getElementById("app")!.clientHeight;
|
|
|
-
|
|
|
- const random = Math.random();
|
|
|
- const angle = ((random * 30 + 10) * Math.PI) / 180; // 随机一个旋转偏移角度
|
|
|
- this.angle = random < 0.5 ? angle : 0 - angle; // 随机向左或者向右旋转
|
|
|
- this.ratio = random * 0.4 + 0.8; // 随机放大的效果,0.8~1.2倍之间
|
|
|
-
|
|
|
- this.init();
|
|
|
- }
|
|
|
- init() {
|
|
|
- setInterval(() => {
|
|
|
- this.draw();
|
|
|
- }, 50);
|
|
|
- }
|
|
|
- draw() {
|
|
|
- const { width, height, context } = this;
|
|
|
- if (this.y < this.element.height) {
|
|
|
- context.clearRect(0, 0, this.element.width, this.element.height);
|
|
|
- const nextX = this.x;
|
|
|
- const nextY = this.y + this.speed;
|
|
|
-
|
|
|
- const img = new Image();
|
|
|
- img.src = "/9f/money1.png";
|
|
|
- // img.onload = () => {
|
|
|
- context.save();
|
|
|
- context.beginPath();
|
|
|
- context.rect(nextX, nextY, width, height);
|
|
|
- context.translate(nextX + width / 2, nextY + height / 2);
|
|
|
- context.scale(this.ratio, this.ratio);
|
|
|
- context.rotate(this.angle);
|
|
|
- context.drawImage(img, nextX, nextY, width, height);
|
|
|
- context.strokeStyle = "#fff";
|
|
|
- context.stroke();
|
|
|
- context.restore();
|
|
|
- // };
|
|
|
-
|
|
|
- this.y = nextY;
|
|
|
- // this.context?.clearRect(0, 0, width, height);
|
|
|
- } else {
|
|
|
- console.log(`🚀🚀🚀🚀🚀-> in Popup.tsx on 70`);
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
+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 images = [
|
|
|
- { src: "/9f/money2.png" },
|
|
|
- { src: "/9f/money1.png" },
|
|
|
- { src: "/9f/money3.png" },
|
|
|
- ];
|
|
|
+ const [maskVisible, setMaskVisible] = useState(true);
|
|
|
return (
|
|
|
- <div></div>
|
|
|
- // <Mask visible={true}>
|
|
|
- // <AnimatePresence>
|
|
|
- // {images.map((image, index) => {
|
|
|
- // return (
|
|
|
- // <motion.img
|
|
|
- // key={image.src}
|
|
|
- // src={image.src}
|
|
|
- // initial={{ y: 300, opacity: 0 }}
|
|
|
- // animate={{ y: 0, opacity: 1 }}
|
|
|
- // exit={{ y: -300, opacity: 0 }}
|
|
|
- // />
|
|
|
- // );
|
|
|
- // })}
|
|
|
- // </AnimatePresence>
|
|
|
- // {/*<canvas id={"canvas"} className={"fixed left-0 top-0"}></canvas>*/}
|
|
|
- // </Mask>
|
|
|
+ <Mask visible={maskVisible}>
|
|
|
+ <FallAnimation />
|
|
|
+
|
|
|
+ <Desc onClose={() => setMaskVisible(false)} />
|
|
|
+
|
|
|
+ {/*<ReceivePackage />*/}
|
|
|
+ </Mask>
|
|
|
);
|
|
|
};
|
|
|
|