Currently what I'm trying to achieve is this, where 1 image moves from left to right as the user scrolls down creating a parallax effect:
Normally with DOM I would use:
let image = document.getElementById("image");
window.addEventListener('scroll', function() {
let value = window.scrollY;
image.style.marginRight = value * 4 + 'px';
image.style.marginTop = value * 1.5 + 'px';
}
But currently I'm trying to replicate this effect in React using setState, but the image doesn't move along with mouse scroll wheel and the layout does not seem right:
CodeSandBox: https://codesandbox.io/s/modest-hill-2wuko?file=/src/App.tsx
Code:
const [leftScroll,setLeftScroll] = useState(false);
const [topScroll,setTopScroll] = useState(false);
const [textScroll, setTextScroll] = useState(false);
useEffect(function onFirstMount() {
const changeBackground = () => {
let value = window.scrollY;
console.log(window.scrollY);
if(value>0 && value<200){
setLeftScroll(true)
setTopScroll(true)
setTextScroll(true);
}else{
setLeftScroll(false)
setTopScroll(false)
setTextScroll(false);
}
}
window.addEventListener('scroll', changeBackground);
return null;
}, []);
return (
<div className="background">
<div style={{backgroundColor:"#0E2043",padding:"50px",height:"1000px",display:"flex",justifyContent:"center"}}>
<div style={{color:"#fff",textAlign:"center",fontSize:"100px",fontFamily:"Roboto", display:"flex",justifyContent:"center"}}>Vanuatu</div>
<img className="image"
style={{marginRight:leftScroll ? '300px' : '0px',transition:"2s",marginTop:topScroll ? "300px" : "0px"}}
src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg"
/>
<div
className="text"
style={{
marginTop: textScroll ? "300px" : "800px",
transition: "4s",
marginLeft: "120px"
}}
>
Minimum Investment
</div>
</div>
</div>
So is there an easier way to do this or can I implement those DOM functions in my React project and still have a parallax like effect?
Top comments (1)
Hi Jay! It looks like your first parallax example without React is using a different approach then what you are attempting to do in your React example.
As pseudocode, example 1 is stating:
"on every single scroll event, set the right margin / top margin to a value computed from the current y scroll value".
Example 2 is stating:
"on every single scroll event, set state for left/top/text to true when the y scroll is between 0 and 200, else set to false," and then you are using css transitions to try to mimic the position of the given parallax elements.
In example 2, the problem is you are setting a boolean on every scroll event and thinking that the css transitions will somehow know the correct margin to be at even though the margin will be hardcoded to either 300px or 0px for the image and 300px or 800px for the div. The transition for the css will occur over a period of time that is in no way linked to the incremental position of your scroll position. Here is a way to visualize it in steps, as a timeline, with example values that represent what is happening:
In the last case, the image will transition to 0px, it will not transition to a point that is relative to the 300px scroll Y value. The image will indeed move across the screen, but not relative to the actual Y value.
To fix this, it's as simple as taking your first example, moving it into your useEffect in the second example, and then setting actual state values for the margin values you want to update as the scroll value changes.
I've updated your codesandbox to included the necessary changes.
codesandbox.io/s/modest-hill-2wuko...
Enjoy!