I have two issues.
- Onload, the bottom links should render only once, but they are rendered twice.
- When clicking the box links at the bottom, the current links should smoothly fade out and the new ones fade in. Instead, the new ones initially fade in stacked with the previous ones.
what am I doing wrong here?
Relevant animation code:
export default function DynamicScreen({}: IProps) {
const { screenKey } = useParams()
const [isLeavingScreen, setIsLeavingScreen] = useState(false)
const [screen, setScreen] = useState<IDynamicScreen>()
const [screenLinks, setScreenLinks] = useState<IDynamicScreenLink[]>([])
const navigate = useNavigate()
const isFirstRenderRef = useRef(true)
useEffect(() => {
if (isFirstRenderRef.current) {
isFirstRenderRef.current = false
return
}
}, [])
useEffect(() => {
const loadScreen = async () => {
console.log("Screen - Loading")
const { data: _screen } = await api.getScreen(screenKey!)
setScreen(_screen)
setScreenLinks(
[_screen.link1?.[0], _screen.link2?.[0], _screen.link3?.[0]].filter(
Boolean,
),
)
console.log("Screen - Loaded")
}
loadScreen()
}, [screenKey])
const springApiLory = useSpringRef()
const springLoryStyle = useSpring({
from: { opacity: 0, scale: 0 },
to: { opacity: 1, scale: 1 },
ref: springApiLory,
})
const springApiTitle = useSpringRef()
const springTitleStyle = useSpring({
from: { opacity: 0, transform: "translateY(-25px)" },
to: !isLeavingScreen
? { opacity: 1, transform: "translateY(0)" }
: {
opacity: 0,
transform: "translateY(-25px)",
},
ref: springApiTitle,
})
const springApiScriptHtml = useSpringRef()
const springScriptHtmlStyle = useSpring({
from: { opacity: 0, transform: "translateX(-25px)" },
to: !isLeavingScreen
? { opacity: 1, transform: "translateY(0)" }
: {
opacity: 0,
transform: "translateX(-25px)",
},
ref: springApiScriptHtml,
})
const springApiLinks = useSpringRef()
const linkTransition = useTransition(isLeavingScreen ? [] : screenLinks, {
ref: springApiLinks,
from: { opacity: 0 },
enter: { opacity: 1 },
leave: isLeavingScreen ? { opacity: 0 } : {},
trail: 100,
})
const chain = [
springApiLory,
springApiTitle,
springApiScriptHtml,
springApiLinks,
]
useChain(
!isLeavingScreen ? chain : chain.reverse(),
[...Array(chain.length).keys()].map(calcStaggerDelay),
)
const goToLink = (link: string) => {
setIsLeavingScreen(true)
setTimeout(() => {
setScreenLinks([])
navigate(`/${link}`)
setIsLeavingScreen(false)
}, 1000)
}
if (!screen) return null
return (
<>
<div className="dynamic-screen-top">
<div className="left">
<animated.div style={springTitleStyle}>
<h1>{screen.title}</h1>
</animated.div>
<animated.div style={springScriptHtmlStyle}>
<div
dangerouslySetInnerHTML={{
__html: screen.scriptHtml,
}}
/>
</animated.div>
{/* TODO screen.actions */}
</div>
<animated.div style={springLoryStyle} className="right">
♀️
</animated.div>
</div>
<div className="dynamic-screen-bottom">
{linkTransition((style, screenLink) => (
<animated.div
style={style}
className="dynamic-screen-bottom-link-wrap"
>
<DynamicScreenLink
linkKey={screenLink!.key}
onClick={goToLink}
text={screenLink!.text}
imageUrl={screenLink!.imageUrl}
size={screenLink!.size}
/>
</animated.div>
))}
</div>
</>
)
}
interface IProps {}
const calcStaggerDelay = (i: number) => i * 0.1 + 0.1