diff --git a/components/Card.tsx b/components/Card.tsx index b27ba9b..91aaea8 100644 --- a/components/Card.tsx +++ b/components/Card.tsx @@ -5,6 +5,7 @@ import { useAppContext } from '@/app/AppContext'; import TiltCard from '@/components/TiltCard'; import ToolTip from '@/components/ToolTip'; import StackTheDeck from '@/components/StackTheDeck'; +import Sheen from '@/components/Sheen'; import getCardInfo from '@/tools/getCardInfo'; import getURL from '@/tools/getURL'; @@ -84,6 +85,7 @@ export default function Card({ card, cardIndex }: CardProps) { onHover={setTooltip} /> )} +
{aria} +
diff --git a/components/Sheen.tsx b/components/Sheen.tsx new file mode 100644 index 0000000..aaf8c92 --- /dev/null +++ b/components/Sheen.tsx @@ -0,0 +1,88 @@ +import { useEffect, useRef, useState } from 'react'; +import { useAppContext } from '@/app/AppContext'; + +const tiltSheen = (sheen: HTMLDivElement, tiltX: number, tiltY: number) => { + const rect = sheen.getBoundingClientRect(); + const centerX = rect.width / 2; + const centerY = rect.height / 2; + const sheenX = centerX + (tiltY / -20) * centerX; + const sheenY = centerY + (tiltX / 20) * centerY; + + sheen.style.opacity = '1'; + sheen.style.backgroundImage = ` + radial-gradient( + circle at + ${sheenX}px ${sheenY}px, + #ffffff44, + #0000000f + ) + `; +}; + +export default function Sheen({ cardIndex, className }: { cardIndex: number; className?: string }) { + const sheenRef = useRef(null); + const [untilt, setUntilt] = useState(false); + const { + gameData, + settings: { tilt, remoteTilt }, + tilt: localTilts, + } = useAppContext(); + + useEffect(() => { + const sheen = sheenRef.current; + if (!sheen) return; + + if (tilt) { + const rotateX = localTilts[cardIndex]?.rotateX || 0; + const rotateY = localTilts[cardIndex]?.rotateY || 0; + + const tilts = remoteTilt + ? [...gameData.tilts[cardIndex], { rotateX, rotateY }] + : [{ rotateX, rotateY }]; + + const { totalX, totalY, count } = tilts + .filter(({ rotateX, rotateY }) => !!rotateX && !!rotateY) + .reduce( + ({ totalX, totalY, count }, { rotateX, rotateY }) => ({ + totalX: totalX + rotateX, + totalY: totalY + rotateY, + count: ++count, + }), + { totalX: 0, totalY: 0, count: 0 }, + ); + + if (count && (totalX || totalY)) { + setUntilt(false); + + const x = totalX / count; + const y = totalY / count; + + tiltSheen(sheen, x, y); + } else { + setUntilt(true); + } + } else { + setUntilt(true); + } + }, [tilt, localTilts, gameData]); + + useEffect(() => { + const sheen = sheenRef.current; + if (!sheen || !untilt) return; + + sheen.style.opacity = '0'; + }, [untilt]); + + return ( +
+ ); +} diff --git a/components/TiltCard.tsx b/components/TiltCard.tsx index f12fb86..8ec6ec0 100644 --- a/components/TiltCard.tsx +++ b/components/TiltCard.tsx @@ -7,24 +7,6 @@ import type { Tilt } from '@/types'; const ZERO_ROTATION = 'rotateX(0deg) rotateY(0deg)'; -const tiltSheen = (sheen: HTMLDivElement, tiltX: number, tiltY: number) => { - const rect = sheen.getBoundingClientRect(); - const centerX = rect.width / 2; - const centerY = rect.height / 2; - const sheenX = centerX + (tiltY / -20) * centerX; - const sheenY = centerY + (tiltX / 20) * centerY; - - sheen.style.opacity = '1'; - sheen.style.backgroundImage = ` - radial-gradient( - circle at - ${sheenX}px ${sheenY}px, - #ffffff44, - #0000000f - ) - `; -}; - export default function TiltCard({ children, cardIndex, @@ -35,7 +17,6 @@ export default function TiltCard({ className?: string; }) { const cardRef = useRef(null); - const sheenRef = useRef(null); const [untilt, setUntilt] = useState(false); const { gameData, @@ -46,8 +27,7 @@ export default function TiltCard({ useEffect(() => { const card = cardRef.current; - const sheen = sheenRef.current; - if (!card || !sheen) return; + if (!card) return; if (tilt) { const rotateX = localTilts[cardIndex]?.rotateX || 0; @@ -75,7 +55,6 @@ export default function TiltCard({ const y = totalY / count; card.style.transform = `rotateX(${x}deg) rotateY(${y}deg)`; - tiltSheen(sheen, x, y); } else { setUntilt(true); } @@ -86,11 +65,9 @@ export default function TiltCard({ useEffect(() => { const card = cardRef.current; - const sheen = sheenRef.current; - if (!card || !sheen || !untilt) return; + if (!card || !untilt) return; card.style.transform = ZERO_ROTATION; - sheen.style.opacity = '0'; }, [untilt]); const handleMouseMove = throttle((e: React.MouseEvent) => { @@ -128,10 +105,6 @@ export default function TiltCard({ className={`h-full w-full transition-transform ${untilt ? 'duration-500' : 'duration-0'}`} > {children} -
);