go on with safari ui optimization

This commit is contained in:
Dmitri 2026-04-16 09:28:57 +04:00
parent 49ca57c63e
commit b40dfe54b5

View File

@ -42,6 +42,7 @@ import { useTransitionPlayback } from '../hooks/useTransitionPlayback';
import { useBackgroundTransition } from '../hooks/useBackgroundTransition';
import { useBackgroundUrls } from '../hooks/useBackgroundUrls';
import { resolveAssetPlaybackUrl } from '../lib/assetUrl';
import { isSafari } from '../lib/browserUtils';
import { logger } from '../lib/logger';
import {
resolveNavigationTarget,
@ -115,6 +116,11 @@ export default function RuntimePresentation({
initialIndex: number;
} | null>(null);
// Safari Black Flash Prevention (video transitions only):
// Track the last successfully displayed background to use as a "snapshot" layer.
// Only shown during video transitions to prevent black flashes.
// NOT shown during crossfade navigation (would interfere with smooth animation).
const [lastKnownBgUrl, setLastKnownBgUrl] = useState<string>('');
const transitionVideoRef = useRef<HTMLVideoElement>(null);
const lastInitializedPageIdRef = useRef<string | null>(null);
@ -344,6 +350,20 @@ export default function RuntimePresentation({
}
}, [pendingTransitionComplete, isBackgroundReady]);
// Safari Black Flash Prevention (video transitions only):
// Update lastKnownBgUrl when a background is successfully displayed.
// This creates a "snapshot" that persists through video transitions.
useEffect(() => {
if (isBackgroundReady && pageSwitch.isNewBgReady) {
if (pageSwitch.currentBgImageUrl) {
setLastKnownBgUrl(pageSwitch.currentBgImageUrl);
}
}
}, [
isBackgroundReady,
pageSwitch.isNewBgReady,
pageSwitch.currentBgImageUrl,
]);
const navigateToPage = useCallback(
async (
@ -554,6 +574,25 @@ export default function RuntimePresentation({
}}
>
<BackdropPortalProvider>
{/* Safari Black Flash Prevention (video transitions only):
Persistent snapshot layer shown ONLY during video transitions.
NOT shown during crossfade navigation (would interfere with animation).
z-[-1] keeps it behind all dynamic content layers. */}
{lastKnownBgUrl &&
isSafari() &&
(transitionPreview || pendingTransitionComplete) && (
<div
className='absolute inset-0 pointer-events-none'
style={{
zIndex: -1,
backgroundImage: `url("${lastKnownBgUrl}")`,
backgroundSize: 'contain',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
}}
/>
)}
{/* Page background wrapper - z-5 keeps it BELOW carousel slide (z-10).
Fades in for non-transition navigation. Uses shared CanvasBackground component
for single source of truth with constructor (same transitions, same structure). */}