only show play/pause when there are animations
This commit is contained in:
parent
5027a62ec5
commit
53b4d34419
4 changed files with 45 additions and 7 deletions
|
@ -29,7 +29,11 @@ import useOutfitAppearance from "../components/useOutfitAppearance";
|
||||||
* OutfitControls is the set of controls layered over the outfit preview, to
|
* OutfitControls is the set of controls layered over the outfit preview, to
|
||||||
* control things like species/color and sharing links!
|
* control things like species/color and sharing links!
|
||||||
*/
|
*/
|
||||||
function OutfitControls({ outfitState, dispatchToOutfit }) {
|
function OutfitControls({
|
||||||
|
outfitState,
|
||||||
|
dispatchToOutfit,
|
||||||
|
showAnimationControls,
|
||||||
|
}) {
|
||||||
const [focusIsLocked, setFocusIsLocked] = React.useState(false);
|
const [focusIsLocked, setFocusIsLocked] = React.useState(false);
|
||||||
const onLockFocus = React.useCallback(() => setFocusIsLocked(true), [
|
const onLockFocus = React.useCallback(() => setFocusIsLocked(true), [
|
||||||
setFocusIsLocked,
|
setFocusIsLocked,
|
||||||
|
@ -140,11 +144,13 @@ function OutfitControls({ outfitState, dispatchToOutfit }) {
|
||||||
d="inline-flex" // Not sure why <a> requires this to style right! ^^`
|
d="inline-flex" // Not sure why <a> requires this to style right! ^^`
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
{showAnimationControls && (
|
||||||
<Box gridArea="play-pause" display="flex" justifyContent="center">
|
<Box gridArea="play-pause" display="flex" justifyContent="center">
|
||||||
<DarkMode>
|
<DarkMode>
|
||||||
<PlayPauseButton />
|
<PlayPauseButton />
|
||||||
</DarkMode>
|
</DarkMode>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
<Stack
|
<Stack
|
||||||
gridArea="sharing"
|
gridArea="sharing"
|
||||||
alignSelf="flex-end"
|
alignSelf="flex-end"
|
||||||
|
|
|
@ -29,6 +29,10 @@ function WardrobePage() {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const { loading, error, outfitState, dispatchToOutfit } = useOutfitState();
|
const { loading, error, outfitState, dispatchToOutfit } = useOutfitState();
|
||||||
|
|
||||||
|
// Whether the current outfit preview has animations. Determines whether we
|
||||||
|
// show the play/pause button.
|
||||||
|
const [hasAnimations, setHasAnimations] = React.useState(false);
|
||||||
|
|
||||||
usePageTitle(outfitState.name || "Untitled outfit");
|
usePageTitle(outfitState.name || "Untitled outfit");
|
||||||
|
|
||||||
// TODO: I haven't found a great place for this error UI yet, and this case
|
// TODO: I haven't found a great place for this error UI yet, and this case
|
||||||
|
@ -64,12 +68,14 @@ function WardrobePage() {
|
||||||
appearanceId={outfitState.appearanceId}
|
appearanceId={outfitState.appearanceId}
|
||||||
wornItemIds={outfitState.wornItemIds}
|
wornItemIds={outfitState.wornItemIds}
|
||||||
engine="canvas"
|
engine="canvas"
|
||||||
|
onChangeHasAnimations={setHasAnimations}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
controls={
|
controls={
|
||||||
<OutfitControls
|
<OutfitControls
|
||||||
outfitState={outfitState}
|
outfitState={outfitState}
|
||||||
dispatchToOutfit={dispatchToOutfit}
|
dispatchToOutfit={dispatchToOutfit}
|
||||||
|
showAnimationControls={hasAnimations}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
itemsAndSearch={
|
itemsAndSearch={
|
||||||
|
|
|
@ -8,7 +8,13 @@ const EaselContext = React.createContext({
|
||||||
removeResizeListener: () => {},
|
removeResizeListener: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
function OutfitCanvas({ children, width, height, pauseMovieLayers }) {
|
function OutfitCanvas({
|
||||||
|
children,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
pauseMovieLayers = true,
|
||||||
|
onChangeHasAnimations = null,
|
||||||
|
}) {
|
||||||
const [stage, setStage] = React.useState(null);
|
const [stage, setStage] = React.useState(null);
|
||||||
const resizeListenersRef = React.useRef([]);
|
const resizeListenersRef = React.useRef([]);
|
||||||
const canvasRef = React.useRef(null);
|
const canvasRef = React.useRef(null);
|
||||||
|
@ -43,6 +49,14 @@ function OutfitCanvas({ children, width, height, pauseMovieLayers }) {
|
||||||
if (afterFirstDraw) {
|
if (afterFirstDraw) {
|
||||||
stage.on("drawend", afterFirstDraw, null, true);
|
stage.on("drawend", afterFirstDraw, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (onChangeHasAnimations) {
|
||||||
|
const hasAnimations = stage.children.some((c) =>
|
||||||
|
createjsNodeHasAnimations(c)
|
||||||
|
);
|
||||||
|
onChangeHasAnimations(hasAnimations);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: We don't bother firing an update, because we trust the ticker
|
// NOTE: We don't bother firing an update, because we trust the ticker
|
||||||
// to do it on the next frame.
|
// to do it on the next frame.
|
||||||
},
|
},
|
||||||
|
@ -52,6 +66,14 @@ function OutfitCanvas({ children, width, height, pauseMovieLayers }) {
|
||||||
const removeChild = React.useCallback(
|
const removeChild = React.useCallback(
|
||||||
(child) => {
|
(child) => {
|
||||||
stage.removeChild(child);
|
stage.removeChild(child);
|
||||||
|
|
||||||
|
if (onChangeHasAnimations) {
|
||||||
|
const hasAnimations = stage.children.some((c) =>
|
||||||
|
createjsNodeHasAnimations(c)
|
||||||
|
);
|
||||||
|
onChangeHasAnimations(hasAnimations);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: We don't bother firing an update, because we trust the ticker
|
// NOTE: We don't bother firing an update, because we trust the ticker
|
||||||
// to do it on the next frame. (And, I don't understand why, but
|
// to do it on the next frame. (And, I don't understand why, but
|
||||||
// updating here actually paused remaining movies! So, don't!)
|
// updating here actually paused remaining movies! So, don't!)
|
||||||
|
|
|
@ -39,6 +39,7 @@ function OutfitPreview({
|
||||||
loadingDelayMs,
|
loadingDelayMs,
|
||||||
spinnerVariant,
|
spinnerVariant,
|
||||||
engine = "images",
|
engine = "images",
|
||||||
|
onChangeHasAnimations = null,
|
||||||
}) {
|
}) {
|
||||||
const { loading, error, visibleLayers } = useOutfitAppearance({
|
const { loading, error, visibleLayers } = useOutfitAppearance({
|
||||||
speciesId,
|
speciesId,
|
||||||
|
@ -72,6 +73,7 @@ function OutfitPreview({
|
||||||
loadingDelayMs={loadingDelayMs}
|
loadingDelayMs={loadingDelayMs}
|
||||||
spinnerVariant={spinnerVariant}
|
spinnerVariant={spinnerVariant}
|
||||||
engine={engine}
|
engine={engine}
|
||||||
|
onChangeHasAnimations={onChangeHasAnimations}
|
||||||
doTransitions
|
doTransitions
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -89,6 +91,7 @@ export function OutfitLayers({
|
||||||
spinnerVariant = "overlay",
|
spinnerVariant = "overlay",
|
||||||
doTransitions = false,
|
doTransitions = false,
|
||||||
engine = "images",
|
engine = "images",
|
||||||
|
onChangeHasAnimations = null,
|
||||||
}) {
|
}) {
|
||||||
const containerRef = React.useRef(null);
|
const containerRef = React.useRef(null);
|
||||||
const [canvasSize, setCanvasSize] = React.useState(0);
|
const [canvasSize, setCanvasSize] = React.useState(0);
|
||||||
|
@ -158,6 +161,7 @@ export function OutfitLayers({
|
||||||
width={canvasSize}
|
width={canvasSize}
|
||||||
height={canvasSize}
|
height={canvasSize}
|
||||||
pauseMovieLayers={isPaused}
|
pauseMovieLayers={isPaused}
|
||||||
|
onChangeHasAnimations={onChangeHasAnimations}
|
||||||
>
|
>
|
||||||
{visibleLayers.map((layer) =>
|
{visibleLayers.map((layer) =>
|
||||||
layer.canvasMovieLibraryUrl ? (
|
layer.canvasMovieLibraryUrl ? (
|
||||||
|
|
Loading…
Reference in a new issue