diff --git a/src/app/WardrobePage/OutfitControls.js b/src/app/WardrobePage/OutfitControls.js
index 4da96ef..3ea60be 100644
--- a/src/app/WardrobePage/OutfitControls.js
+++ b/src/app/WardrobePage/OutfitControls.js
@@ -6,6 +6,7 @@ import {
DarkMode,
Flex,
IconButton,
+ Portal,
Stack,
Tooltip,
useClipboard,
@@ -255,29 +256,111 @@ function CopyLinkButton({ outfitState }) {
function PlayPauseButton() {
const [isPaused, setIsPaused] = useLocalStorage("DTIOutfitIsPaused", true);
+ // We show an intro animation if this mounts while paused. Whereas if we're
+ // not paused, we initialize as if we had already finished.
+ const [blinkInState, setBlinkInState] = React.useState(
+ isPaused ? { type: "ready" } : { type: "done" }
+ );
+ const buttonRef = React.useRef(null);
+
+ React.useLayoutEffect(() => {
+ if (blinkInState.type === "ready" && buttonRef.current) {
+ setBlinkInState({
+ type: "started",
+ position: {
+ left: buttonRef.current.offsetLeft,
+ top: buttonRef.current.offsetTop,
+ },
+ });
+ }
+ }, [blinkInState, setBlinkInState]);
+
return (
- : }
- size="sm"
- color="gray.100"
- variant="outline"
- borderColor="gray.200"
- borderRadius="full"
- backgroundColor="blackAlpha.600"
- boxShadow="md"
- marginTop="0.3rem" // to center-align with buttons (not sure on amt?)
- _hover={{
- backgroundColor: "gray.600",
- borderColor: "gray.50",
- color: "gray.50",
- }}
- onClick={() => setIsPaused(!isPaused)}
- >
- {isPaused ? <>Paused> : <>Playing>}
-
+ <>
+
+ {blinkInState.type === "started" && (
+
+ setBlinkInState({ type: "done" })}
+ // Don't disrupt the hover state of the controls! (And the button
+ // doesn't seem to click correctly, not sure why, but instead of
+ // debugging I'm adding this :p)
+ pointerEvents="none"
+ className={css`
+ @keyframes fade-in-out {
+ 0% {
+ opacity: 0;
+ }
+
+ 10% {
+ opacity: 1;
+ }
+
+ 90% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ }
+ }
+
+ opacity: 0;
+ animation: fade-in-out 2s;
+ `}
+ />
+
+ )}
+ >
);
}
+const PlayPauseButtonContent = React.forwardRef(
+ ({ isPaused, setIsPaused, ...props }, ref) => {
+ return (
+ : }
+ size="sm"
+ color="gray.100"
+ variant="outline"
+ borderColor="gray.200"
+ borderRadius="full"
+ backgroundColor="blackAlpha.600"
+ boxShadow="md"
+ position="absolute"
+ _hover={{
+ backgroundColor: "gray.600",
+ borderColor: "gray.50",
+ color: "gray.50",
+ }}
+ _focus={{
+ backgroundColor: "gray.600",
+ borderColor: "gray.50",
+ color: "gray.50",
+ }}
+ onClick={() => setIsPaused(!isPaused)}
+ {...props}
+ >
+ {isPaused ? <>Paused> : <>Playing>}
+
+ );
+ }
+);
+
/**
* ControlButton is a UI helper to render the cute round buttons we use in
* OutfitControls!