Image Sequence Player Override in Framer

Image Sequence Player Override in Framer

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

Animation

Image Sequence Player Override in Framer

This is a code override for Framer that you can use to switch between a component's variants as you scroll, thus displaying an animation. Check out how you can use it below.

image of Nandi Muzsik

Created by

Image Sequence Override in Framer
Image Sequence Override in Framer
Image Sequence Override in Framer
Framer Tutorial: Making The AirPods Pro Scroll Animation

Related Lesson

Framer Tutorial: Making The AirPods Pro Scroll Animation

Framer Tutorial: Making The AirPods Pro Scroll Animation

Related Lesson

Framer Tutorial: Making The AirPods Pro Scroll Animation

Framer Tutorial: Making The AirPods Pro Scroll Animation

Related Lesson

Framer Tutorial: Making The AirPods Pro Scroll Animation

About the resource

To use this override, you need to make a component with multiple variants. Each variant is a segment of the image sequence.

To switch the component's variants from "Variant 1" to "Variant 2", and then all the way up to "Variant X" as you scroll through the page, you gotta use the code override. You can check it out below.

Code override for cycling through component's variants on scroll

The VARIANT_LENGTH is important - it should be one more than the total number of variants your component has. The code here uses 66 so remember to adjust that based on your own component's number of variants.

When you scroll down on the web page, the component progressively shows different variants as the component comes into view.

You can even change when the animation starts and ends by tweaking two values named "start 0.1" and "end 0.1".

Go ahead and copy the code, then start creating the override in your Framer project from ground zero.

About the resource

To use this override, you need to make a component with multiple variants. Each variant is a segment of the image sequence.

To switch the component's variants from "Variant 1" to "Variant 2", and then all the way up to "Variant X" as you scroll through the page, you gotta use the code override. You can check it out below.

Code override for cycling through component's variants on scroll

The VARIANT_LENGTH is important - it should be one more than the total number of variants your component has. The code here uses 66 so remember to adjust that based on your own component's number of variants.

When you scroll down on the web page, the component progressively shows different variants as the component comes into view.

You can even change when the animation starts and ends by tweaking two values named "start 0.1" and "end 0.1".

Go ahead and copy the code, then start creating the override in your Framer project from ground zero.

About the resource

To use this override, you need to make a component with multiple variants. Each variant is a segment of the image sequence.

To switch the component's variants from "Variant 1" to "Variant 2", and then all the way up to "Variant X" as you scroll through the page, you gotta use the code override. You can check it out below.

Code override for cycling through component's variants on scroll

The VARIANT_LENGTH is important - it should be one more than the total number of variants your component has. The code here uses 66 so remember to adjust that based on your own component's number of variants.

When you scroll down on the web page, the component progressively shows different variants as the component comes into view.

You can even change when the animation starts and ends by tweaking two values named "start 0.1" and "end 0.1".

Go ahead and copy the code, then start creating the override in your Framer project from ground zero.

import React, { useState, ComponentType, useRef, useEffect } from "react"
import { useScroll, useMotionValueEvent } from "framer-motion"

const VARIANT_LENGTH = 66

export const withScrollVariants = (Component): ComponentType => {
    const variants = Array.from(
        { length: VARIANT_LENGTH },
        (_, i) => `Variant ${i}`
    )

    return (props) => {
        const [variantIndex, setVariantIndex] = useState(0)
        const [imagesLoaded, setImagesLoaded] = useState(false)
        const ref = useRef(null)
        const { scrollYProgress } = useScroll({
            target: ref,
            offset: ["start 0.1", "end 0.1"],
        })

        useEffect(() => {
            const imageSources = []
            document.querySelectorAll("img").forEach((imgElement) => {
                imageSources.push(imgElement.src)
            })

            const imagePromises = imageSources.map((src) => {
                return new Promise((resolve, reject) => {
                    const img = new Image()
                    img.onload = () => resolve(src)
                    img.onerror = () => reject(src)
                    img.src = src
                })
            })

            Promise.all(imagePromises)
                .then(() => setImagesLoaded(true))
                .catch(() => setImagesLoaded(false))
        }, [])

        useEffect(() => {
            const newVariantIndex =
                Math.round(scrollYProgress.current * (VARIANT_LENGTH - 2)) + 1

            setVariantIndex(newVariantIndex)
        }, [scrollYProgress.current])

        useMotionValueEvent(scrollYProgress, "change", (currentProgress) => {
            const newVariantIndex =
                Math.round(scrollYProgress.current * (VARIANT_LENGTH - 2)) + 1

            if (newVariantIndex !== variantIndex && imagesLoaded) {
                setVariantIndex(newVariantIndex)
            }
        })

        return (
            <>
                <div style={{ display: "none" }}>
                    {variants.map((variant) => (
                        <Component key={variant} {...props} variant={variant} />
                    ))}
                </div>
                <Component
                    {...props}
                    variant={variants[variantIndex]}
                    ref={ref}
                />
            </>
        )
    }
}
import React, { useState, ComponentType, useRef, useEffect } from "react"
import { useScroll, useMotionValueEvent } from "framer-motion"

const VARIANT_LENGTH = 66

export const withScrollVariants = (Component): ComponentType => {
    const variants = Array.from(
        { length: VARIANT_LENGTH },
        (_, i) => `Variant ${i}`
    )

    return (props) => {
        const [variantIndex, setVariantIndex] = useState(0)
        const [imagesLoaded, setImagesLoaded] = useState(false)
        const ref = useRef(null)
        const { scrollYProgress } = useScroll({
            target: ref,
            offset: ["start 0.1", "end 0.1"],
        })

        useEffect(() => {
            const imageSources = []
            document.querySelectorAll("img").forEach((imgElement) => {
                imageSources.push(imgElement.src)
            })

            const imagePromises = imageSources.map((src) => {
                return new Promise((resolve, reject) => {
                    const img = new Image()
                    img.onload = () => resolve(src)
                    img.onerror = () => reject(src)
                    img.src = src
                })
            })

            Promise.all(imagePromises)
                .then(() => setImagesLoaded(true))
                .catch(() => setImagesLoaded(false))
        }, [])

        useEffect(() => {
            const newVariantIndex =
                Math.round(scrollYProgress.current * (VARIANT_LENGTH - 2)) + 1

            setVariantIndex(newVariantIndex)
        }, [scrollYProgress.current])

        useMotionValueEvent(scrollYProgress, "change", (currentProgress) => {
            const newVariantIndex =
                Math.round(scrollYProgress.current * (VARIANT_LENGTH - 2)) + 1

            if (newVariantIndex !== variantIndex && imagesLoaded) {
                setVariantIndex(newVariantIndex)
            }
        })

        return (
            <>
                <div style={{ display: "none" }}>
                    {variants.map((variant) => (
                        <Component key={variant} {...props} variant={variant} />
                    ))}
                </div>
                <Component
                    {...props}
                    variant={variants[variantIndex]}
                    ref={ref}
                />
            </>
        )
    }
}
import React, { useState, ComponentType, useRef, useEffect } from "react"
import { useScroll, useMotionValueEvent } from "framer-motion"

const VARIANT_LENGTH = 66

export const withScrollVariants = (Component): ComponentType => {
    const variants = Array.from(
        { length: VARIANT_LENGTH },
        (_, i) => `Variant ${i}`
    )

    return (props) => {
        const [variantIndex, setVariantIndex] = useState(0)
        const [imagesLoaded, setImagesLoaded] = useState(false)
        const ref = useRef(null)
        const { scrollYProgress } = useScroll({
            target: ref,
            offset: ["start 0.1", "end 0.1"],
        })

        useEffect(() => {
            const imageSources = []
            document.querySelectorAll("img").forEach((imgElement) => {
                imageSources.push(imgElement.src)
            })

            const imagePromises = imageSources.map((src) => {
                return new Promise((resolve, reject) => {
                    const img = new Image()
                    img.onload = () => resolve(src)
                    img.onerror = () => reject(src)
                    img.src = src
                })
            })

            Promise.all(imagePromises)
                .then(() => setImagesLoaded(true))
                .catch(() => setImagesLoaded(false))
        }, [])

        useEffect(() => {
            const newVariantIndex =
                Math.round(scrollYProgress.current * (VARIANT_LENGTH - 2)) + 1

            setVariantIndex(newVariantIndex)
        }, [scrollYProgress.current])

        useMotionValueEvent(scrollYProgress, "change", (currentProgress) => {
            const newVariantIndex =
                Math.round(scrollYProgress.current * (VARIANT_LENGTH - 2)) + 1

            if (newVariantIndex !== variantIndex && imagesLoaded) {
                setVariantIndex(newVariantIndex)
            }
        })

        return (
            <>
                <div style={{ display: "none" }}>
                    {variants.map((variant) => (
                        <Component key={variant} {...props} variant={variant} />
                    ))}
                </div>
                <Component
                    {...props}
                    variant={variants[variantIndex]}
                    ref={ref}
                />
            </>
        )
    }
}

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

More resources

More resources

  • Framer website homepage with navigation menu and pixelated project previews showcasing web design tool capabilities

    New

    Animated Navigation Bar in Framer

    Animation

    Framer website homepage with navigation menu and pixelated project previews showcasing web design tool capabilities

    New

    Animated Navigation Bar in Framer

    Animation

    Framer website homepage with navigation menu and pixelated project previews showcasing web design tool capabilities

    New

    Animated Navigation Bar in Framer

    Animation

  • Apple TV Scroll Zoom Animation in Framer

    Apple TV Scroll Zoom Animation in Framer

    Animation

    Apple TV Scroll Zoom Animation in Framer

    Apple TV Scroll Zoom Animation in Framer

    Animation

    Apple TV Scroll Zoom Animation in Framer

    Apple TV Scroll Zoom Animation in Framer

    Animation