Pause animation when FPS gets too low
Woof, the "Swirl of Power Effect" item tanks my CPU waaay too much
(I bet it's those 7000x7000 PNGs lolol 😬)
Anyway, before thinking about optimizing specific issues, I'm just adding this emergency switch: if we detect FPS < 2 on any layer, we just pause the whole outfit, until the user decides to unpause.
This commit is contained in:
parent
307ab932c8
commit
bb5ec56752
2 changed files with 44 additions and 5 deletions
|
@ -10,6 +10,7 @@ function OutfitMovieLayer({
|
|||
height,
|
||||
isPaused = false,
|
||||
onLoad = null,
|
||||
onLowFps = null,
|
||||
}) {
|
||||
const [stage, setStage] = React.useState(null);
|
||||
const [library, setLibrary] = React.useState(null);
|
||||
|
@ -165,6 +166,8 @@ function OutfitMovieLayer({
|
|||
return;
|
||||
}
|
||||
|
||||
const targetFps = library.properties.fps;
|
||||
|
||||
let lastFpsLoggedAtInMs = performance.now();
|
||||
let numFramesSinceLastLogged = 0;
|
||||
const intervalId = setInterval(() => {
|
||||
|
@ -181,16 +184,20 @@ function OutfitMovieLayer({
|
|||
const roundedFps = Math.round(fps * 100) / 100;
|
||||
|
||||
console.debug(
|
||||
`[OutfitMovieLayer] FPS: ${roundedFps} (Target: ${library.properties.fps}, ${numFramesSinceLastLogged}, ${timeSinceLastFpsLoggedAtInSec}) (${libraryUrl})`
|
||||
`[OutfitMovieLayer] FPS: ${roundedFps} (Target: ${targetFps}) (${libraryUrl})`
|
||||
);
|
||||
|
||||
if (onLowFps && fps < 2) {
|
||||
onLowFps(fps);
|
||||
}
|
||||
|
||||
lastFpsLoggedAtInMs = now;
|
||||
numFramesSinceLastLogged = 0;
|
||||
}
|
||||
}, 1000 / library.properties.fps);
|
||||
}, 1000 / targetFps);
|
||||
|
||||
return () => clearInterval(intervalId);
|
||||
}, [libraryUrl, stage, updateStage, movieClip, library, isPaused]);
|
||||
}, [libraryUrl, stage, updateStage, movieClip, library, isPaused, onLowFps]);
|
||||
|
||||
// This effect keeps the `movieClip` scaled correctly, based on the canvas
|
||||
// size and the `library`'s natural size declaration. (If the canvas size
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
import React from "react";
|
||||
import { Box, DarkMode, Flex, Text, useColorModeValue } from "@chakra-ui/react";
|
||||
import {
|
||||
Box,
|
||||
DarkMode,
|
||||
Flex,
|
||||
Text,
|
||||
useColorModeValue,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import LRU from "lru-cache";
|
||||
import { WarningIcon } from "@chakra-ui/icons";
|
||||
import { ClassNames } from "@emotion/react";
|
||||
|
@ -54,6 +61,9 @@ export function useOutfitPreview({
|
|||
onChangeHasAnimations = null,
|
||||
...props
|
||||
}) {
|
||||
const [isPaused, setIsPaused] = useLocalStorage("DTIOutfitIsPaused", true);
|
||||
const toast = useToast();
|
||||
|
||||
const appearance = useOutfitAppearance({
|
||||
speciesId,
|
||||
colorId,
|
||||
|
@ -70,7 +80,26 @@ export function useOutfitPreview({
|
|||
layersHaveAnimations,
|
||||
} = usePreloadLayers(visibleLayers);
|
||||
|
||||
const [isPaused] = useLocalStorage("DTIOutfitIsPaused", true);
|
||||
const onLowFps = React.useCallback(
|
||||
(fps) => {
|
||||
setIsPaused(true);
|
||||
console.warn(`[OutfitPreview] Pausing due to low FPS: ${fps}`);
|
||||
|
||||
if (!toast.isActive("low-fps-warning")) {
|
||||
toast({
|
||||
id: "low-fps-warning",
|
||||
status: "warning",
|
||||
title: "Sorry, the animation was lagging, so we paused it! 😖",
|
||||
description:
|
||||
"We do this to help make sure your machine doesn't lag too much! " +
|
||||
"You can unpause the preview to try again.",
|
||||
duration: null,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
[setIsPaused, toast]
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (onChangeHasAnimations) {
|
||||
|
@ -100,6 +129,7 @@ export function useOutfitPreview({
|
|||
loadingDelayMs={loadingDelayMs}
|
||||
spinnerVariant={spinnerVariant}
|
||||
onChangeHasAnimations={onChangeHasAnimations}
|
||||
onLowFps={onLowFps}
|
||||
doTransitions
|
||||
isPaused={isPaused}
|
||||
{...props}
|
||||
|
@ -122,6 +152,7 @@ export function OutfitLayers({
|
|||
spinnerVariant = "overlay",
|
||||
doTransitions = false,
|
||||
isPaused = true,
|
||||
onLowFps = null,
|
||||
...props
|
||||
}) {
|
||||
const [hiResMode] = useLocalStorage("DTIHiResMode", false);
|
||||
|
@ -228,6 +259,7 @@ export function OutfitLayers({
|
|||
width={canvasSize}
|
||||
height={canvasSize}
|
||||
isPaused={isPaused}
|
||||
onLowFps={onLowFps}
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
|
|
Loading…
Reference in a new issue