Initial Commit

This commit is contained in:
Nazareno Oviedo
2022-03-28 15:00:11 -03:00
commit 4aa3fdbc2a
147 changed files with 8710 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
import { useMedia } from 'hooks/use-media'
import * as React from 'react'
import { DURATION, gsap } from '~/lib/gsap'
const AnimationContext = React.createContext<
| {
fontsLoaded: boolean
minInteractionTimeComplete: boolean
prefersReducedMotion: boolean | undefined
shouldAnimate: boolean
}
| undefined
>(undefined)
export const AnimationContextProvider: React.FC = ({ children }) => {
const [fontsLoaded, setFontsLoaded] = React.useState(false)
const [minInteractionTimeComplete, setMinInteractionTimeComplete] =
React.useState(false)
const prefersReducedMotion = useMedia('(prefers-reduced-motion: reduce)')
const shouldAnimate = React.useMemo(
() => fontsLoaded && minInteractionTimeComplete && !prefersReducedMotion,
[fontsLoaded, minInteractionTimeComplete, prefersReducedMotion]
)
React.useEffect(() => {
if (window.fontsReady) {
setFontsLoaded(true)
return
}
const timeout = setTimeout(() => {
setFontsLoaded(true)
}, 500)
try {
document.fonts.ready
.then(() => {
setFontsLoaded(true)
})
.catch((error: unknown) => {
console.error(error)
setFontsLoaded(true)
})
} catch (error) {
console.error(error)
setFontsLoaded(true)
}
return () => {
clearTimeout(timeout)
}
}, [])
React.useEffect(() => {
const timeout = window.setTimeout(() => {
setMinInteractionTimeComplete(true)
}, DURATION * 1000)
return () => {
window.clearTimeout(timeout)
}
}, [])
React.useEffect(() => {
if (fontsLoaded) {
window.fontsReady = true
document.documentElement.classList.add('fonts-ready')
}
}, [fontsLoaded, minInteractionTimeComplete])
React.useEffect(() => {
if (fontsLoaded && minInteractionTimeComplete) {
const timeline = gsap.timeline({
paused: true,
smoothChildTiming: true
})
timeline.to(document.body, {
opacity: 1,
duration: DURATION,
ease: 'BodyFadeIn'
})
timeline.play()
return () => {
timeline.kill()
}
}
}, [fontsLoaded, minInteractionTimeComplete])
return (
<AnimationContext.Provider
value={{
fontsLoaded,
minInteractionTimeComplete,
prefersReducedMotion,
shouldAnimate
}}
>
{children}
<style jsx global>{`
body {
opacity: 0;
will-change: opacity;
}
`}</style>
</AnimationContext.Provider>
)
}
export const useAnimationContext = () => {
const context = React.useContext(AnimationContext)
if (context === undefined) {
throw new Error(
'useAnimationContext must be used within a AnimationContextProvider'
)
}
return context
}