fix how it work loading issue
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import React, { useRef, useEffect, useState } from 'react'
|
||||
import React, { useRef, useEffect, useState, useCallback } from 'react'
|
||||
import Experience from './components/Experience'
|
||||
import ScrollRig from './components/ScrollRig'
|
||||
import Navbar from './components/ui/Navbar'
|
||||
@@ -44,7 +44,9 @@ gsap.registerPlugin(ScrollTrigger)
|
||||
* this small component when a section actually enters/leaves its range.
|
||||
*/
|
||||
function StorySections() {
|
||||
const firstActive = useSceneStore((s) => s.scrollProgress >= 0.02 && s.scrollProgress < 0.14)
|
||||
// First Mile is active from the very top (progress 0) so its card is visible
|
||||
// the instant the user enters the section — no scroll required.
|
||||
const firstActive = useSceneStore((s) => s.scrollProgress < 0.14)
|
||||
const midActive = useSceneStore((s) => s.scrollProgress >= 0.38 && s.scrollProgress < 0.50)
|
||||
const lastActive = useSceneStore((s) => s.scrollProgress >= 0.78 && s.scrollProgress < 0.875)
|
||||
const promiseActive = useSceneStore((s) => s.scrollProgress >= 0.90)
|
||||
@@ -59,6 +61,46 @@ function StorySections() {
|
||||
)
|
||||
}
|
||||
|
||||
/** Branded loading state shown over the stage while the GLB scene loads. Never
|
||||
* a blank canvas — fades out once the scene signals ready. */
|
||||
function BrandedLoader({ hidden }) {
|
||||
return (
|
||||
<div
|
||||
className="dm-hiw-3d-loader"
|
||||
aria-hidden={hidden}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
zIndex: 50,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '18px',
|
||||
background: 'linear-gradient(180deg, #f5f5f7 0%, #e9edf2 100%)',
|
||||
opacity: hidden ? 0 : 1,
|
||||
pointerEvents: hidden ? 'none' : 'auto',
|
||||
transition: 'opacity 0.6s ease',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: '50%',
|
||||
border: '3px solid rgba(192,18,39,0.18)',
|
||||
borderTopColor: '#c01227',
|
||||
animation: 'dm-hiw-spin 0.8s linear infinite',
|
||||
}}
|
||||
/>
|
||||
<span style={{ fontWeight: 600, letterSpacing: '0.01em', color: '#1f1f1f', fontSize: '0.95rem' }}>
|
||||
Loading Doormile Experience…
|
||||
</span>
|
||||
<style>{`@keyframes dm-hiw-spin{to{transform:rotate(360deg)}}`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/** Lightweight poster shown when a live scene isn't appropriate/possible. */
|
||||
function StaticFallback() {
|
||||
return (
|
||||
@@ -102,6 +144,10 @@ export default function Experience3D() {
|
||||
const canvasWrapperRef = useRef(null)
|
||||
const [pinState, setPinState] = useState('before')
|
||||
const [mountScene, setMountScene] = useState(false)
|
||||
const [sceneReady, setSceneReady] = useState(false)
|
||||
|
||||
// Stable callback handed to the in-Canvas readiness signal.
|
||||
const handleSceneReady = useCallback(() => setSceneReady(true), [])
|
||||
|
||||
const tier = caps?.tier ?? 'desktop'
|
||||
const useFallback = caps?.fallback ?? false
|
||||
@@ -126,12 +172,9 @@ export default function Experience3D() {
|
||||
return () => io.disconnect()
|
||||
}, [liveScene])
|
||||
|
||||
// Refresh ScrollTrigger once the scene mounts (canvas creation can shift layout).
|
||||
useEffect(() => {
|
||||
if (!mountScene) return
|
||||
const timer = setTimeout(() => ScrollTrigger.refresh(), 150)
|
||||
return () => clearTimeout(timer)
|
||||
}, [mountScene])
|
||||
// (ScrollTrigger refreshing is owned by ScrollRig now — it refreshes on the
|
||||
// next frame, on every layout settle via ResizeObserver/fonts.ready, and again
|
||||
// when `ready` flips true. No arbitrary timeouts.)
|
||||
|
||||
// Smooth scroll — DESKTOP ONLY. Touch devices keep native momentum (native is
|
||||
// smoother than emulated inertia on a heavy WebGL page, and avoids the
|
||||
@@ -216,15 +259,20 @@ export default function Experience3D() {
|
||||
wheelRefs={wheelRefs}
|
||||
dashboardRefs={dashboardRefs}
|
||||
tier={tier}
|
||||
onReady={handleSceneReady}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Branded loader while the GLB loads — no blank canvas. Mounts with the
|
||||
Canvas, fades out the moment the scene is ready. */}
|
||||
{mountScene && <BrandedLoader hidden={sceneReady} />}
|
||||
|
||||
<Navbar />
|
||||
<StorySections />
|
||||
</div>
|
||||
|
||||
<ScrollRig dashboardRefs={dashboardRefs} onPinState={setPinState} tier={tier} />
|
||||
<ScrollRig dashboardRefs={dashboardRefs} onPinState={setPinState} tier={tier} ready={sceneReady} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user