Skuteczna paralaksa

Robert Flack
Robert Flack

Czy to się kocha, czy nienawidzi, paralaksa pozostanie w naszej mocy. Właściwie wykorzystywana może aby nadać aplikacji internetowej głębię i subtelność. Problemem jest jednak to, że wdrożenie i efektywną paralaksę może być wyzwaniem. W tym artykule omówimy Omówić skuteczne, a także skuteczne rozwiązanie, w różnych przeglądarkach.

Ilustracja z paralaksą.

TL;DR

  • Nie używaj zdarzeń przewijania ani parametru background-position do tworzenia animacji paralaksy.
  • Aby uzyskać dokładniejszy efekt paralaksy, użyj przekształceń CSS 3D.
  • W przeglądarce mobilnej Safari użyj parametru position: sticky, by zapewnić efekt paralaksy. nie jest rozpowszechniana.

Jeżeli potrzebujesz tego rozwiązania, przejdź do repozytorium GitHub z przykładowymi elementami interfejsu i pobierz Asystent paralaksy JS! Prezentację na żywo mechanizmu przewijania paralaksy znajdziesz w repozytorium GitHub.

Paralaksery do zadań

Na początek przyjrzyjmy się 2 popularnym sposobom na uzyskanie paralaksy: a w szczególności dlaczego są one nieodpowiednie do naszych celów.

Błąd: używasz zdarzeń przewijania

Najważniejszym wymaganiem w przypadku paralaksacji jest to, aby była połączona z przewijaniem. w przypadku każda zmiana pozycji przewijania strony, efekt paralaksy należy zaktualizować pozycję. Choć brzmi to prosto, ważnym mechanizmem nowoczesnych przeglądarek to zdolność do pracy asynchronicznej. Ma to zastosowanie w przypadku konkretnego przypadku, aby przewijać zdarzenia. W większości przeglądarek są dostarczane zdarzenia przewijania w ramach najlepszych starań, i nie są gwarantowane, aby były wyświetlane w każdej klatce animacja przewijania!

Ta ważna informacja mówi nam, dlaczego musimy unikać Rozwiązanie oparte na języku JavaScript, które przenosi elementy na podstawie zdarzeń przewijania: JavaScript nie gwarantuje, że paralaksa będzie współpracowała z pozycję przewijania na stronie. W starszych wersjach Mobile Safari zdarzenia przewijania były została wyświetlona na końcu przewijania, co uniemożliwiło Efekt przewijania oparty na języku JavaScript. Nowsze wersje obsługują zdarzenia przewijania w trakcie animacji, ale, podobnie jak w przypadku Chrome, w miarę możliwości podstaw. Jeśli wątek główny jest zajęty czymś innym, zdarzenia przewijania nie zostaną dostarczone co oznacza, że efekt paralaksy zostanie utracony.

Błąd: aktualizuję aplikację background-position

Inną sytuacją, której chcemy uniknąć, jest malowanie każdej klatki. Wiele rozwiązań możesz spróbować zmienić background-position, aby uzyskać wygląd paralaksy, powoduje ponowne wyrenderowanie problematycznych części strony podczas przewijania, może być tak kosztowna, że może znacznie zaburzyć animację.

Jeśli zależy nam na stworzeniu ruchu paralaksy, można zastosować jako właściwość przyspieszoną (co obecnie oznacza pozostawanie przekształcenia i przezroczystości), które nie bazują na zdarzeniach przewijania.

CSS w 3D

Zarówno Scott Kellum, jak i Keith Clark uzyskały Wykorzystaliśmy narzędzia CSS 3D do uzyskania ruchu paralaksy, a ich technika jest następująca:

  • Skonfiguruj element zawierający, aby przewijać za pomocą overflow-y: scroll (i prawdopodobnie overflow-x: hidden).
  • Do tego samego elementu zastosuj wartości perspective i perspective-origin ustawiono na top left lub 0 0.
  • Do elementów podrzędnych tego elementu zastosuj tłumaczenie w formacie Z i zmniejsz je. aby zapewnić ruch paralaksy bez wpływu na ich rozmiar na ekranie.

Kod CSS w tym podejściu wygląda tak:

.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);
}

Zakładamy, że fragment kodu HTML wygląda tak:

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

Dostosowywanie skali do perspektywy

Wypchnięcie elementu podrzędnego z powrotem spowoduje zmniejszenie jego proporcji z perspektywy marki. Możesz obliczyć, ile trzeba będzie przeskalować w górę to równanie: (perspektywa – odległość) / perspektywa. Ponieważ najprawdopodobniej chcesz, aby element paralaksy miał postać paralaksy, ale był w rozmiarze, który napisaliśmy, w ten sposób należy go rozbudować, a nie pozostawić w niezmienionej formie.

W przypadku tego kodu perspektywa to 1px, a parametr Odległość na osi parallax-child wynosi -2 piks.. Oznacza to, że element będzie musiał do skalowania do 3x, co widać w kodzie: scale(3)

W przypadku treści, które nie mają przypisanej wartości translateZ, można: podstawić wartość zero. Oznacza to, że skala to (perspektywa - 0) / z perspektywy, która daje wartość 1, co oznacza, że została przeskalowana. ani w górę, ani w dół. Naprawdę przydatny.

Jak to działa

Potrzebujemy jasnego wyjaśnienia, dlaczego tak działa, ponieważ będziemy używać tego wiedzę. Przewijanie to w zasadzie przekształcanie, dlatego accelerated; polega głównie na przemieszczaniu warstw za pomocą GPU. W typowego przewijania, czyli takiego, który nie ma pojęcia o perspektywie, w stosunku 1:1 przy porównywaniu przewijanego elementu i jego elementów podrzędnych. Jeśli przewiniesz element w dół o 300px, jego elementy podrzędne zostaną przekształcone w górę o tę samą kwotę: 300px.

Jednak zastosowanie wartości perspektywicznej do przewijanego elementu sprawia, że w tym procesie. zmienia macierze, na których opiera się przekształcenie przewijania. Teraz przewijanie o 300 pikseli może przesunąć elementy podrzędne tylko o 150 pikseli w zależności od perspective i translateZ wybrane przez Ciebie wartości. Jeśli element ma atrybut translateZ o wartości 0, będzie przewijany o współczynniku 1:1 (tak jak wcześniej), ale będzie przewinięty przesunięte w pozycję Z w dal od punktu początkowego, zostanie przewinięte w innym miejscu. stawki. Wynik netto: ruch paralaksy. Bardzo ważne jest to, automatycznie wchodzą w skład wewnętrznego systemu przewijania w przeglądarce, co oznacza, że nie trzeba nasłuchiwać zdarzeń scroll ani zmieniać elementu background-position.

Muszka w kształcie mazi: Mobile Safari

Każdy efekt wiąże się z pewnymi zastrzeżeniami. Jednym z najważniejszych czynników, które dotyczy przekształceń, zachowywanie efektów 3D w elementach podrzędnych. Jeśli w kolumnie między elementem z perspektywą a paralaksującymi elementami podrzędnymi, perspektywa 3D jest „spłaszczona”, co oznacza, że efekt jest tracony.

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

W powyższym kodzie HTML obiekt .parallax-container jest nowy i będzie skutecznie spłaszcz wartość perspective, co spowoduje utratę efektu paralaksy. Rozwiązaniem jest w większości przypadków jest dość proste: dodajesz transform-style: preserve-3d powodując rozprzestrzenianie się efektów 3D (takich jak nasza perspektywa) ), które zostały zastosowane wyżej w drzewie.

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

W przypadku przeglądarki Mobile Safari sprawa jest jednak nieco bardziej zagmatwana. Technicznie rzecz biorąc, zastosowanie metody overflow-y: scroll do elementu kontenera jest poprawne, ale jest to koszt możliwości przesuwania przewijanego elementu. Rozwiązaniem jest dodanie -webkit-overflow-scrolling: touch, ale zostanie również spłaszczony perspective i nie wystąpi paralaksa.

Z perspektywy stopniowego ulepszania – to prawdopodobnie nie jest zbyt obszerne. Google Cloud. Jeśli nie możemy zastosować paralaksy w każdej sytuacji, aplikacja będzie działać, dobrze byłoby znaleźć obejście tego problemu.

position: sticky na ratunek!

Istnieje pewna pomoc w postaci position: sticky, która ma na celu zezwalaj na „przyklejanie” elementów na górze widocznego obszaru lub do danego elementu nadrzędnego podczas przewijania. Specyfikacja, tak jak większość z nich, jest dość spora, pomocny klejnot w:

Na pierwszy rzut oka może to nie znaczyć zbyt wiele, to zdanie odnosi się do tego, jak, dokładnie, przyklejenie elementu obliczone: "przesunięcie jest obliczane w odniesieniu do najbliższego elementu nadrzędnego z polem przewijania”. Inaczej mówiąc, odległość przesunięcia przyklejonego elementu (aby wyglądała na dołączone do innego elementu lub widoczny obszar) jest obliczone przed zastosowaniem jakichkolwiek innych przekształceń, a nie po. Oznacza to, że Podobnie jak w przykładzie z przewijaniem, jeśli przesunięcie zostało obliczone w 300px, to nowa możliwość użycia perspektywy (lub dowolnej innej zmiany) do zmiany jej wartości przesunięcia 300 pikseli przed zastosowaniem jej do dowolnego elementu .

Dzięki zastosowaniu atrybutu position: -webkit-sticky do elementu paralaksy możemy skutecznie „odwróć” efekt wygładzania komórek -webkit-overflow-scrolling: touch. Dzięki temu element paralaksy odnosi się do najbliższych element nadrzędny z polem przewijania, czyli w tym przypadku .container. Następnie: podobnie jak wcześniej, .parallax-container stosuje wartość perspective, co zmienia obliczone przesunięcie przewijania i tworzy efekt paralaksy.

<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);
}

W ten sposób przywrócisz efekt paralaksy w przeglądarce mobilnej Safari. runda!

Zastrzeżenia dotyczące przyklejonego pozycjonowania

Istnieje różnica, ale position: sticky zmienia parametr mechanika paralaksy. Przyklejanie elementów ma na celu przyklejenie w kontenerze do przewijania, a wersja nieprzyklejona już nie. Oznacza to, że paralaksa z przyklejonym w ostatecznym rozrachunku jest odwrotnością tej, która nie ma:

  • Przy użyciu parametru position: sticky im bardziej element jest z=0, tym mniejszy jest ruchy.
  • Bez position: sticky im bardziej element jest z=0, tym więcej w ruchu.

Jeśli wydaje Ci się to abstrakcyjne, obejrzyj demonstrację Roberta Flacka, pokazuje, jak różne elementy zachowują się inaczej z przyklejonym i bez pozycjonowanie. Aby zobaczyć różnicę, musisz mieć Chrome Canary (w wersji 56) w momencie pisania) lub Safari.

Zrzut ekranu z perspektywą paralaksy

Prezentacja Roberta Flacka, która pokazuje, jak position: sticky wpływa na przewijanie paralaksy.

różne błędy i sposoby ich obejścia,

Jak zawsze, ale zawsze są pewne wyjątki i niedociągnięcia, które trzeba wygładzone:

  • Pomoc przyklejona jest niespójna. Pomoc jest nadal wdrażana w: Chrome i Edge nie obsługują całkowicie, a w Firefoksie występują błędy malowania w połączeniu z przekształcaniem perspektywy. W takim warto dodać mały kod, aby dodać jedynie position: sticky (parametr -webkit-) jeśli jest potrzebna (dotyczy to przeglądarki mobilnej Safari).
  • Efekt nie „po prostu działa” w Edge. Edge próbuje obsłużyć przewijanie na poziomie systemu operacyjnego, co jest zwykle dobrym rozwiązaniem, ale w tym przypadku wykrywaniu zmian perspektywy podczas przewijania. Aby rozwiązać ten problem, możesz dodać element o stałej pozycji, ponieważ wydaje się, że przechodzi na Edge metodę przewijania inną niż system operacyjny. i dba o uwzględnienie zmian perspektyw.
  • „Zawartość strony właśnie stała się ogromna!” Wiele przeglądarek uwzględnia tę wagę podczas decydowania o wielkości treści strony, ale niestety Chrome i Safari Nie uwzględniaj perspektywy. No więc jeśli na przykład zastosujesz do elementu skalę 3x, możesz widać paski przewijania i podobne, nawet jeśli element znajduje się 1x po tagu Zastosowano: perspective. Można obejść ten problem, stosując skalowanie elementów od prawego dolnego rogu (z transform-origin: bottom right), co działa, ponieważ powoduje, że nadmiernie duże elementy powiększają się „region wykluczający” (zwykle w lewym górnym rogu) obszaru przewijania; z możliwością przewijania w których regionach nigdy nie można wyświetlać ani przewijać treści w tych regionach.

Podsumowanie

Paralaksa to przyjemny efekt, jeśli używasz jej rozsądnie. Jak widać, można aby wdrożyć go w wydajny sposób, który łączy się z przewijaniem i działa w różnych przeglądarkach. Wymaga to trochę matematycznego drygowania i stworzyliśmy małą bibliotekę pomocniczą, aby uzyskać pożądany efekt. i przykład. Znajdziesz je w naszym repozytorium GitHub z przykładowymi elementami interfejsu.

Zagraj i daj nam znać, jak Ci poszło.