Add: global factor controlling fps base interval
This commit is contained in:
@@ -17,6 +17,7 @@ type UiSettingsSnapshot = {
|
||||
scale: number;
|
||||
visible: boolean;
|
||||
always_on_top: boolean;
|
||||
tauri_animation_slowdown_factor: number;
|
||||
};
|
||||
|
||||
type UiSpritePackOption = {
|
||||
@@ -33,6 +34,9 @@ const SCALE_MIN = 0.5;
|
||||
const SCALE_MAX = 3.0;
|
||||
const LOGICAL_BASE_FRAME_WIDTH = 512;
|
||||
const LOGICAL_BASE_FRAME_HEIGHT = 512;
|
||||
const SLOWDOWN_FACTOR_MIN = 1;
|
||||
const SLOWDOWN_FACTOR_MAX = 20;
|
||||
const SLOWDOWN_FACTOR_DEFAULT = 3;
|
||||
|
||||
async function invokeSetSpritePack(packIdOrPath: string): Promise<UiSnapshot> {
|
||||
return invoke<UiSnapshot>("set_sprite_pack", { packIdOrPath });
|
||||
@@ -50,6 +54,14 @@ async function invokeSetAlwaysOnTop(alwaysOnTop: boolean): Promise<UiSnapshot> {
|
||||
return invoke<UiSnapshot>("set_always_on_top", { alwaysOnTop });
|
||||
}
|
||||
|
||||
async function invokeAnimationSlowdownFactor(): Promise<number> {
|
||||
return invoke<number>("tauri_animation_slowdown_factor");
|
||||
}
|
||||
|
||||
async function invokeSetAnimationSlowdownFactor(factor: number): Promise<number> {
|
||||
return invoke<number>("set_tauri_animation_slowdown_factor", { factor });
|
||||
}
|
||||
|
||||
function fittedWindowSize(
|
||||
scale: number
|
||||
): { width: number; height: number } {
|
||||
@@ -142,6 +154,7 @@ function MainOverlayWindow(): JSX.Element {
|
||||
const activePackRef = React.useRef<UiSpritePack | null>(null);
|
||||
const loadedPackKeyRef = React.useRef<string | null>(null);
|
||||
const effectiveScaleSyncRef = React.useRef<number | null>(null);
|
||||
const slowdownFactorRef = React.useRef<number>(SLOWDOWN_FACTOR_DEFAULT);
|
||||
const loadingPackRef = React.useRef(false);
|
||||
const mountedRef = React.useRef(false);
|
||||
|
||||
@@ -158,6 +171,7 @@ function MainOverlayWindow(): JSX.Element {
|
||||
}
|
||||
const previousRenderer = rendererRef.current;
|
||||
const nextRenderer = await PixiPetRenderer.create(hostRef.current, pack, nextSnapshot);
|
||||
nextRenderer.setAnimationSlowdownFactor(slowdownFactorRef.current);
|
||||
rendererRef.current = nextRenderer;
|
||||
activePackRef.current = pack;
|
||||
loadedPackKeyRef.current = nextSnapshot.active_sprite_pack;
|
||||
@@ -252,13 +266,18 @@ function MainOverlayWindow(): JSX.Element {
|
||||
Promise.all([
|
||||
invoke<UiSpritePack>("load_active_sprite_pack"),
|
||||
invoke<UiSnapshot>("current_state"),
|
||||
invoke<boolean>("debug_overlay_visible")
|
||||
invoke<boolean>("debug_overlay_visible"),
|
||||
invokeAnimationSlowdownFactor()
|
||||
])
|
||||
.then(async ([pack, initialSnapshot, showDebug]) => {
|
||||
.then(async ([pack, initialSnapshot, showDebug, slowdownFactor]) => {
|
||||
if (!mountedRef.current) {
|
||||
return;
|
||||
}
|
||||
setDebugOverlayVisible(showDebug);
|
||||
slowdownFactorRef.current = Math.min(
|
||||
Math.max(Math.round(slowdownFactor), SLOWDOWN_FACTOR_MIN),
|
||||
SLOWDOWN_FACTOR_MAX
|
||||
);
|
||||
await recreateRenderer(pack, initialSnapshot);
|
||||
await processSnapshot(initialSnapshot);
|
||||
|
||||
@@ -271,9 +290,23 @@ function MainOverlayWindow(): JSX.Element {
|
||||
}
|
||||
setDebugOverlayVisible(Boolean(event.payload));
|
||||
});
|
||||
const unlistenSlowdown = await listen<number>(
|
||||
"runtime:animation-slowdown-factor",
|
||||
(event) => {
|
||||
if (!mountedRef.current) {
|
||||
return;
|
||||
}
|
||||
slowdownFactorRef.current = Math.min(
|
||||
Math.max(Math.round(Number(event.payload)), SLOWDOWN_FACTOR_MIN),
|
||||
SLOWDOWN_FACTOR_MAX
|
||||
);
|
||||
rendererRef.current?.setAnimationSlowdownFactor(slowdownFactorRef.current);
|
||||
}
|
||||
);
|
||||
unlisten = () => {
|
||||
unlistenSnapshot();
|
||||
unlistenDebug();
|
||||
unlistenSlowdown();
|
||||
};
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -406,10 +439,29 @@ function SettingsWindow(): JSX.Element {
|
||||
active_sprite_pack: payload.active_sprite_pack,
|
||||
scale: payload.scale,
|
||||
visible: payload.visible,
|
||||
always_on_top: payload.always_on_top
|
||||
always_on_top: payload.always_on_top,
|
||||
tauri_animation_slowdown_factor:
|
||||
prev.tauri_animation_slowdown_factor ?? SLOWDOWN_FACTOR_DEFAULT
|
||||
};
|
||||
});
|
||||
});
|
||||
const unlistenSlowdown = await listen<number>("runtime:animation-slowdown-factor", (event) => {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
const factor = Math.min(
|
||||
Math.max(Math.round(Number(event.payload)), SLOWDOWN_FACTOR_MIN),
|
||||
SLOWDOWN_FACTOR_MAX
|
||||
);
|
||||
setSettings((prev) =>
|
||||
prev === null ? prev : { ...prev, tauri_animation_slowdown_factor: factor }
|
||||
);
|
||||
});
|
||||
const previousUnlisten = unlisten;
|
||||
unlisten = () => {
|
||||
previousUnlisten();
|
||||
unlistenSlowdown();
|
||||
};
|
||||
})
|
||||
.catch((err) => {
|
||||
if (mounted) {
|
||||
@@ -499,6 +551,29 @@ function SettingsWindow(): JSX.Element {
|
||||
[withPending]
|
||||
);
|
||||
|
||||
const onAnimationSlowdownFactorChange = React.useCallback(
|
||||
async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = Number(event.target.value);
|
||||
if (!Number.isFinite(value)) {
|
||||
return;
|
||||
}
|
||||
const clamped = Math.min(
|
||||
Math.max(Math.round(value), SLOWDOWN_FACTOR_MIN),
|
||||
SLOWDOWN_FACTOR_MAX
|
||||
);
|
||||
const persisted = await withPending(() => invokeSetAnimationSlowdownFactor(clamped));
|
||||
if (persisted === null) {
|
||||
return;
|
||||
}
|
||||
setSettings((prev) =>
|
||||
prev === null
|
||||
? prev
|
||||
: { ...prev, tauri_animation_slowdown_factor: Number(persisted) }
|
||||
);
|
||||
},
|
||||
[withPending]
|
||||
);
|
||||
|
||||
return (
|
||||
<main className="settings-root">
|
||||
<section className="settings-card">
|
||||
@@ -535,6 +610,20 @@ function SettingsWindow(): JSX.Element {
|
||||
onChange={onScaleChange}
|
||||
/>
|
||||
</label>
|
||||
<label className="field">
|
||||
<span>
|
||||
Animation Speed Factor: x{settings.tauri_animation_slowdown_factor}
|
||||
</span>
|
||||
<input
|
||||
type="range"
|
||||
min={SLOWDOWN_FACTOR_MIN}
|
||||
max={SLOWDOWN_FACTOR_MAX}
|
||||
step={1}
|
||||
value={settings.tauri_animation_slowdown_factor}
|
||||
disabled={pending}
|
||||
onChange={onAnimationSlowdownFactorChange}
|
||||
/>
|
||||
</label>
|
||||
<label className="toggle">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
||||
Reference in New Issue
Block a user