nerdware/apps/web/src/components/boom.tsx
AyoubBenziza c9f3197300 feat(web): real explosion at 0 — fullscreen flash + giant 💥
- store: boomKey counter + boom() action
- Countdown fires boom() once when it reaches 0 (timer expiry only)
- Boom component (portal to body) plays a fullscreen white flash + giant 💥
- rendered at RoomPage level, keyed by boomKey so it plays fully (independent
  of the countdown unmounting on reveal) and replays each round

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:05:42 +02:00

35 lines
1.1 KiB
TypeScript

import { createPortal } from "react-dom"
import { motion } from "framer-motion"
/**
* Explosion plein écran : flash blanc + 💥 géant.
* Rendue dans document.body via portal pour échapper aux transforms parents,
* et montée avec une `key` qui change → l'animation rejoue à chaque boom.
*/
export function Boom() {
return createPortal(
<div className="pointer-events-none fixed inset-0 z-50 flex items-center justify-center overflow-hidden">
<motion.div
className="absolute inset-0 bg-white"
initial={{ opacity: 0 }}
animate={{ opacity: [0, 0.9, 0] }}
transition={{ duration: 0.5, times: [0, 0.12, 1], ease: "easeOut" }}
/>
<motion.span
className="relative leading-none select-none"
style={{ fontSize: "45vmin" }}
initial={{ scale: 0, rotate: -20, opacity: 0 }}
animate={{
scale: [0, 1.35, 1.1],
rotate: [-20, 12, 0],
opacity: [0, 1, 0],
x: [0, 12, -8, 0],
}}
transition={{ duration: 0.8, times: [0, 0.3, 1], ease: "easeOut" }}
>
💥
</motion.span>
</div>,
document.body
)
}