Framer Motion Integration
Using a state to do animations can be very expensive in terms of performance.
motion provides a way to control the styles/text without triggering re-renders.
By using the MotionValue with useTransform and motion elements, you can update the value without triggering re-renders.
react-scrollytelling provides a wrapper around useSectionScroll() to update the MotionValue, so you can animate the element based on the scroll progress.
Example
Single Section
You can use useSectionScrollMotionValue() which returned updated MotionValue - scrolledRatioMotionValue based on the scroll progress:
import { useSectionScrollMotionValue } from '@react-scrollytelling/framer-motion';
import { motion, useTransform } from 'motion/react';
export const Section = () => {
const sectionRef = useRef<HTMLDivElement>(null);
const { scrolledRatioMotionValue } = useSectionScrollMotionValue(sectionRef);
// Transform the motion value for opacity
const opacity = useTransform(scrolledRatioMotionValue, (val) => 0.2 + 0.8 * val);
// Transform the motion value for border width
const borderWidth = useTransform(scrolledRatioMotionValue, (val) => `${Math.round(val * 6)}px`);
return (
<>
{/* Use MotionValue with a motion element to change the styles */}
<motion.section
ref={sectionRef}
style={{
opacity,
borderWidth,
}}
>
{/* ... */}
</motion.section>
</>
);
};
Example
- scrolledRatio: 0
Multiple Sections
Example
You can simply the example in track grouped sections and use useActiveSectionMotionValue() to get the active section information and the updated MotionValue based on the scroll progress:
import { useActiveSectionMotionValue } from '@react-scrollytelling/framer-motion';
const { trackingId, scrolledRatioMotionValue } = useActiveSectionMotionValue();
You are viewing section
0
RED
ORANGE
YELLOW
GREEN
BLUE
PURPLE