Parallax Hintergrund in React

#Diese Webseite#Projekte#JavaScript#React#TypeScript

Ein Parallax Hintergrund in React erstellen

Bibliotheken für Parallax

Für die erste Version dieser Website wollte ich einen Weltraum-Themen Parallax Hintergrund erstellen. Nach einer kurzen Google-Suche fand ich einige Bibliotheken, die ich in React verwenden könnte:

Obwohl dies großartige Bibliotheken für die Erstellung von Parallax-Effekten sind, haben sie nicht wirklich meinen Zwecken entsprochen:
  • Ich wollte einen Parallax-Hintergrund erstellen, der als Hintergrund verwendet wird, mit verschiedenen Ebenen, die sich mit unterschiedlichen Geschwindigkeiten bewegen, um den 3D-Raum zu simulieren. Aber es schien, dass spring-parallax besser geeignet war, um Parallax-Effekte in Bannern oder für bewegliche Objekte zu erstellen.
  • Um den 3D-Effekt meines Hintergrunds realistischer zu gestalten, wollte ich, dass die vorderen Ebenen größere Objekte haben als die hinteren. Da ich auch das gleiche Bild für alle Ebenen wiederverwenden wollte, sollte es möglich sein, die Größe des Bildes anzugeben. Das Bild müsste auch über die ganze Seite wiederholt werden, damit man bis zum Ende der Seite scrollen kann und trotzdem einen Hintergrund sieht. Da dies mit <img />-Tags umständlich ist, ist es besser, divs zu verwenden und das background-image zu setzen. Soweit meine Bemühungen gingen, war das mit der react-scroll-parallax-Bibliothek nicht möglich.
  • Daher war die react-parallax-Bibliothek am besten für meinen Anwendungsfall geeignet. Als ich versuchte, sie zu verwenden, funktionierte sie gut für sich allein, verursachte aber Probleme mit meiner bestehenden Website (ich konnte keine mehreren Parallax-Ebenen behalten, die Höhe einer langen Seite beizubehalten, die Verwendung des Inhaltsverzeichnisses auf meinen Blogseiten funktionierte nicht mehr, Glitches usw.) Zu diesem Zeitpunkt war ich so genervt, dass ich beschloss, es schnell selbst zu schreiben, da es eigentlich überhaupt nicht schwierig ist.

Parallax Code

Die erste gut funktionierende Version sah so aus:import React, { useEffect, useRef, useState } from 'react'; export function WithParallax({ children }) { const scroll = useScroll(); const content = useRef(); const h = useElementHeight(content) const height = Math.max(h ? h : 0, window.innerHeight) const w = useElementWidth(content) const width = w && w > 0 ? w : 80 return <div> <Layer speed={0.5} backgroundSize='50%' backgroundColor='#292d3e' url={require('./sterne.png')} /> <Layer speed={0.4} backgroundSize='70%' url={require('./sterne.png')} /> <Layer speed={0.3} backgroundSize='100%' url={require('./sterne.png')}/> <div id="parallaxcontent" ref={content}> {children} </div> </div> function Layer({ speed, backgroundSize = "100%", backgroundColor = "transparent", url=require('./sterne.png') }) { return <div style={{ backgroundColor: backgroundColor, position: "absolute", top: 0, left: 0, overflow: "hidden", zIndex: -20, height: height, width: width }}> <div style={{ height: "2000vh", backgroundImage: 'url(' + url + ')', backgroundSize: backgroundSize, filter: "brightness(100%)", translate: "0px " + (scroll * speed) + "px", }} /> </div>; } } // react hook for getting scroll position on page function useScroll() { const [scrollPosition, setScrollPosition] = useState(0); const handleScroll = () => { const position = window.pageYOffset; setScrollPosition(position); }; useEffect(() => { window.addEventListener('scroll', handleScroll, { passive: true }); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); return scrollPosition; } // Helper functions to get the height and width of the element the parallax is supposed to wrap ( =the whole page) function useElementHeight(ref) { return useElementProp(ref, (el) => el.scrollHeight) } function useElementWidth(ref) { return useElementProp(ref, (el) => el.scrollWidth) } function useElementProp(ref, fn) { const [height, setHeight] = useState(undefined); useEffect(() => { const resizeObserver = new ResizeObserver(entries => { setHeight(fn(ref.current)); }); var toObserve = ref.current resizeObserver.observe(toObserve); return () => { resizeObserver.disconnect(); }; }, []); return height; }

Kommentare

Noch Fragen?