From 79568c0ea1c95cb6ace10f338d70c3cb593c7312 Mon Sep 17 00:00:00 2001 From: eric Date: Mon, 4 Aug 2025 14:13:30 +0800 Subject: [PATCH] 's' --- src/pages/index/index.jsx | 215 +++++++++++++++++++++++++++++++------ src/pages/index/index.scss | 175 +++++++++++++++++------------- 2 files changed, 284 insertions(+), 106 deletions(-) diff --git a/src/pages/index/index.jsx b/src/pages/index/index.jsx index 7456968..3210191 100644 --- a/src/pages/index/index.jsx +++ b/src/pages/index/index.jsx @@ -3,22 +3,123 @@ import Taro from "@tarojs/taro"; import { View, Text, Image, Button, Audio } from "@tarojs/components"; import "./index.scss"; import React, { useCallback, useEffect, useState } from "react"; -import { AtList, AtListItem, AtNavBar, AtTag, AtMessage } from "taro-ui"; +import { + AtList, + AtListItem, + AtNavBar, + AtTag, + AtMessage, + AtCurtain, +} from "taro-ui"; import gif11 from "../../images/11.gif"; import gif22 from "../../images/22.gif"; import doro11 from "../../images/doro11.gif"; import baby from "../../images/baby.mp3"; +import confetti from "canvas-confetti"; +import { AtToast } from "taro-ui"; const Index = () => { // ws://(或者 wss:// 对于 HTTPS 环境 const [message, setMessage] = useState(""); const [status, setStatus] = useState("0"); //0无状态,1是小新 const [userInfoArr, setuserInfoArr] = useState([]); // 用户信息 + const [giftUser, setGiftUser] = useState({}); // 用户信息 + const [giftOpen, setGiftOpen] = useState(false); // 用户信息 const [messageArr, setMessageArr] = useState([]); + // useEffect(() => { + // const intervalId = setInterval(() => { + // speak(`欢迎进入直播间`); + // }, 3000); + + // return () => { + // clearInterval(intervalId); + // }; + // }, []); + + + const confettiSvg = () => { + var scalar = 2; + var pineapple = confetti.shapeFromText({ text: "🍍", scalar }); + + confetti({ + shapes: [pineapple], + scalar, + }); + }; + + const stars = () => { + // note: you CAN only use a path for confetti.shapeFrompath(), but for + // performance reasons it is best to use it once in development and save + // the result to avoid the performance penalty at runtime + + // pumpkin shape from https://thenounproject.com/icon/pumpkin-5253388/ + var pumpkin = confetti.shapeFromPath({ + path: "M449.4 142c-5 0-10 .3-15 1a183 183 0 0 0-66.9-19.1V87.5a17.5 17.5 0 1 0-35 0v36.4a183 183 0 0 0-67 19c-4.9-.6-9.9-1-14.8-1C170.3 142 105 219.6 105 315s65.3 173 145.7 173c5 0 10-.3 14.8-1a184.7 184.7 0 0 0 169 0c4.9.7 9.9 1 14.9 1 80.3 0 145.6-77.6 145.6-173s-65.3-173-145.7-173zm-220 138 27.4-40.4a11.6 11.6 0 0 1 16.4-2.7l54.7 40.3a11.3 11.3 0 0 1-7 20.3H239a11.3 11.3 0 0 1-9.6-17.5zM444 383.8l-43.7 17.5a17.7 17.7 0 0 1-13 0l-37.3-15-37.2 15a17.8 17.8 0 0 1-13 0L256 383.8a17.5 17.5 0 0 1 13-32.6l37.3 15 37.2-15c4.2-1.6 8.8-1.6 13 0l37.3 15 37.2-15a17.5 17.5 0 0 1 13 32.6zm17-86.3h-82a11.3 11.3 0 0 1-6.9-20.4l54.7-40.3a11.6 11.6 0 0 1 16.4 2.8l27.4 40.4a11.3 11.3 0 0 1-9.6 17.5z", + matrix: [ + 0.020491803278688523, 0, 0, 0.020491803278688523, -7.172131147540983, + -5.9016393442622945, + ], + }); + // tree shape from https://thenounproject.com/icon/pine-tree-1471679/ + var tree = confetti.shapeFromPath({ + path: "M120 240c-41,14 -91,18 -120,1 29,-10 57,-22 81,-40 -18,2 -37,3 -55,-3 25,-14 48,-30 66,-51 -11,5 -26,8 -45,7 20,-14 40,-30 57,-49 -13,1 -26,2 -38,-1 18,-11 35,-25 51,-43 -13,3 -24,5 -35,6 21,-19 40,-41 53,-67 14,26 32,48 54,67 -11,-1 -23,-3 -35,-6 15,18 32,32 51,43 -13,3 -26,2 -38,1 17,19 36,35 56,49 -19,1 -33,-2 -45,-7 19,21 42,37 67,51 -19,6 -37,5 -56,3 25,18 53,30 82,40 -30,17 -79,13 -120,-1l0 41 -31 0 0 -41z", + matrix: [ + 0.03597122302158273, 0, 0, 0.03597122302158273, -4.856115107913669, + -5.071942446043165, + ], + }); + // heart shape from https://thenounproject.com/icon/heart-1545381/ + var heart = confetti.shapeFromPath({ + path: "M167 72c19,-38 37,-56 75,-56 42,0 76,33 76,75 0,76 -76,151 -151,227 -76,-76 -151,-151 -151,-227 0,-42 33,-75 75,-75 38,0 57,18 76,56z", + matrix: [ + 0.03333333333333333, 0, 0, 0.03333333333333333, -5.566666666666666, + -5.533333333333333, + ], + }); + + var defaults = { + scalar: 2, + spread: 180, + particleCount: 30, + origin: { y: -0.1 }, + startVelocity: -35, + }; + + confetti({ + ...defaults, + shapes: [pumpkin], + colors: ["#ff9a00", "#ff7400", "#ff4d00"], + }); + confetti({ + ...defaults, + shapes: [tree], + colors: ["#8d960f", "#be0f10", "#445404"], + }); + confetti({ + ...defaults, + shapes: [heart], + colors: ["#f93963", "#a10864", "#ee0b93"], + }); + }; + + useEffect(() => { + // var myCanvas = document.createElement("canvas"); + // document.body.appendChild(myCanvas); + // var myConfetti = confetti.create(myCanvas, { + // resize: true, + // useWorker: true, + // }); + // myConfetti({ + // particleCount: 100, + // spread: 160, + // // any other options from the global + // // confetti function + // }); + }, []); useEffect(() => { // 创建 WebSocket 连接 const socket = new WebSocket("ws://192.168.31.222:8888"); // 注意使用 ws:// @@ -33,20 +134,42 @@ const Index = () => { socket.onmessage = (event) => { try { const data = JSON.parse(event.data); - + console.log("data.type---", data.type); if (data.type === "join") { - const user = data.data; // 就是你后端推送的 user_data 字典 - + // const user = data.data; // 就是你后端推送的 user_data 字典 + const user = { + ...data.data, + animate: true, + uid: Date.now() + Math.random(), // 确保唯一 + }; console.log("✅ 新观众进场:", user); - // let newuserInfoArr = userInfoArr - // newuserInfoArr.push(user); - // console.log('newuserInfoArr---',newuserInfoArr) - // setuserInfoArr(newuserInfoArr); setuserInfoArr((prev) => [user, ...prev]); + setTimeout(() => { + setuserInfoArr((prev) => + prev.map((u) => + u.uid === user.uid ? { ...u, animate: false } : u + ) + ); + }, 1000); // ✅ 举例使用 - - speak(`${user?.nick_name} 进入了直播间`); + // speak(`欢迎${user?.nick_name} 进入直播间`); + } else if (data.type === "like") { + const user = data.data; + // 粒子特效 + // confettiSvg(); + stars(); + } else if (data.type === "gift") { + stars(); + const user = data.data; + // console.log("✅ 送礼:", user); + // speak(`谢谢${user?.nick_name} 送小星星`); + //特殊特效 + setGiftUser(user); + setGiftOpen(true); + setTimeout(() => { + setGiftOpen(false); + }, 2000); } } catch (e) { console.log("❌ 非 JSON 消息:", event.data); @@ -182,23 +305,19 @@ const Index = () => { return ( - {/* - 扣 11 变小新 + + {/* + 👍 {`点赞`}   ➖{" "} + 看烟花 + */} + + 🩷 小星星 ➖{" "} + 看烟花 + - - 扣 22 娜娜子 - */} - - {/* - {messageArr?.slice(0, 5)?.map((item, index) => ( - - {item} - - ))} - */} {/* .slice(0, 5) */} @@ -207,11 +326,18 @@ const Index = () => { key={index} className={index === 0 ? "message_item_first" : "message_item"} > - {item?.nick_name} - + + {/* ${item?.gender === "1" ? "👨" : "👩"} */} + {`${item?.nick_name}`} + + @@ -219,6 +345,33 @@ const Index = () => { ))} + {/* */} + + setGiftOpen(false)} + closeBtnPosition={"top"} + > +
+ + 谢谢{" "} + + {giftUser?.nick_name} + {" "} + 送🩷🩷🩷🩷🩷 + + +
+
+ {/* 添加doro的gif组合场景 */} {/* @@ -228,7 +381,7 @@ const Index = () => { // src={status === "1" ? gif11 : status === "2" ? gif22 : doro11} src={doro11} /> - */} +
*/} {/* diff --git a/src/pages/index/index.scss b/src/pages/index/index.scss index 68bc9a0..fa28ad9 100644 --- a/src/pages/index/index.scss +++ b/src/pages/index/index.scss @@ -1,87 +1,97 @@ -.index { - width: 100vw; - height: 100vh; - // overflow: hidden; // 防止溢出 - display: flex; - flex-direction: column; - align-items: center; - background-color: black; - // justify-content: center; - // background-image: url('../../images/iphone.jpg'); - // background-size: cover; // 拉伸铺满容器 - // background-position: center; // 居中 - // background-repeat: no-repeat; // 不重复 - - .messageArr { - padding: 40px; - font-size: 30px; +@media (max-width: 1000px) { + .index { + width: 100vw; + height: 100vh; + // overflow: hidden; // 防止溢出 display: flex; flex-direction: column; + align-items: center; + background-color: black; + // justify-content: center; + // background-image: url('../../images/iphone.jpg'); + // background-size: cover; // 拉伸铺满容器 + // background-position: center; // 居中 + // background-repeat: no-repeat; // 不重复 - .message_item_first { - color: red; + .messageArr { + padding: 40px; + font-size: 30px; + display: flex; + flex-direction: column; + + .message_item_first { + color: red; + } + + .message_item { + } } - .message_item {} - } - - - .index_backImg { - width: 100%; - height: 100%; - background-color: yellowgreen; - - .index_backImg_bg { + .index_backImg { width: 100%; height: 100%; + background-color: yellowgreen; + + .index_backImg_bg { + width: 100%; + height: 100%; + } } - } - .index_video { - position: absolute; - top: 0px; - width: 400px; - height: 200px; - // display: flex; - // flex-direction: column; - // align-items: center; - // justify-content: center; - background-color: aqua; - - .video_js { + .index_video { + position: absolute; + top: 0px; width: 400px; height: 200px; + // display: flex; + // flex-direction: column; + // align-items: center; + // justify-content: center; + background-color: aqua; + + .video_js { + width: 400px; + height: 200px; + } + } + + .gifImg { + position: absolute; + bottom: 0; } } - - .gifImg{ - position: absolute; - bottom: 0; - } - } - // PC 浏览器下旋转 -@media (min-width: 1600px) { +@media (min-width: 1000px) { + html, + body, + #root, + #app { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + background-color: black; + box-sizing: border-box; + } .index { - // position: absolute; - // top: 0; - // left: 0; - // width: 750px; // 根据标准宽度调整 - // height: 1334px; // 保持竖屏比例 - - - - width: 100vw; // 使容器宽度始终填满视口 - height: 100vh; // 使容器高度始终填满视口 - // transform: rotate(-90deg) translate(-100vh, 0); + position: absolute; + top: 0; + left: 0; + width: 750px; // 根据标准宽度调整 + height: 1334px; // 保持竖屏比例 + background-color: black; + // width: 100vw; // 使容器宽度始终填满视口 + // height: 100vh; // 使容器高度始终填满视口 + transform: rotate(-90deg) translate(-100vh, 0); transform-origin: top left; display: flex; flex-direction: column; align-items: center; + // justify-content: center; // background-image: url('../../images/iphone.jpg'); @@ -103,10 +113,10 @@ color: red; } - .message_item {} + .message_item { + } } - .index_backImg { width: 100%; height: 100%; @@ -121,19 +131,34 @@ } } - .index_video { - position: absolute; - top: 0px; - width: 400px; - height: 200px; - - .video_js { - width: 400px; - height: 200px; - } + .AtToastDouyin { + z-index: 999; } + .giftCurtain { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: white; + font-size: 20px; + width: 100%; + height: 100%; + } + .at-curtain__btn-close { + display: none !important; + } + // .index_video { + // position: absolute; + // top: 0px; + // width: 400px; + // height: 200px; + + // .video_js { + // width: 400px; + // height: 200px; + // } + // } } - -} \ No newline at end of file +}