fix(slideshow): dip-to-white/black no longer flickers the image

The flash overlay had no base opacity and the keyframe animation has fill-mode
none, so after the first dip it reverted to opacity 1 and stayed opaque between
slides — hiding the image, then briefly revealing it on each advance. Set base
opacity 0, and swap the image at the flash peak so the cut stays hidden.
This commit is contained in:
Luca
2026-06-20 03:07:49 +02:00
parent 6ec46de0e7
commit db8388c79e
+23 -8
View File
@@ -127,15 +127,25 @@ export function SlideshowPage() {
if (list.length < 2) return;
const next = (positionRef.current + 1) % list.length;
positionRef.current = next;
const hidden: 0 | 1 = activeRef.current === 0 ? 1 : 0;
setBuffers((prev) => {
const updated: [number, number] = [...prev] as [number, number];
updated[hidden] = next;
return updated;
});
setActive(hidden);
const swap = () => {
const hidden: 0 | 1 = activeRef.current === 0 ? 1 : 0;
setBuffers((prev) => {
const updated: [number, number] = [...prev] as [number, number];
updated[hidden] = next;
return updated;
});
setActive(hidden);
};
const tr = settingsRef.current.transition;
if (tr === 'dipwhite' || tr === 'dipblack') setFlash((f) => f + 1);
if (tr === 'dipwhite' || tr === 'dipblack') {
// Dip: start the white/black flash now, and swap the image at the flash
// PEAK (fully opaque) so the cut is hidden — otherwise the new image is
// visible before the flash covers it, which reads as a flicker.
setFlash((f) => f + 1);
window.setTimeout(swap, Math.max(100, settingsRef.current.transition_ms) / 2);
} else {
swap();
}
}, []);
// ----- Start: gesture-driven (fullscreen needs a user gesture). -----
@@ -392,6 +402,11 @@ export function SlideshowPage() {
inset: 0,
pointerEvents: 'none',
background: settings.transition === 'dipwhite' ? '#fff' : '#000',
// Base opacity 0 so that BEFORE and AFTER the one-shot animation
// (animation-fill-mode defaults to none) the overlay is fully
// transparent. Without this it reverted to opacity 1 and stayed
// opaque between slides, hiding the image repeatedly.
opacity: 0,
animation: `picpeak-dip ${Math.max(200, settings.transition_ms)}ms ease-in-out`,
}}
/>