Initial commit

This commit is contained in:
2025-07-18 13:07:28 +08:00
commit e3832acfa8
91 changed files with 10929 additions and 0 deletions

488
app/test/page.tsx Normal file
View File

@@ -0,0 +1,488 @@
"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>
)
}