framer-motion#useSpring TypeScript Examples
The following examples show how to use
framer-motion#useSpring.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: parallax.tsx From samuelkraft-next with MIT License | 6 votes |
Parallax = ({ children, offset = 50, clampInitial, clampFinal }: ParallaxProps): JSX.Element => {
const prefersReducedMotion = useReducedMotion()
const [elementTop, setElementTop] = useState(0)
const [clientHeight, setClientHeight] = useState(0)
const ref = useRef(null)
const { scrollY } = useViewportScroll()
const initial = elementTop - clientHeight
const final = elementTop + offset
const yRange = useTransform(scrollY, [initial, final], [clampInitial ? 0 : offset, clampFinal ? 0 : -offset])
const y = useSpring(yRange, { stiffness: 400, damping: 90 })
useLayoutEffect(() => {
const element = ref.current
const onResize = () => {
setElementTop(element.getBoundingClientRect().top + window.scrollY || window.pageYOffset)
setClientHeight(window.innerHeight)
}
onResize()
window.addEventListener('resize', onResize)
return () => window.removeEventListener('resize', onResize)
}, [ref])
// Don't parallax if the user has "reduced motion" enabled
if (prefersReducedMotion) {
return <>{children}</>
}
return (
<motion.div ref={ref} style={{ y }}>
{children}
</motion.div>
)
}
Example #2
Source File: Parallax.tsx From vignette-web with MIT License | 5 votes |
Parallax = ({
children,
id,
offset = 30,
className,
fadeIn,
}: ParallaxProps): JSX.Element => {
const prefersReducedMotion = useReducedMotion()
const [elementTop, setElementTop] = useState(0)
const [clientHeight, setClientHeight] = useState(0)
const ref = useRef<HTMLDivElement>(null)
const { scrollY } = useViewportScroll()
const initial = elementTop - clientHeight
const final = elementTop + offset
const router = useRouter()
const yRange = useTransform(scrollY, [initial, final], [offset, -offset], {
clamp: true,
})
const y = useSpring(yRange, { stiffness: 400, damping: 90 })
useEffect(() => {
const element = ref.current
const onResize = () => {
if (element) {
setElementTop(
element.getBoundingClientRect().top + window.scrollY ||
window.pageYOffset,
)
}
setClientHeight(window.innerHeight)
}
onResize()
window.addEventListener(`resize`, onResize)
return () => window.removeEventListener(`resize`, onResize)
}, [ref, router.pathname])
// Don't parallax if the user has "reduced motion" enabled
if (prefersReducedMotion) {
return <>{children}</>
}
return (
<motion.div
id={id}
className={className}
ref={ref}
style={{ y }}
transition={fadeIn ? { delay: 0.15, duration: 0.3 } : {}}
initial={fadeIn && { opacity: 0 }}
whileInView={fadeIn ? { opacity: 1 } : {}}
viewport={{ once: true }}
>
{children}
</motion.div>
)
}
Example #3
Source File: index.tsx From nosgestesclimat-site with MIT License | 4 votes |
Budget = ({ score, details, headlessMode }) => {
// Configuration is try and test, feeling, really
const valueSpring = useSpring(0, {
mass: 10,
stiffness: 50,
damping: 60,
})
const [value, setValue] = useState(0)
useEffect(() => {
const unsubscribe = valueSpring.onChange((v) => {
setValue(v)
})
headlessMode ? setValue(score) : valueSpring.set(score)
return () => unsubscribe()
})
const backgroundColor = getBackgroundColor(value).toHexString(),
backgroundColor2 = getBackgroundColor(value + 2000).toHexString(),
textColor = findContrastedTextColor(backgroundColor, true),
roundedValue = (value / 1000).toLocaleString('fr-FR', {
maximumSignificantDigits: 2,
minimumSignificantDigits: 2,
}),
integerValue = roundedValue.split(',')[0],
decimalValue = roundedValue.split(',')[1],
shareImage = generateImageLink(window.location)
const { integratorYoutubeVideo, integratorActionText, integratorActionUrl } =
useContext(IframeOptionsContext)
return (
<div>
<Meta
title="Mon empreinte climat"
description={`Mon empreinte climat est de ${roundedValue} tonnes de CO2e. Mesure la tienne !`}
image={shareImage}
url={window.location}
/>
<motion.div
animate={{ scale: [0.9, 1] }}
transition={{ duration: headlessMode ? 0 : 0.6 }}
className=""
id="fin"
css={`
background: ${backgroundColor};
background: linear-gradient(
180deg,
${backgroundColor} 0%,
${backgroundColor2} 100%
);
color: ${textColor};
margin: 0 auto;
border-radius: 0.6rem;
display: flex;
flex-direction: column;
justify-content: space-evenly;
text-align: center;
font-size: 110%;
`}
>
<div id="shareImage" css="padding: 2rem 0 0">
<div css="display: flex; align-items: center; justify-content: center">
<BallonGES css="height: 10rem; width: auto" />
<div
css={`
flex-direction: ${headlessMode ? 'column-reverse' : 'column'};
display: flex;
justify-content: space-evenly;
height: 10rem;
`}
>
<div css="font-weight: bold; font-size: 280%;">
<span css="width: 4rem; text-align: right; display: inline-block">
{integerValue}
{score < 10000 && (
<AnimatePresence>
{(score - value) / score < 0.01 && (
<motion.small
initial={{ opacity: 0, width: 0 }}
animate={{ opacity: 1, width: 'auto' }}
css={`
color: inherit;
font-size: 60%;
`}
>
,{decimalValue}
</motion.small>
)}
</AnimatePresence>
)}
</span>{' '}
tonnes
</div>
<div
css={`
background: #ffffff3d;
border-radius: 0.6rem;
padding: 0.4rem 1rem;
> div {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
strong {
font-weight: bold;
}
> img {
margin: 0 0.6rem !important;
}
`}
>
<div>
<span>
{emoji('?? ')}
moyenne{' '}
</span>{' '}
<strong>
{' '}
<DefaultFootprint />{' '}
</strong>
</div>
<div>
<span>
{emoji('? ')}
objectif{' '}
</span>
<strong>2 tonnes</strong>
</div>
{!headlessMode && (
<div css="margin-top: .2rem;justify-content: flex-end !important">
<a
css="color: inherit"
href="https://datagir.ademe.fr/blog/budget-empreinte-carbone-c-est-quoi/"
target="_blank"
>
Comment ça ?
</a>
</div>
)}
</div>
</div>
</div>
{!integratorActionText && (
<ActionButton text="Passer à l'action" score={score} />
)}
<div css="padding: 1rem">
<Chart
noAnimation
details={details}
links
color={textColor}
noText
noCompletion
valueColor={textColor}
/>
</div>
</div>
<div css="display: flex; flex-direction: column; margin: 1rem 0">
<ShareButton
text="Voilà mon empreinte ?️climat. Mesure la tienne !"
url={window.location}
title={'Nos Gestes Climat'}
color={textColor}
label="Partager mes résultats"
/>
</div>
{integratorActionText && integratorActionUrl && (
<IntegratorActionButton />
)}
{integratorYoutubeVideo && (
<div
class="videoWrapper"
css={`
iframe {
width: 100%;
}
`}
>
<iframe
width="560"
height="315"
src={integratorYoutubeVideo}
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
)}
{integratorActionText && <ActionButton text="Réduire mon empreinte" />}
<DocumentationEndButton ruleName={'bilan'} color={textColor} />
</motion.div>
</div>
)
}