Skip to content

Pausing useTransform / changing bounds during scroll #2775

@aidan-rypens

Description

@aidan-rypens

Hello! Is there a way to 'pause' the useTransform hook any way?

What I'd like to achieve:

  • A strip of boxes that auto sizes depending on the available width of the screen.
  • The last box is only half visible. The next box is half in the screen, half out of the screen.
  • Upon scrolling, the invisible boxes become visible until you reach a point where all boxes are visible / have been visible.

I've tried the following:

Use IntersectionObserver to check when the last box is in view and then alter the range of the transform. So for example, if it was x: -65%, set value as following: useTransform(scrollYProgress, [0, 1], ["-65%", "0%"]).

Implementation, inside hook:

if (entry.isIntersecting && xOffset === initialXOffset) {
   setXOffset(transformation.get());
}

This works, but there is a 'jump' because the initial value (for example -80%) makes it jump.

Is there a way to calculate this or to 'pause' the useTransform or am I using the wrong tool for the job here? Is there a way to calculate this beforehand? Or to 'run' this animation in the background on loading?

image

And when you scroll down, move from right to left:

image

"use client";

import { motion, useScroll, useTransform } from "framer-motion";
import { useRef } from "react";

export default function BoxesScrollStrip() {
  const targetRef = useRef(null);
  const { scrollYProgress } = useScroll({
    target: targetRef,
  });

  // Move the strip from right to left as you scroll down
  const x = useTransform(scrollYProgress, [0, 1], ["-20%", "0%"]);

  return (
    <div ref={targetRef} className="w-full overflow-x-hidden">
      <motion.div style={{ x }} className="flex gap-4 pl-[10%]">
        {Array.from({ length: 3 }).map((_, index) => (
          <div
            key={index}
            className="aspect-[3/2] bg-red-500 w-[35%] flex-shrink-0 flex justify-center items-center text-5xl"
          >
            {index}
          </div>
        ))}
      </motion.div>
    </div>
  );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions