Skip rendering layers without a usable image

This happens on the Baby Kougra, where for most poses half of the
assets have a manifest that includes an SVG but no PNG. Skip 'em!

I considered adding a glitch tag for this, but idk I think we can do
that once we're aware of an actual case where this causes visible
issues.
This commit is contained in:
Emi Matchu 2024-02-01 08:55:42 -08:00
parent a4ca9ae522
commit 612cf914e0

View file

@ -215,6 +215,10 @@ export function OutfitLayers({
return () => window.removeEventListener("resize", computeAndSaveCanvasSize); return () => window.removeEventListener("resize", computeAndSaveCanvasSize);
}, [setCanvasSize]); }, [setCanvasSize]);
const layersWithAssets = visibleLayers.filter((l) =>
layerHasUsableAssets(l, { hiResMode }),
);
return ( return (
<ClassNames> <ClassNames>
{({ css }) => ( {({ css }) => (
@ -247,7 +251,7 @@ export function OutfitLayers({
</FullScreenCenter> </FullScreenCenter>
)} )}
<TransitionGroup enter={false} exit={doTransitions}> <TransitionGroup enter={false} exit={doTransitions}>
{visibleLayers.map((layer) => ( {layersWithAssets.map((layer) => (
<CSSTransition <CSSTransition
// We manage the fade-in and fade-out separately! The fade-out // We manage the fade-in and fade-out separately! The fade-out
// happens here, when the layer exits the DOM. // happens here, when the layer exits the DOM.
@ -359,11 +363,17 @@ export function FullScreenCenter({ children, ...otherProps }) {
export function getBestImageUrlForLayer(layer, { hiResMode = false } = {}) { export function getBestImageUrlForLayer(layer, { hiResMode = false } = {}) {
if (hiResMode && layer.svgUrl) { if (hiResMode && layer.svgUrl) {
return layer.svgUrl; return layer.svgUrl;
} else { } else if (layer.imageUrl) {
return layer.imageUrl; return layer.imageUrl;
} else {
return null;
} }
} }
function layerHasUsableAssets(layer, options = {}) {
return getBestImageUrlForLayer(layer, options) != null;
}
/** /**
* usePreloadLayers preloads the images for the given layers, and yields them * usePreloadLayers preloads the images for the given layers, and yields them
* when done. This enables us to keep the old outfit preview on screen until * when done. This enables us to keep the old outfit preview on screen until
@ -397,11 +407,12 @@ export function usePreloadLayers(layers) {
const imageAssetPromises = []; const imageAssetPromises = [];
const movieAssetPromises = []; const movieAssetPromises = [];
for (const layer of layers) { for (const layer of layers) {
const imageAssetPromise = loadImage( const imageUrl = getBestImageUrlForLayer(layer, { hiResMode });
getBestImageUrlForLayer(layer, { hiResMode }), const imageAssetPromise =
{ preferArchive }, imageUrl != null ? loadImage(imageUrl, { preferArchive }) : null;
); if (imageAssetPromise != null) {
imageAssetPromises.push(imageAssetPromise); imageAssetPromises.push(imageAssetPromise);
}
if (layer.canvasMovieLibraryUrl) { if (layer.canvasMovieLibraryUrl) {
// Start preloading the movie. But we won't block on it! The blocking // Start preloading the movie. But we won't block on it! The blocking
@ -424,8 +435,12 @@ export function usePreloadLayers(layers) {
minimalAssetPromises.push( minimalAssetPromises.push(
Promise.any([imageAssetPromise, movieAssetPromise]), Promise.any([imageAssetPromise, movieAssetPromise]),
); );
} else { } else if (imageAssetPromise != null) {
minimalAssetPromises.push(imageAssetPromise); minimalAssetPromises.push(imageAssetPromise);
} else {
console.warn(
`Skipping preloading layer ${layer.id}: no asset URLs found`,
);
} }
} }