use corner spinner on item page, and fix delay bug
Fading the whole preview to a black overlay for the loading state was feeling aggressive, especially since loading delay wasn't working correctly! In this change, I fix loading delay, and I add a nice subtle "corner" variant for outfit preview spinners :)
This commit is contained in:
parent
c11c2b1394
commit
351b9a88bd
4 changed files with 51 additions and 41 deletions
|
@ -40,7 +40,7 @@ function HomePage() {
|
||||||
colorId={previewState?.colorId}
|
colorId={previewState?.colorId}
|
||||||
pose={previewState?.pose}
|
pose={previewState?.pose}
|
||||||
wornItemIds={[]}
|
wornItemIds={[]}
|
||||||
loadingDelay="1.5s"
|
loadingDelayMs={1500}
|
||||||
placeholder={
|
placeholder={
|
||||||
<Box
|
<Box
|
||||||
as="img"
|
as="img"
|
||||||
|
|
|
@ -383,6 +383,8 @@ function ItemPageOutfitPreview({ itemId }) {
|
||||||
colorId="8"
|
colorId="8"
|
||||||
pose="HAPPY_FEM"
|
pose="HAPPY_FEM"
|
||||||
wornItemIds={[itemId]}
|
wornItemIds={[itemId]}
|
||||||
|
spinnerVariant="corner"
|
||||||
|
loadingDelayMs={2000}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</AspectRatio>
|
</AspectRatio>
|
||||||
|
|
|
@ -86,12 +86,7 @@ function HangerSpinner({ size = "md", ...props }) {
|
||||||
`}
|
`}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<HangerIcon
|
<HangerIcon boxSize={boxSize} color={color} transition="color 0.2s" />
|
||||||
boxSize={boxSize}
|
|
||||||
color={color}
|
|
||||||
transition="color 0.2s"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { css, cx } from "emotion";
|
import { css, cx } from "emotion";
|
||||||
import { CSSTransition, TransitionGroup } from "react-transition-group";
|
import { CSSTransition, TransitionGroup } from "react-transition-group";
|
||||||
import { Box, Flex, DarkMode, Text } from "@chakra-ui/core";
|
import { Box, DarkMode, Flex, Text } from "@chakra-ui/core";
|
||||||
import { WarningIcon } from "@chakra-ui/icons";
|
import { WarningIcon } from "@chakra-ui/icons";
|
||||||
|
|
||||||
import HangerSpinner from "./HangerSpinner";
|
import HangerSpinner from "./HangerSpinner";
|
||||||
|
@ -25,10 +25,11 @@ function OutfitPreview({
|
||||||
speciesId,
|
speciesId,
|
||||||
colorId,
|
colorId,
|
||||||
pose,
|
pose,
|
||||||
appearanceId = null,
|
|
||||||
wornItemIds,
|
wornItemIds,
|
||||||
|
appearanceId = null,
|
||||||
placeholder,
|
placeholder,
|
||||||
loadingDelay,
|
loadingDelayMs,
|
||||||
|
spinnerVariant,
|
||||||
}) {
|
}) {
|
||||||
const { loading, error, visibleLayers } = useOutfitAppearance({
|
const { loading, error, visibleLayers } = useOutfitAppearance({
|
||||||
speciesId,
|
speciesId,
|
||||||
|
@ -55,15 +56,14 @@ function OutfitPreview({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DarkMode>
|
|
||||||
<OutfitLayers
|
<OutfitLayers
|
||||||
loading={loading || loading2}
|
loading={loading || loading2}
|
||||||
visibleLayers={loadedLayers}
|
visibleLayers={loadedLayers}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
loadingDelay={loadingDelay}
|
loadingDelayMs={loadingDelayMs}
|
||||||
|
spinnerVariant={spinnerVariant}
|
||||||
doAnimations
|
doAnimations
|
||||||
/>
|
/>
|
||||||
</DarkMode>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,13 +75,18 @@ export function OutfitLayers({
|
||||||
loading,
|
loading,
|
||||||
visibleLayers,
|
visibleLayers,
|
||||||
placeholder,
|
placeholder,
|
||||||
loadingDelay = "0.5s",
|
loadingDelayMs = 500,
|
||||||
|
spinnerVariant = "overlay",
|
||||||
doAnimations = false,
|
doAnimations = false,
|
||||||
}) {
|
}) {
|
||||||
const [isMounted, setIsMounted] = React.useState(false);
|
const [loadingDelayHasPassed, setLoadingDelayHasPassed] = React.useState(
|
||||||
React.useLayoutEffect(() => {
|
false
|
||||||
setIsMounted(true);
|
);
|
||||||
}, []);
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const t = setTimeout(() => setLoadingDelayHasPassed(true), loadingDelayMs);
|
||||||
|
return () => clearTimeout(t);
|
||||||
|
}, [loadingDelayMs]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
@ -164,14 +169,14 @@ export function OutfitLayers({
|
||||||
zIndex="9000"
|
zIndex="9000"
|
||||||
// This is similar to our Delay util component, but Delay disappears
|
// This is similar to our Delay util component, but Delay disappears
|
||||||
// immediately on load, whereas we want this to fade out smoothly. We
|
// immediately on load, whereas we want this to fade out smoothly. We
|
||||||
// also delay the fade-in by 0.5s, but don't delay the fade-out at all.
|
// also use a timeout to delay the fade-in by 0.5s, but don't delay the
|
||||||
//
|
// fade-out at all. (The timeout was an awkward choice, it was hard to
|
||||||
// We also use `isMounted` here to make sure it actually _fades_ in!
|
// find a good CSS way to specify this delay well!)
|
||||||
// (This starts the opacity at 0, then fires an immediate callback to
|
opacity={loading && loadingDelayHasPassed ? 1 : 0}
|
||||||
// set it to 1, triggering the transition.)
|
transition="opacity 0.2s"
|
||||||
opacity={isMounted && loading ? 1 : 0}
|
|
||||||
transition={`opacity 0.2s ${loading ? loadingDelay : "0s"}`}
|
|
||||||
>
|
>
|
||||||
|
{spinnerVariant === "overlay" && (
|
||||||
|
<>
|
||||||
<Box
|
<Box
|
||||||
position="absolute"
|
position="absolute"
|
||||||
top="0"
|
top="0"
|
||||||
|
@ -181,7 +186,15 @@ export function OutfitLayers({
|
||||||
backgroundColor="gray.900"
|
backgroundColor="gray.900"
|
||||||
opacity="0.7"
|
opacity="0.7"
|
||||||
/>
|
/>
|
||||||
|
{/* Against the dark overlay, use the Dark Mode spinner. */}
|
||||||
|
<DarkMode>
|
||||||
<HangerSpinner />
|
<HangerSpinner />
|
||||||
|
</DarkMode>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{spinnerVariant === "corner" && (
|
||||||
|
<HangerSpinner size="sm" position="absolute" bottom="2" right="2" />
|
||||||
|
)}
|
||||||
</FullScreenCenter>
|
</FullScreenCenter>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue