How to detect the scroll progress in a Next.js app

85 views Asked by At

I want a way to detect the scroll progress of the web page and animate the perspective camera (provided by @react-three/drei) on the basis of that scroll progress. I currently have this code inside a separate component called Stars.jsx and is called in another component called Her.jsx which is rendered in the app component:

"use client";
import { useState, useRef, Suspense } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { Points, PointMaterial, Preload } from "@react-three/drei";
import * as random from "maath/random/dist/maath-random.esm";
import { useScroll, useTransform, motion } from "framer-motion";
import { PerspectiveCamera } from "@react-three/drei";
import {
  MotionCanvas,
  LayoutCamera,
} from "framer-motion-3d";

function Camera() {
  const ref = useRef();
  useFrame(({ state, delta, clock }) => {
  });
  return (
    <PerspectiveCamera ref={ref} makeDefault position={[0, 0, 1]} fov={50} />
  );
}

const Stars = (props) => {
  // const { scrollYProgress } = useScroll();
  // let YProgress;
  const ref = useRef();
  // YProgress = useTransform(scrollYProgress, [0, 1], [0, 100]);
  const [sphere] = useState(() =>
    random.inSphere(new Float32Array(5000), { radius: 1.2 }),
  );

  useFrame((state, delta) => {
    ref.current.rotation.x -= delta / 10;
    ref.current.rotation.y -= delta / 15;
  });

  return (
    <group rotation={[0, 0, Math.PI / 4]}>
      <Points ref={ref} positions={sphere} stride={3} frustumCulled {...props}>
        <PointMaterial
          transparent
          color="#f272c8"
          size={0.005}
          sizeAttenuation={true}
          depthWrite={false}
        />
      </Points>
    </group>
  );
};

const StarsCanvas = ({ children }) => {
  return (
    <div className="w-full h-full fixed top-0 left-0 inset-0 z-[-1]">
      <Canvas>
        <Camera />
        <Suspense fallback={null}>
          <Stars />
        </Suspense>
        <Preload all />
      </Canvas>
    </div>
  );
};

export default StarsCanvas;

I tried using gsap and framer motion but I didn't have any previous experience with these libraries so, I wasn't able to get a solution. I also tried a custom function but it didn't work. By the way this was its code:

function getScrollPercentage() {
      const h = document.documentElement,
        b = document.body,
        st = "scrollTop",
        sh = "scrollHeight";
      return ((h[st] || b[st]) / ((h[sh] || b[sh]) - h.clientHeight)) * 100;
    }
0

There are 0 answers