0

I am trying to change 'bottom' property and create a parallax effect on scroll. This could be easily done in vanilla JS by adding a scroll listener however react has many working parts and i'm wondering was is the best way to do this that isn't memory intensive? I have a new value being calculated based on window.scrollY. Here is what I have so far, using use/setState() however the scroll event won't even fire.

import { useState } from 'react';
import './App.css';

function App() {

   const [scroll, setScroll] = useState(0)
   const map = (value, x1, y1, x2, y2) => (value - x1) * (y2 - x2) / (y1 - x1) + x2;

   function handleScroll() {
      console.log('scroll')
      let yScroll = window.scrollY;
      let minS = 0;
      let maxS = document.body.scrollHeight;
      let minB = 5 * 50;
      let maxB = 38 * 50;
      let newBottom = map(yScroll, minS, maxS, minB, maxB)
      setScroll(newBottom)
   }

  return (
    <div onScroll={handleScroll} className="App">
      <div className="container">
      <div className="wrapper" style={{bottom: scroll}}>
            <div style={{top: '2em'}} className="disc"></div>
            <div style={{top: '4em'}} className="disc"></div>
            <div style={{top: '6em'}} className="disc"></div>
      </div>
      </div>
    </div>)
)} 

export default App;

CSS

.container  {
   width: 100vw;
   height: 200vh;
   display: flex;
   justify-content: center;
   align-items: center;
   font-size: 50px;
   perspective-origin: center;
   perspective: 17em;
   overflow: hidden;
}



.wrapper {
   bottom: 200px;
   transform-style: preserve-3d;
   transition: all 0.2s ease;
}

.disc {
   position: absolute;
   transform:
      translate(-50%, -50%) rotateX(80deg) scale(1);
   width: 10em;
   height: 10em;
   transform-style: preserve-3d;
   background-image: url('./img/cd3.png');
   background-size: 100% 100%;
}
Laiqa Mohid
  • 461
  • 3
  • 14
  • 1
    Have you checked out answers like these? I think they might be really helpful for your problem: https://stackoverflow.com/q/29725828/14077491 – Jacob K Feb 27 '22 at 21:49
  • I did get i it to work but wondered if this is okay on the performance and memory side of things – Laiqa Mohid Feb 27 '22 at 21:59

1 Answers1

0

I managed to solve it based on comment pointing me to an answer, it's probably not good for memory tho. Using Use Effect and then calling the scroll listening event within it.

  const [scroll, setScroll] = useState(0)
   
   useEffect(() => {
      window.addEventListener("scroll", handleScroll);
      return () => window.removeEventListener("scroll", handleScroll);
   }, [])

   function handleScroll() {
      let yScroll = window.scrollY;
      let minS = 0;
      let maxS = document.body.scrollHeight;
      let minB = 5 * 50;
      let maxB = 38 * 50;
      let newBottom = map(yScroll, minS, maxS, minB, maxB)
      setScroll(newBottom)
   }
<div className="wrapper" style={{bottom: scroll}}>
            <div style={{top: '2em'}} className="disc"></div>
            <div style={{top: '4em'}} className="disc"></div>
            <div style={{top: '6em'}} className="disc"></div>
            <div style={{top: '8em'}} className="disc"></div>
</div>
Laiqa Mohid
  • 461
  • 3
  • 14