Webentwicklung und mehr

777
Parallaxe Verschiebung im Videospiel Super Marioworld

Eine Anleitung für Parallax Scrolling mit jQuery

Parallax Scrolling bezeichnet den Effekt wenn sich mehrere zweidimensionale Flächen mit unterschiedlichen Geschwindigkeiten bewegen. Ihr erinnert euch vielleicht an alte Sidescroller Videospiele bei denen sich die Hintergrundebenen langsamer bewegen und somit den Anschein von räumlicher Tiefe vermitteln oder Ihr habt parallax Scrolling mal auf irgendwelchen Webseiten gesehen. Ein netter Effekt der sich relativ einfach mit der jQuery Methode scrollTop und einigen Berechnungen in JavaScript realisieren lässt.

In der folgenden Anleitung beschreibe ich wie Ihr eine Internetseite mit parallax Scrolling programmiert. Das Ergebnis findet Ihr auf der parallax Scrolling Demo-Seite. Wenn Ihr euch etwas tiefer mit der Materie beschäftigt werdet Ihr feststellen, dass es unterschiedliche Methoden gibt um parallax Scrolling zu realisieren, die folgende Herangehensweise hat sich in einem Projekt auf der Arbeit allerdings als flüssigste etabliert und ist zudem Fallback-orientiert geschrieben.


Das HTML Gerüst für parallax Scrolling

Zuerst legen wir mehrere Sektionen für die Seite an. Diese dienen (A) dazu unsere Inhalte semantisch zu Strukturieren und (B) um eine grafische Einteilung der Inhalte zu realisieren.

<div class="sektion" id="start">...</div>
<div class="sektion" id="leistungen">...</div>
<div class="sektion" id="kontakt">...</div>

In die Sektionen legen wir jeweils zwei div Container, welche unsere Vorder-, sowie Hintergrundeben bilden.

<div class="sektion" id="start">
	<div class="hintergrundbild"></div>
	<div class="text"></div>
</div>
<div class="sektion" id="leistungen">
	<div class="hintergrundbild"></div>
	<div class="text"></div>
</div>
<div class="sektion" id="kontakt">
	<div class="hintergrundbild"></div>
	<div class="text"></div>
</div>

Dann ergänzen wir Text und Hintergrundbilder.

<div class="sektion" id="start">
	<div class="hintergrundbild">
		<img class="stretch" src="bilder/hintergrundbild_start.jpg" alt="Hintergrundbild Start"/>
	</div>
	<div class="text">
		<h1>Willkommen</h1>
		<p>Hier steht ein einleitender Satz.</p>
	</div>
</div>
<div class="sektion" id="leistungen">
	<div class="hintergrundbild">
		<img class="stretch" src="bilder/hintergrundbild_leistungen.jpg" alt="Hintergrundbild Leistungen"/>
	</div>
	<div class="text">
		<h2>Leistungen</h2>
		<p>Hier steht eine Liste mit Leistungen.</p>
		<ul>
			<li>Leistung</li>
			<li>Service</li>
			<li>Dienst</li>
		</ul>
	</div>
</div>
<div class="sektion" id="kontakt">
	<div class="hintergrundbild">
		<img class="stretch" src="bilder/hintergrundbild_kontakt.jpg" alt="Hintergrundbild Kontakt"/>
	</div>
	<div class="text">
		<h2>Kontakt</h2>
		<p>Hier stehen Kontaktinformationen und eine <a href="mailto:" title="schreiben Sie eine Mail an uns">E-Mail Adresse</a>.</p>
	</div>
</div>

Das schöne ist, dass wir die Elemente nicht großartig verschachteln müssen, sondern einfach eine Seite anlegen die wie ein ganz normaler One-Pager aufgebaut ist.

Nun definieren wir einige Styles für unsere Klassen. Ich habe diese einfach im Header meines HTML Dokuments eingefügt aber Ihr könnt das Stylesheet natürlich auch extern auslagern.


Das CSS Stylesheet für Parallax Scrolling

Mit dem Universalselektor * formatieren wir alle vordefinierten margins und paddings.

* {
	margin: 0;
	padding: 0;
}

Dem body geben wir die Höhe von 100%. Das ist wichtig, denn die innenliegenden Ebenen sollen jeweils eine Browser-Höhe annehmen und richten sich dabei an den Elementen aus, die in der Hierarchie höher liegen.

body {
	height: 100%;
	color: #333;
}

Jeder Sektion verpassen wir nun eine Höhe von 100%. Außerdem vergeben wir ein overflow: hidden; um überstehende Bildteile auszublenden. Die relative Positionierung ist ein muss, damit sich die innenliegenden Blöcke genau ausrichten lassen.

.sektion {
	position: relative;
	height: 100%;
	overflow: hidden;
}

Das Hintergrundbild positionieren wir absolut und richten sie am linken und oberen Rand aus. Für die Höhe und Weite definieren wir jeweils 100%. Das Hintergrundbild liegt somit perfekt über der jeweiligen Sektion. Weil wir den Wert top später mit JavaScript dynamisch berechnen ist es gut, dass er schon da ist.

.hintergrundbild {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 1;
}

Den Textblock positionieren wir ebenfalls absolut, rücken Ihn aber in das Zentrum der Seite. Mittels z-index: 2 erreichen wir, dass er in der grafischen Hierarchie vor unserem Hintergrundbild liegt.

.text {
	position: absolute;
	top: 25%;
	left: 25%;
	width: 50%;
	z-index: 2;
	background-color: #efefef;
}

Mit min-width und min-height erreichen wir, dass das Hintergrundbild die gesamte Fenstergröße einnimmt, ohne seine Proportionen zu ändern.

.hintergrundbild img {
	min-height: 100%;
	min-width: 100%;
}

Das Styling für die Texte ist sporadisch. Ich finde es schöner, wenn die Texte ein wenig Rand bekommen.

.text h1, .text h2, .text p, .text ul {
	margin: 2%;
}

ul {
	list-style: none;
}

Das JavaScript für parallax Scrolling

Nun wird es mathematisch aber keine Sorge, im Grunde wird nur addiert, subtrahiert, multipliziert und dividiert. Anfangs definieren wir ein paar globale, numerische Variablen, auf die von überall aus dem Skript Zugriff besteht. Aller Text hinter den // sind Kommentare aus dem Code, welche ich zur Verständlichkeit belasse.

var fensterHoehe = 0,
	seitenHoehe = 0,
	bewegungsTeiler = 1.3;	// Die Verschiebung der Hintergrundebene entspricht der gescrollten Hoehe geteilt durch diesen Wert.	// bewegungsTeiler = 1.1= 2

Für die Berechnung der Fensterhöhe schreiben wir eine kleine Funktion, die später im Skript aufgerufen wird. In der letzten Zeile übergeben wir den berechneten Wert an unsere Sektionen – weil manche Browser unsere Höhendefinition (100%) aus dem CSS ignorieren beziehungsweise unterschiedlich interpretieren.

function bezieheDimensionen() {
	fensterHoehe = $( window ).height(),
	seitenHoehe = $( document ).height();
    $( '.sektion' ).css('height', fensterHoehe );
}

Um das parallax Scrolling zu berechnen, schreiben wir die folgende Funktion.

function parallaxeVerschiebung() {

	// Prueft die aktuelle Scrollposition
	var gescrollt = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop,

	// Berechnet die gegenwaertige Sektion
	gegenwaertigeSektion = Math.ceil( gescrollt  / fensterHoehe  ),

	// Berechnet den scrollabstand zur naechsten Sektion
	gescrolltInSektion = gescrollt - ( Math.ceil ( fensterHoehe * gegenwaertigeSektion ) ),

	// Berechnet Position des Blocks mit der Klasse "hintergrundbild" für die gegenwaertige Sektion
	bewegungAktiv= Math.round( ( gescrolltInSektion / bewegungsTeiler ) + ( fensterHoehe / bewegungsTeiler ) ),

	// Berechnet Position des Blocks mit der Klasse "hintergrundbild" für die kommende Sektion
	bewegungProaktiv = Math.round( gescrolltInSektion / bewegungsTeiler );

	// Prueft in welcher Sektion wir uns befinden, repositioniert den inneliegenden Block mit der Klasse "hintergrundbild"
	if ( gegenwaertigeSektion == 1 ) {
		$( '#start .hintergrundbild' ).css( 'top', bewegungAktiv );
	} else {
		$( '#start .hintergrundbild' ).css( 'top', bewegungProaktiv );
	};
	if ( gegenwaertigeSektion == 2 ) {
		$( '#leistungen .hintergrundbild' ).css( 'top', bewegungAktiv );
	} else {
		$( '#leistungen .hintergrundbild' ).css( 'top', bewegungProaktiv );
	};
	if ( gegenwaertigeSektion == 3 ) {
		$( '#kontakt .hintergrundbild' ).css( 'top', bewegungAktiv );
    } else {
		$( '#kontakt .hintergrundbild' ).css( 'top', bewegungProaktiv );
	};
}

Somit haben wir alle Funktionen, die für die Berechnung der parallaxen Verschiebung benötigt werden. Wir schreiben eine document.ready Funktion die alles ausführt, nachdem das HTML geladen wurde.

$( document ).ready(function() {

	// Bezieht die Dimensionen für die Berechnung der Parallaxen Verschiebung einmalig
	bezieheDimensionen();

	// Schaut wann gescrollt und führt die Funktion zur parallaxen Verschiebung aus
	$( window ).scroll(function() {
		parallaxeVerschiebung();
	});
});

Ändert sich die Größe des Browser-Fensters, werden die neuen Höhenwerte berechnet. Hierfür nutzen wir das jQuery resize event.

$( window ).resize( function() {
	bezieheDimensionen();
});

Nun haben wir alle Schritte erledigt und eine Seite mit simplem parallax Scrolling programmiert. Das Skript in Aktion seht Ihr auf der Demo-Seite. Alle Dateien (ohne die Bilder) findet Ihr hier zum Download.

13 Antworten zu “Eine Anleitung für Parallax Scrolling mit jQuery” + -

  1. Michael sagt:

    Meiner Erfahrung nach bringen die meisten Paralaxx-Skripte zwar die Funktion mit sich, bei sehr großen oder langen Seiten werden die Ladezeiten allerdings extrem lange. In Zeiten von DSL und Co ist das zwar nicht immer merkbar, wer aber mit UMTS z.B. unterwegs ist merkt das deutlich. Ist euch ein Parallax-Script bekannt, dass auch für dieses Problem eine Lösung parat hat?

  2. Michael sagt:

    Finde diese Lösung für Parallax Scrolling eigentlich gut. Ich habe es ausprobiert, aber leider ruckelt es stark, wenn ich mit dem Mausrad scrolle. Beim verschieben des Scrollbalkens ist alles gut. Ein Tipp wäre super. Danke.

    • Niklas sagt:

      Wie ist das Scrollrad bei Ihrer Maus eingestellt? Bei mir entsteht dieses Ruckeln zum Beispiel weil der Browser beim scrollen in recht großen Schritten springt.

  3. Paul sagt:

    Danke für die einfache Erklärung, kann man viel raus machen!

  4. Michael sagt:

    Hallo Niklas,
    ich wollte das von dir gegebene Tutorial gerne in eine Webseite von uns einbinden.
    Ich habe das ganze um eine weitere Ebene erweitert.

    Allerdings ist mir leider zu spät aufgefallen, dass dein Beispielcode im IE nicht verwendbar ist.
    Vielleicht hast du ja kurz Zeit für mich und kannst mal deine Demoseite im Internet Explorer ansehen.

    Dort ruckelt es leider stark und die Animation ist alles andere als flüssig. Ich habe bereits versucht
    mit einigen Tricks die Animation zum Laufen zu bekommen, allerdings ist es mir bisher nicht gelungen.

    Hast du eine Idee ?

    Grüße
    Michael

    • Niklas sagt:

      Grundsätzlich gibt es verschiede Techniken um Parallax Scrolling zu realisieren. Die „weichsten“ Animationen lassen sich meiner Erfahrung nach mit CSS3 realisieren. Leider wird dieses von älteren Browsern unter anderem IE nicht unterstüzt darum wirst Du bei deinem Problem vermutlich eine JavaScript gestützte Animation benötigen. Google mal nach Parallax Scrolling Plugins, da gibt es mittlerweile gute Lösungen, vielleicht ist auch eine dabei, die in deinem Fall besser „animiert“. Ich werde bei Zeit nochmal etwas näher auf Deine Frage eingehen.

  5. monique sagt:

    Funktioniert auf meinem Tablet nicht optimal
    L.G.M

  6. be flash sagt:

    Das Ruckeln beim IE 11 finde ich schon störend. Suche nach einer Lösung des Problems für ein Projekt und bin somit hier gelandet. Hat da jemand eine Lösung für das Problem?
    Tritt ja nur auf wenn man das Scrollrad der Maus benutzt, beim Verwenden der Scrollbar läuft alles…
    VG

  7. Philipp sagt:

    Meine Frage ist, welche Methode am besten ist für Paralax Scrolling. Entweder mit css3 oder js ? Was sagt ihr dazu ?

  8. kevin sagt:

    Hi.ich bin noch recht unerfahren mit dem programmieren und Probiere mich in diesem Thema gerade ein bisschen aus. Konnte diesen Beitrag gut gebrauchen. Hab’s als Übung erstmal nachgebaut und klappt auch super. Nun will ich einen Schritt weiter gehen und es nach meinen Vorstellungen optimieren und erweitern. Unterteilt ist das Beispiel ja in 3 Sektionen die alle über die eine (die selbe) .sektion=… definiert werden. Also haben auch alle die selbe Höhe, Farbe etc. Jetzt meine Frage. Ist es möglich diese 3 Sektionen unterschiedlich hoch zu gestallten (sektion1 height=100%, sektion2 height=70% ….) obwohl ich alle nur über diese eine class definiere?? die Idee dahinter ist, das ich probieren möchte die 1. sektion 100% vom Fenster zu haben wo dann ein hintergrundbild drin ist und ein vordergrundtext ( wie in der Demo halt) jedoch soll die 2. sektion nur 50% vom Fenster haben. und die 3. wieder 100%. bin ich da jetzt gezwungen für „jede höhe“ eine eigene class zu erstellen und wenn ja wie verändern sich dann
    die funktionen in .js ?? hoffe das mir hier jemand helfen kann. gern auch links zu beiträgen die genau das thema behandeln..

  9. frankeee sagt:

    Tolle Anleitung – strukturiert und mit Hintergrund – vielen Dank!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert