impress-2020/src/app/OutfitPreview.js

112 lines
3 KiB
JavaScript
Raw Normal View History

import React from "react";
2020-04-25 23:17:59 -07:00
import { css } from "emotion";
2020-04-24 00:28:00 -07:00
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { Box, Flex, Icon, Image, Spinner, Text } from "@chakra-ui/core";
2020-04-24 19:16:24 -07:00
import { Delay } from "./util";
import useOutfitAppearance from "./useOutfitAppearance";
2020-04-24 23:13:28 -07:00
/**
* OutfitPreview renders the actual image layers for the outfit we're viewing!
*/
function OutfitPreview({ outfitState }) {
const { loading, error, visibleLayers } = useOutfitAppearance(outfitState);
2020-04-25 07:22:03 -07:00
if (error) {
return (
<FullScreenCenter>
<Text color="gray.50" d="flex" alignItems="center">
<Icon name="warning" />
<Box width={2} />
Could not load preview. Try again?
</Text>
</FullScreenCenter>
);
}
return (
<Box pos="relative" height="100%" width="100%">
2020-04-24 00:28:00 -07:00
<TransitionGroup>
2020-04-24 23:13:28 -07:00
{visibleLayers.map((layer) => (
// We manage the fade-in and fade-out separately! The fade-out
// happens here, when the layer exits the DOM.
2020-04-24 00:28:00 -07:00
<CSSTransition
key={layer.id}
2020-04-25 23:17:59 -07:00
classNames={css`
&-exit {
opacity: 1;
}
&-exit-active {
opacity: 0;
transition: opacity 0.2s;
}
`}
2020-04-24 00:28:00 -07:00
timeout={200}
>
<FullScreenCenter>
<Image
src={layer.imageUrl}
objectFit="contain"
maxWidth="100%"
maxHeight="100%"
// We manage the fade-in and fade-out separately! The fade-in
// happens here, when the <Image> finishes preloading and
// applies the src to the underlying <img>.
2020-04-25 23:17:59 -07:00
className={css`
opacity: 0.01;
&[src] {
opacity: 1;
transition: opacity 0.2s;
}
`}
2020-04-24 23:13:28 -07:00
// This sets up the cache to not need to reload images during
// download!
// TODO: Re-enable this once we get our change into Chakra
// main. For now, this will make Downloads a bit slower, which
// is fine!
// crossOrigin="Anonymous"
2020-04-24 00:28:00 -07:00
/>
</FullScreenCenter>
</CSSTransition>
))}
</TransitionGroup>
{loading && (
<Delay ms={0}>
<FullScreenCenter>
<Box
width="100%"
height="100%"
backgroundColor="gray.900"
opacity="0.8"
/>
</FullScreenCenter>
<FullScreenCenter>
<Spinner color="green.400" size="xl" />
</FullScreenCenter>
</Delay>
)}
</Box>
);
}
function FullScreenCenter({ children }) {
return (
<Flex
pos="absolute"
top="0"
right="0"
bottom="0"
left="0"
alignItems="center"
justifyContent="center"
>
{children}
</Flex>
);
}
export default OutfitPreview;