Currently I'm trying to achieve the following parallax effect in React where my image is in a fixed position vertically but moves left to right along with text.
I've used useEffect to achieve this where I take the total height pixels and move my components accordingly. The problem with this is that it looks perfect on my screen, but as soon as I resize it to a bigger or smaller screen the layout gets janky. Is there anyway to have this same effect but responsive friendly. Feel free to edit the CodeSandBox
CodeSandBox(View in fullscreen for better reference): https://codesandbox.io/s/stoic-rumple-s8cr6?file=/src/App.js
Code:
export default function App() {
const [index, setIndex] = useState(false);
const [display, setDisplay] = useState(false);
const [number, setNumber] = useState(false);
const [screen, setScreen] = useState(false);
useEffect(function onFirstMount() {
const changeBackground = () => {
let value = window.scrollY;
console.log(value);
let img = document.getElementById("moveLeft");
let text = document.getElementById("moveUp");
let text2 = document.getElementById("text2");
let text3 = document.getElementById("text3");
let text4 = document.getElementById("text4");
let imgWidth = 280;
text.style.marginTop = "-" + value * 0.5 + "px";
text2.style.transform = `translateX(${value * 1.3}px)`;
text3.style.transform = `translateX(-${value * 1.3}px)`;
text4.style.transform = `translateX(${value * 1.3}px)`;
if (value > 600) {
img.style.transform = `translateX(${value * 0.8 - 480 - imgWidth}px)`;
} else {
img.style.transform = `translateX(-${value * 0.5}px)`;
}
if (value > 1400) {
img.style.transform = `translateX(${
-1 * (value * 0.8 - 1120) + 80 + imgWidth
}px)`;
}
if (value > 1700) {
setNumber(true);
} else {
setNumber(false);
}
if (value > 1100) {
setIndex(true);
} else {
setIndex(false);
}
};
window.addEventListener("scroll", changeBackground);
return () => window.removeEventListener("scroll", changeBackground);
}, []);
return (
<>
<div className="App">
<div className="middletext" id="moveUp" style={{ zIndex: "9" }}>
Random Text
</div>
<div class="inflow">
<div class="positioner">
<div class="fixed" style={{ zIndex: "11" }}>
<div id="moveLeft">
<img
alt="passport"
src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg"
/>
</div>
</div>
</div>
<div className="halfWindow" style={{ zIndex: "8" }}></div>
<div>
<div class="fixedText" style={{ zIndex: "7" }}>
<div id="text2" className="text2">
Random Text
</div>
</div>
</div>
<div className="secondhalfWindow" style={{ zIndex: index ? "10" : "6" }}></div>
<div>
<div
class="secondfixedText"
style={{
zIndex: index ? "9" : "5",
display: "block"
}}
>
<div id="text3" className="text3">
Random Text 2
</div>
</div>
</div>
<div className="thirdhalfWindow" style={{ zIndex: "4" }}></div>
<div>
<div
class="thirdfixedText"
style={{
zIndex: number ? "10" : "3"
}}
>
<div id="text4" className="text4">
Random Text 3
</div>
</div>
</div>
</div>
</div>
</>
Using vw instead of px should work but the calculations are really complex.