Files
wish-pool/app/test/page.tsx
2025-07-18 13:07:28 +08:00

489 lines
20 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState, useEffect } from "react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Sparkles, Volume2, VolumeX, Play, Pause, RotateCcw } from "lucide-react"
import { soundManager } from "@/lib/sound-effects"
export default function TestPage() {
const [soundEnabled, setSoundEnabled] = useState(true)
const [animationPaused, setAnimationPaused] = useState(false)
const [animationStatus, setAnimationStatus] = useState<string>("檢查中...")
useEffect(() => {
// 檢查動畫是否正常運作
const checkAnimations = () => {
const testElement = document.createElement("div")
testElement.className = "animate-pulse"
testElement.style.position = "absolute"
testElement.style.top = "-1000px"
document.body.appendChild(testElement)
const computedStyle = window.getComputedStyle(testElement)
const animationName = computedStyle.animationName
document.body.removeChild(testElement)
if (animationName && animationName !== "none") {
setAnimationStatus("✅ 動畫系統正常")
} else {
setAnimationStatus("❌ 動畫系統異常")
}
}
setTimeout(checkAnimations, 1000)
}, [])
useEffect(() => {
// 初始化音效系統
const initSound = async () => {
const handleFirstInteraction = async () => {
await soundManager.play("hover")
document.removeEventListener("click", handleFirstInteraction)
}
document.addEventListener("click", handleFirstInteraction)
}
initSound()
}, [])
const playSound = async (soundName: string) => {
if (soundEnabled) {
await soundManager.play(soundName)
}
}
const toggleSound = () => {
setSoundEnabled(!soundEnabled)
soundManager.toggle()
}
const toggleAnimation = () => {
setAnimationPaused(!animationPaused)
const style = document.createElement("style")
style.textContent = animationPaused
? ""
: `
* {
animation-play-state: paused !important;
}
`
style.id = "animation-control"
const existing = document.getElementById("animation-control")
if (existing) {
existing.remove()
}
if (!animationPaused) {
document.head.appendChild(style)
}
}
return (
<div className="min-h-screen bg-gradient-to-b from-slate-900 via-blue-900 to-indigo-900 relative overflow-hidden">
{/* 星空背景 */}
<div className="absolute inset-0 overflow-hidden pointer-events-none">
{[...Array(30)].map((_, i) => (
<div
key={i}
className="absolute w-1 h-1 bg-white rounded-full animate-pulse"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 3}s`,
animationDuration: `${2 + Math.random() * 2}s`,
}}
/>
))}
<div className="absolute top-1/4 left-1/2 transform -translate-x-1/2 w-96 h-96 bg-gradient-radial from-cyan-400/20 via-blue-500/10 to-transparent rounded-full blur-3xl"></div>
</div>
{/* Header */}
<header className="border-b border-blue-800/50 bg-slate-900/80 backdrop-blur-sm sticky top-0 z-50">
<div className="container mx-auto px-4 py-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full flex items-center justify-center shadow-lg shadow-cyan-500/25">
<Sparkles className="w-6 h-6 text-white" />
</div>
<h1 className="text-2xl font-bold text-white"></h1>
<Badge className="bg-red-500/20 text-red-200 border border-red-400/30"></Badge>
</div>
<div className="flex items-center gap-4">
<Button
variant="ghost"
size="sm"
onClick={toggleSound}
className="text-blue-200 hover:text-white hover:bg-blue-800/50"
>
{soundEnabled ? <Volume2 className="w-4 h-4 mr-2" /> : <VolumeX className="w-4 h-4 mr-2" />}
{soundEnabled ? "音效開啟" : "音效關閉"}
</Button>
<Button
variant="ghost"
size="sm"
onClick={toggleAnimation}
className="text-blue-200 hover:text-white hover:bg-blue-800/50"
>
{animationPaused ? <Play className="w-4 h-4 mr-2" /> : <Pause className="w-4 h-4 mr-2" />}
{animationPaused ? "恢復動畫" : "暫停動畫"}
</Button>
</div>
</div>
</div>
</header>
{/* Main Content */}
<main className="py-12 px-4">
<div className="container mx-auto max-w-6xl">
<div className="grid lg:grid-cols-2 gap-8">
{/* 音效測試區 */}
<Card className="bg-slate-800/50 backdrop-blur-sm border border-blue-700/50">
<CardHeader>
<CardTitle className="text-white flex items-center gap-3">
<Volume2 className="w-6 h-6 text-cyan-400" />
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<Button
onClick={() => playSound("click")}
className="bg-gradient-to-r from-blue-500 to-cyan-600 hover:from-blue-600 hover:to-cyan-700 text-white"
>
🔘
</Button>
<Button
onClick={() => playSound("hover")}
className="bg-gradient-to-r from-purple-500 to-pink-600 hover:from-purple-600 hover:to-pink-700 text-white"
>
</Button>
<Button
onClick={() => playSound("submit")}
className="bg-gradient-to-r from-green-500 to-emerald-600 hover:from-green-600 hover:to-emerald-700 text-white"
>
📤
</Button>
<Button
onClick={() => playSound("success")}
className="bg-gradient-to-r from-yellow-500 to-orange-600 hover:from-yellow-600 hover:to-orange-700 text-white"
>
🎉
</Button>
</div>
<div className="mt-6 p-4 bg-slate-700/30 rounded-lg">
<h4 className="text-white font-semibold mb-2"></h4>
<ul className="text-blue-200 text-sm space-y-1">
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
</ul>
</div>
</CardContent>
</Card>
{/* 動畫測試區 */}
<Card className="bg-slate-800/50 backdrop-blur-sm border border-blue-700/50">
<CardHeader>
<CardTitle className="text-white flex items-center gap-3">
<Sparkles className="w-6 h-6 text-cyan-400" />
</CardTitle>
</CardHeader>
<CardContent>
{/* 許願瓶動畫展示 - 使用內聯樣式確保動畫運作 */}
<div className="text-center mb-8">
<h4 className="text-white font-semibold mb-4"></h4>
<div className="relative mx-auto w-24 h-32 mb-6">
<div
className="absolute bottom-0 left-1/2 w-16 h-24 bg-gradient-to-b from-cyan-100/30 to-blue-200/40 rounded-t-xl rounded-b-lg shadow-xl shadow-cyan-500/20 backdrop-blur-sm border border-cyan-300/30"
style={{
transform: "translateX(-50%)",
animation: "bottleBreathe 6s ease-in-out infinite",
}}
>
<div className="absolute -top-2 left-1/2 transform -translate-x-1/2 w-4 h-3 bg-slate-700 rounded-t-md"></div>
<div
className="absolute inset-2 bg-gradient-radial from-yellow-300/40 via-cyan-300/20 to-transparent rounded-t-lg rounded-b-md"
style={{
animation: "glowPulse 4s ease-in-out infinite",
}}
></div>
<div className="absolute top-1 left-1 w-1 h-16 bg-white/20 rounded-full"></div>
{/* 星光粒子 - 使用內聯動畫 */}
<div
className="absolute top-3 right-3 w-1 h-1 bg-cyan-300 rounded-full"
style={{
animation: "sparkleFloat 8s ease-in-out infinite",
}}
></div>
<div
className="absolute bottom-4 left-3 w-1 h-1 bg-yellow-300 rounded-full"
style={{
animation: "sparkleDrift 10s ease-in-out infinite",
}}
></div>
<div
className="absolute top-8 left-4 w-1 h-1 bg-pink-300 rounded-full"
style={{
animation: "sparkleTwinkle 5s ease-in-out infinite",
}}
></div>
<div
className="absolute bottom-6 right-4 w-1 h-1 bg-purple-300 rounded-full"
style={{
animation: "sparkleGentle 12s ease-in-out infinite",
}}
></div>
</div>
{/* 呼吸光暈 */}
<div
className="absolute bottom-0 left-1/2 w-28 h-28 bg-gradient-radial from-cyan-400/20 via-blue-500/10 to-transparent rounded-full blur-xl -z-10"
style={{
transform: "translateX(-50%)",
animation: "auraBreathe 6s ease-in-out infinite",
}}
></div>
</div>
</div>
{/* 動畫說明 */}
<div className="p-4 bg-slate-700/30 rounded-lg">
<h4 className="text-white font-semibold mb-2"></h4>
<ul className="text-blue-200 text-sm space-y-1">
<li>
<strong></strong>6 +
</li>
<li>
<strong></strong>4
</li>
<li>
<strong></strong>6
</li>
<li>
<strong></strong>4
</li>
</ul>
</div>
{/* 動畫狀態顯示 */}
<div className="mt-4 p-3 bg-slate-700/50 rounded-lg">
<div className="flex items-center justify-between">
<span className="text-blue-200 text-sm"></span>
<Badge
className={
animationStatus.includes("✅") ? "bg-green-500/20 text-green-200" : "bg-red-500/20 text-red-200"
}
>
{animationStatus}
</Badge>
</div>
</div>
{/* 內聯 CSS 動畫定義 */}
<style jsx>{`
@keyframes bottleBreathe {
0%, 100% {
transform: translateX(-50%) translateY(0px);
filter: brightness(1);
}
50% {
transform: translateX(-50%) translateY(-3px);
filter: brightness(1.1);
}
}
@keyframes auraBreathe {
0%, 100% {
opacity: 0.2;
transform: translateX(-50%) scale(1);
}
50% {
opacity: 0.4;
transform: translateX(-50%) scale(1.05);
}
}
@keyframes glowPulse {
0%, 100% {
opacity: 0.3;
filter: brightness(1);
}
50% {
opacity: 0.6;
filter: brightness(1.2);
}
}
@keyframes sparkleFloat {
0%, 100% {
transform: translateY(0px) scale(1);
opacity: 0.4;
}
50% {
transform: translateY(-2px) scale(1.1);
opacity: 0.8;
}
}
@keyframes sparkleDrift {
0%, 100% {
transform: translateX(0px) translateY(0px) scale(1);
opacity: 0.3;
}
50% {
transform: translateX(1px) translateY(-1px) scale(1.2);
opacity: 0.7;
}
}
@keyframes sparkleTwinkle {
0%, 100% {
opacity: 0.2;
transform: scale(0.8);
}
50% {
opacity: 0.6;
transform: scale(1.1);
}
}
@keyframes sparkleGentle {
0%, 100% {
opacity: 0.3;
transform: translateY(0px) rotate(0deg);
}
50% {
opacity: 0.6;
transform: translateY(-1px) rotate(180deg);
}
}
`}</style>
</CardContent>
</Card>
</div>
{/* 星光粒子測試區 */}
<Card className="bg-slate-800/50 backdrop-blur-sm border border-blue-700/50 mt-8">
<CardHeader>
<CardTitle className="text-white flex items-center gap-3"> </CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-4 gap-8 text-center">
<div>
<h4 className="text-white font-semibold mb-4">Float </h4>
<div className="relative h-16 flex items-center justify-center">
<div
className="w-3 h-3 bg-cyan-300 rounded-full"
style={{ animation: "sparkleFloat 8s ease-in-out infinite" }}
></div>
</div>
<p className="text-blue-200 text-xs mt-2">8</p>
</div>
<div>
<h4 className="text-white font-semibold mb-4">Drift </h4>
<div className="relative h-16 flex items-center justify-center">
<div
className="w-3 h-3 bg-yellow-300 rounded-full"
style={{ animation: "sparkleDrift 10s ease-in-out infinite" }}
></div>
</div>
<p className="text-blue-200 text-xs mt-2">10</p>
</div>
<div>
<h4 className="text-white font-semibold mb-4">Twinkle </h4>
<div className="relative h-16 flex items-center justify-center">
<div
className="w-3 h-3 bg-pink-300 rounded-full"
style={{ animation: "sparkleTwinkle 5s ease-in-out infinite" }}
></div>
</div>
<p className="text-blue-200 text-xs mt-2">5</p>
</div>
<div>
<h4 className="text-white font-semibold mb-4">Gentle </h4>
<div className="relative h-16 flex items-center justify-center">
<div
className="w-3 h-3 bg-purple-300 rounded-full"
style={{ animation: "sparkleGentle 12s ease-in-out infinite" }}
></div>
</div>
<p className="text-blue-200 text-xs mt-2">12</p>
</div>
</div>
</CardContent>
</Card>
{/* 測試控制區 */}
<Card className="bg-slate-800/50 backdrop-blur-sm border border-blue-700/50 mt-8">
<CardHeader>
<CardTitle className="text-white flex items-center gap-3">🎛 </CardTitle>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-4">
<Button
onClick={() => window.location.reload()}
className="bg-gradient-to-r from-slate-500 to-slate-600 hover:from-slate-600 hover:to-slate-700 text-white"
>
<RotateCcw className="w-4 h-4 mr-2" />
</Button>
<Button
onClick={() => {
playSound("click")
setTimeout(() => playSound("submit"), 500)
setTimeout(() => playSound("success"), 1000)
}}
className="bg-gradient-to-r from-indigo-500 to-purple-600 hover:from-indigo-600 hover:to-purple-700 text-white"
>
🎵
</Button>
<Button
onClick={() => window.open("/", "_blank")}
className="bg-gradient-to-r from-cyan-500 to-blue-600 hover:from-cyan-600 hover:to-blue-700 text-white"
>
🏠
</Button>
</div>
<div className="mt-6 p-4 bg-slate-700/30 rounded-lg">
<h4 className="text-white font-semibold mb-2"></h4>
<ul className="text-blue-200 text-sm space-y-1">
<li>
<code className="bg-slate-600 px-1 rounded">/test</code>
</li>
<li> </li>
<li> 使</li>
<li> </li>
</ul>
</div>
</CardContent>
</Card>
</div>
</main>
</div>
)
}