Leistungsstarke Parallelisierung

Paul Lewis
Robert Flack
Robert Flack

Ob egal oder ob du sie ungemütlich magst – Entspannung pur. Bei vernünftigem Einsatz Verleihen Sie einer Webanwendung Tiefe und Feinheiten. Das Problem ist jedoch, auf wirkungsvolle Weise zu parsen, kann eine Herausforderung sein. In diesem Artikel erfahren Sie, eine Lösung besprechen, die sowohl leistungsstark browserübergreifend nutzen können.

Parallaxe-Illustration.

Zusammenfassung

  • Verwende keine Scroll-Ereignisse oder background-position, um Parallaxe-Animationen zu erstellen.
  • Verwenden Sie CSS-3D-Transformationen, um einen genaueren Parallaxe-Effekt zu erzeugen.
  • Verwende für Safari in der mobilen Version position: sticky, damit der Parallaxe-Effekt weitergegeben werden.

Wenn Sie die Drop-in-Lösung benötigen, rufen Sie das GitHub-Repository für UI Element Samples auf und kopieren Sie das Parallaxen-Assistent JS Eine Live-Demo des Parallaxe-Scrollers findest du in der GitHub-Repository.

Problem-Parallaxener

Werfen wir zunächst einen Blick auf zwei gängige Methoden, um eine Parallaxe zu erreichen. und vor allem, warum sie für unsere Zwecke nicht geeignet sind.

Schlecht: Scroll-Ereignisse werden verwendet.

Die Hauptanforderung des Parallaxeneffekts besteht darin, dass es scrollbar ist. für jede einzelne Änderung an der Scrollposition der Seite, Position aktualisiert werden soll. Das klingt zwar einfach, aber ein wichtiger Mechanismus moderne Browser sind ihre Fähigkeit, asynchron zu arbeiten. Dies gilt in unseren zum Scrollen von Ereignissen. In den meisten Browsern werden Scroll-Ereignisse als „Best-Effort“ und nicht garantiert für jeden Frame des Scroll-Animation.

Diese wichtige Information verrät uns, warum wir JavaScript-basierte Lösung, die Elemente basierend auf Scroll-Ereignissen verschiebt: JavaScript garantiert jedoch nicht, dass das Parallaxe-Effekt dem der Scrollposition der Seite. In älteren Versionen von Mobile Safari wurden Scroll-Ereignisse am Ende der Schriftrolle ausgeliefert wird, was es unmöglich machte, JavaScript-basierter Scroll-Effekt Neuere Versionen liefern Scroll-Ereignisse. während der Animation, aber, ähnlich wie bei Chrome, zu verstehen. Wenn die Hauptthread mit anderen Aufgaben beschäftigt ist, werden Scroll-Ereignisse nicht zugestellt. Dadurch geht der Parallaxe-Effekt verloren.

Fehlerhaft: background-position wird aktualisiert

Eine weitere Situation, die wir vermeiden möchten, ist das Malen auf jeden Frame. Viele Lösungen Versuchen Sie, background-position zu ändern, um den Parallaxe-Look bereitzustellen, der führt dazu, dass der Browser die betroffenen Teile der Seite beim Scrollen aktualisiert, und dass kann kostspielig sein und zu Verzögerungen bei der Animation führen.

Wenn wir das Versprechen der Parallaxe-Bewegung einhalten möchten, brauchen wir etwas, kann als beschleunigte Property angewendet werden. Das bedeutet heute, Transformationen und Deckkraft).

CSS in 3D

Sowohl Scott Kellum als auch Keith Clark haben bei der Verwendung von CSS 3D zur Umsetzung einer Parallaxe-Bewegung, und verwendet effektiv folgende Technik:

  • Richten Sie ein Element ein, das mit overflow-y: scroll gescrollt werden kann (und wahrscheinlich overflow-x: hidden).
  • Auf dasselbe Element wird ein perspective-Wert und ein perspective-origin-Wert angewendet. auf top left oder 0 0 festgelegt ist.
  • Wenden Sie auf die untergeordneten Elemente dieses Elements eine Übersetzung in Z an und verkleinern Sie sie. um eine Parallaxe-Bewegung zu erzeugen, ohne dass sich dies auf die Bildschirmgröße auswirkt.

Das CSS für diesen Ansatz sieht so aus:

.container {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: scroll;
  perspective: 1px;
  perspective-origin: 0 0;
}

.parallax-child {
  transform-origin: 0 0;
  transform: translateZ(-2px) scale(3);
}

Dabei wird von einem HTML-Snippet wie diesem ausgegangen:

<div class="container">
    <div class="parallax-child"></div>
</div>

Maßstab für Perspektive anpassen

Durch Verschieben des untergeordneten Elements wird es proportional zum Perspektive. Sie können berechnen, wie viel er hochskaliert werden muss, die Gleichung: (Perspektive – Entfernung) ÷ Perspektive. Da wir höchstwahrscheinlich dass das Parallaxe-Element Parallaxe ausgelöst wird, aber in der Größe erscheint, die wir erstellt haben, nicht so zu bleiben, wie sie ist.

Im Fall des obigen Codes ist die Perspektive 1px und der Parameter Der Z-Distanz von parallax-child beträgt -2px. Das bedeutet, dass das Element um 3x hochskaliert werden. Wie Sie sehen, ist der Wert in den Code eingefügt: scale(3)

Für alle Inhalte, für die kein „translateZ“-Wert gilt, kannst du Folgendes tun: einen Wert von null ersetzen. Dies bedeutet, dass die Skala (Perspektive - 0) / mit einem Wert von 1, was bedeutet, dass sie skaliert wurde. weder nach oben noch nach unten. Ziemlich praktisch.

Funktionsweise

Es ist wichtig, klar zu machen, warum dies funktioniert, da wir diese Wissen schnell vermitteln können. Scrollen ist im Grunde eine Transformation. accelerated; hauptsächlich mit dem Verschieben der Schichten mit der GPU. In einer typisches Scrollen, also ohne Perspektive, geschieht 1:1 beim Vergleich des scrollbaren Elements mit seinen untergeordneten Elementen. Wenn Sie ein Element um 300px nach unten scrollen, werden die untergeordneten Elemente nach oben transformiert. um denselben Betrag: 300px.

Das Anwenden eines Perspektivwerts auf das Scrollelement führt jedoch zu Problemen. mit diesem Prozess; ändert sie die Matrizen, die der Scroll-Transformation zugrunde liegen. Bei einem Scrollen von 300 Pixeln werden die untergeordneten Elemente jetzt nur um 150 Pixel verschoben, je nachdem, Die von Ihnen ausgewählten Werte perspective und translateZ. Wenn ein Element über translateZ-Wert 0 hat, wird wie gewohnt bei 1:1 gescrollt, aber ein untergeordnetes Element vom perspektivischen Ursprungsort weggedrückt wird, wird mit einer anderen bewerten! Das Ergebnis: Parallaxe-Bewegung. Wichtig ist, dass dies so gehandhabt wird, Teil der internen Scroll-Maschine des Browsers. Das bedeutet, Sie müssen weder scroll-Ereignisse überwachen noch background-position ändern.

Eine Fliege: Mobile Safari

Jeder Effekt hat Nachteile, aber bei Transformationen ist es wichtig, die Beibehaltung von 3D-Effekten auf untergeordnete Elemente. Wenn Elemente in der eine Hierarchie zwischen dem Element mit einer Perspektive und seinen Parallaxe-untergeordneten Elementen, wird die 3D-Perspektive abgeflacht, das heißt, der Effekt geht verloren.

<div class="container">
    <div class="parallax-container">
    <div class="parallax-child"></div>
    </div>
</div>

Im obigen HTML-Code ist das .parallax-container neu und wird effektiv Wenn wir den perspective-Wert vereinfachen, geht der Parallaxe-Effekt verloren. Die Lösung: In den meisten Fällen ist das ziemlich einfach: Sie fügen transform-style: preserve-3d hinzu. auf das Element zu übertragen, wodurch es alle 3D-Effekte (wie unsere Perspektive) -Wert), die weiter oben in der Baumstruktur angewendet wurden.

.parallax-container {
  transform-style: preserve-3d;
}

Im Fall von Mobile Safari ist das Ganze jedoch etwas komplizierter. Die Anwendung von overflow-y: scroll auf das Containerelement funktioniert technisch, aber bei die Kosten dafür, das Scrolling-Element zu betätigen. Die Lösung besteht darin, -webkit-overflow-scrolling: touch, wodurch aber auch perspective vereinfacht wird sodass wir keine Abstriche machen können.

Im Hinblick auf Progressive Enhancement ist dies wahrscheinlich keine große Problem. Wenn wir nicht in jeder Situation eine Parallaxe durchführen können, funktioniert unsere App zwar trotzdem, würde ich mich freuen, wenn Sie eine Problemumgehung finden könnten.

position: sticky zur Rettung!

Es gibt tatsächlich Hilfe in Form von position: sticky, die dazu dient, Elemente zu fixieren im Darstellungsbereich oder einem bestimmten übergeordneten Element hinzugefügt werden. während des Scrollens. Die Spezifikation ist, wie die meisten, ziemlich gut, aber sie enthält eine eine kleine Kleinigkeit:

Auf den ersten Blick scheint dies nicht viel zu bedeuten, aber es ist ein wichtiger Punkt wenn sich dieser Satz darauf bezieht, wie genau die „Stickiness“ eines Elements berechnet: "Der Offset wird mit Verweis auf den nächsten Ancestor berechnet. mit einem Bildlauffeld“. Mit anderen Worten, die Entfernung, um das fixierte Element zu bewegen, damit es an ein anderes Element oder den Darstellungsbereich angehängt erscheint. berechnet, bevor andere Transformationen angewendet werden, nicht nach. Das bedeutet, dass, ähnlich wie im obigen Beispiel für das Scrollen, wenn der Offset berechnet wird, bei 300 Pixeln gibt es eine neue Möglichkeit, verschiedene Perspektiven einzubringen um diesen 300-Pixel-Versatzwert zu bearbeiten, bevor er auf fixierte Elemente.

Durch die Anwendung von position: -webkit-sticky auf das Parallaxenelement effektiv „umkehren“ der Abflachungseffekt von -webkit-overflow-scrolling: touch. Dadurch wird sichergestellt, dass das Parallaxenelement auf das nächstgelegene Ancestor mit einem Scrollfeld, in diesem Fall .container. Gehen Sie dann so vor: Ähnlich wie zuvor wendet .parallax-container einen perspective-Wert an, wodurch der berechnete Scroll-Offset geändert und ein Parallaxe-Effekt erzeugt wird.

<div class="container">
    <div class="parallax-container">
    <div class="parallax-child"></div>
    </div>
</div>
.container {
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
}

.parallax-container {
  perspective: 1px;
}

.parallax-child {
  position: -webkit-sticky;
  top: 0px;
  transform: translate(-2px) scale(3);
}

Dadurch wird der Parallaxe-Effekt für Mobile Safari wiederhergestellt. Runde!

Hinweise zur fixierten Positionierung

Es gibt hier jedoch einen Unterschied: position: sticky ändert den Parameter der Parallaxe-Mechanik. Bei der fixierten Positionierung wird versucht, das Element im Gegensatz zu einer nicht fixierten Version. Das bedeutet, dass der Parallaxe mit Klebstoff ist der Kehrwert der ohne:

  • Bei position: sticky ist der Abstand zwischen dem Element und z=0, je kleiner es ist bewegt.
  • Ohne position: sticky ist der Abstand zwischen dem Element zu z=0, umso mehr bewegt.

Wenn Ihnen das alles etwas abstrakt erscheint, sehen Sie sich diese Demo von Robert Flack an. Hier wird gezeigt, wie sich Elemente mit und ohne fixierte Positionierung. Um den Unterschied zu sehen, benötigst du Chrome Canary, also Version 56 als dieser Artikel verfasst wurde) oder Safari.

Screenshot: Parallaxe-Perspektive

Eine Demo von Robert Flack, die zeigt, wie position: sticky wirkt sich auf das Parallaxen-Scrollen aus.

Verschiedene Programmfehler und Behelfslösungen

Wie bei jedem anderen müssen jedoch auch kleine Unebenheiten behoben werden. geglättet über:

  • Fixierte Unterstützung ist inkonsistent. Support ist noch in der Chrome, Edge wird aber überhaupt nicht unterstützt und in Firefox werden Bildfehler in Kombination mit fixierten Bildern und perspektivischen Transformationen angezeigt. In solchen Fällen ist es sinnvoll, nur ein wenig Code hinzuzufügen, um nur position: sticky (die Version mit dem Präfix -webkit-), wenn dies erforderlich ist: für Safari Mobile .
  • Der Effekt „funktioniert nicht einfach“ in Edge. Edge versucht, das Scrollen was im Allgemeinen gut ist, aber in diesem Fall verhindert, Änderungen der Perspektive beim Scrollen zu erkennen. Um das Problem zu beheben, ein Element mit fester Position, da dadurch Edge zu einer Scrollmethode ohne Betriebssystem zu wechseln scheint. und stellt sicher, dass Änderungen der Perspektive berücksichtigt werden.
  • „Der Inhalt der Seite ist einfach riesig!“ Viele Browser haben diese Größenordnung ausgemacht wie groß der Seiteninhalt ist. Leider kam Chrome oder Safari berücksichtigen Sie die Perspektive. Also wenn beispielsweise eine Skala von 3x auf ein Element angewendet wird, Bildlaufleisten und Ähnliches sehen, auch wenn sich das Element 1x nach dem „perspective“ wurde angewendet. Dieses Problem lässt sich umgehen, Skalieren von Elementen von der unteren rechten Ecke aus (mit transform-origin: bottom right). Dies funktioniert, da übergroße Elemente in die „ausschließende Region“ (normalerweise oben links) des scrollbaren Bereichs. scrollbar In Regionen können Sie Inhalte im negativen Bereich nicht sehen oder dorthin scrollen.

Fazit

Die Parallaxe macht Spaß, wenn sie wohlüberlegt eingesetzt wird. Wie Sie sehen, ist es möglich, um ihn leistungsfähig, mit Scrollen sichtbar und browserübergreifend zu implementieren. Da hierfür etwas mathematisches Wriggling und mit Textbausteinen, um den gewünschten Effekt zu erzielen, haben wir eine kleine und das Beispiel, das Sie im GitHub-Repository für UI-Elemente-Beispiele finden.

Lass uns wissen, wie es dir gefällt.