"use client"; import { useRef, useState } from "react"; import { AnimatePresence, motion } from "framer-motion"; import { Coins } from "lucide-react"; import Coin3D from "@/components/coin-3d"; import { gsap } from "@/lib/gsap"; import { coinEase } from "@/lib/motion"; import { popConfetti } from "@/lib/confetti"; import { useSound } from "@/components/providers/sound-provider"; import { useLocalStorage } from "@/hooks/use-local-storage"; import { usePrefersReducedMotion } from "@/hooks/use-prefers-reduced-motion"; export default function CoinFlip() { const [frontLabel, setFrontLabel] = useLocalStorage("coin-front", "Kopf"); const [backLabel, setBackLabel] = useLocalStorage("coin-back", "Zahl"); const [history, setHistory] = useState([]); const [flipping, setFlipping] = useState(false); const [result, setResult] = useState(null); const coinRef = useRef(null); const stageRef = useRef(null); const rotationRef = useRef(0); const { play } = useSound(); const reduced = usePrefersReducedMotion(); const front = frontLabel.trim() || "Kopf"; const back = backLabel.trim() || "Zahl"; const flip = () => { if (flipping) return; const isBack = Math.random() < 0.5; const label = isBack ? back : front; setFlipping(true); setResult(null); play("coin"); const current = rotationRef.current; const base = Math.ceil(current / 360) * 360; let target = base + 360 * 5 + (isBack ? 180 : 0); if (target - current < 360 * 4) target += 360; const dur = reduced ? 0.3 : 2.6; gsap.to(coinRef.current, { rotationX: target, duration: dur, ease: reduced ? "power1.out" : coinEase, onComplete: () => { rotationRef.current = target; setFlipping(false); setResult(label); setHistory((h) => [label, ...h].slice(0, 10)); play("pop"); popConfetti(); }, }); if (!reduced) { gsap.to(stageRef.current, { y: -54, duration: dur / 2, yoyo: true, repeat: 1, ease: "power2.out", }); } }; return (
{/* Bühne */}
{result && ( {result}! )}
{flipping ? "Fliegt …" : "Münze werfen"}

Tipp: Du kannst auch direkt auf die Münze tippen.

{/* Einstellungen */}

Seiten beschriften

Z. B. „Ja“ & „Nein“, „Kino“ & „Couch“ – deine Beschriftung bleibt gespeichert.

{history.length > 0 && (

Verlauf

{history.map((entry, i) => ( {entry} ))}
)}
); }