Performanslı Paralaks

Paul Lewis
Robert Flack
Robert Flack

İster sevin, ister nefret edin, paralaks hep hayatımızda. Akıllıca kullanıldığında, bir web uygulamasına derinlik ve incelik katabilir. Ancak sorun, bu çözümün yüksek performanslı bir şekilde paralaks yapmak zor olabilir. Bu makalede, hem yüksek performans gösteren hem de daha da önemlisi işe yarayan yardımcı olabilir.

Paralaks resmi.

Özet:

  • Paralaks animasyonları oluşturmak için kaydırma etkinliklerini veya background-position öğesini kullanmayın.
  • Daha doğru bir paralaks efekti oluşturmak için CSS 3D dönüştürmelerini kullanın.
  • Mobil Safari'de paralaks efektinin etkinleştirildiğinden emin olmak için position: sticky kullanın yayılır.

Geçici çözümü kullanmak istiyorsanız UI Element Samples GitHub deposuna gidin ve Paralaks yardımcı JS'si. Paralaks kaydırma aracının canlı demosunu GitHub deposu.

Problem paralaksörleri

İlk olarak, paralaks elde etmenin yaygın olarak kullanılan iki yolundan ve özellikle de amaçlarımız için neden uygun olmadıklarını anlamaktır.

Kötü: Kaydırma etkinlikleri kullanılıyor

Paralakslığın temel koşulu, kaydırmaya bağlı olmasıdır. şunun için: sayfanın kaydırma konumundaki her bir değişiklik, paralaks öğesinin güncellenmelidir. Bu kulağa basit gelse de projenin önemli bir modern tarayıcıların eşzamansız olarak çalışabilmesidir. Bu, özel bir durum kullanabilirsiniz. Çoğu tarayıcıda kaydırma etkinlikleri yayınlanır. “en iyi çaba” olarak ve tüm karelerde sağlanacağı garanti edilmez. kaydırma animasyonu!

Bu önemli bilgiler bize, neden geri bildirim göndermekten Kaydırma etkinliklerine göre öğeleri taşıyan JavaScript tabanlı çözüm: JavaScript, paralaksajın Kaydırma konumunu kullanabilirsiniz. Mobile Safari'nin eski sürümlerinde kaydırma etkinlikleri sonuna kadar izlenmelidir. Bu da JavaScript tabanlı kaydırma efekti. Diğer son sürümler kaydırma etkinlikleri gerçekleştirir görebilirsiniz ancak Chrome'da olduğu gibi "en iyi çaba" hedefiyle . Öğe ana ileti dizisi başka bir işle meşgul, kaydırma etkinlikleri teslim edilmeyecek hemen ardından paralaks etkisi kaybolur.

Kötü: background-position güncelleniyor

Kaçınmak istediğimiz bir başka durum da her kareyi boyamaktır. Birçok çözüm paralaks görünümünü sağlamak için background-position değerini değiştirmeyi deneyin. Tarayıcı, sayfayı kaydırırken sayfanın etkilenen kısımlarını yeniden boyayabilir ve bu da animasyonu önemli ölçüde sekteye uğratacak kadar maliyetli olabilir.

Paralaks hareket vaadini yerine getirmek istiyorsak, hızlandırılmış bir özellik olarak uygulanabilir (bu nedenle, dönüşümleri ve opaklığı içerir.

3D CSS

Hem Scott Kellum hem de Keith Clark, paralaks hareketi elde etmek için CSS 3D kullanma alanında ve kullandıkları teknik şudur:

  • overflow-y: scroll ile kaydırmak için bir kapsayıcı öğe ayarlayın (büyük olasılıkla overflow-x: hidden) tıklayın.
  • Aynı öğeye bir perspective değeri ve bir perspective-origin uygulayın. top left veya 0 0 olarak ayarlandı.
  • O öğenin alt öğelerine Z dilinde bir çeviri uygular ve sonra ölçeğini küçültür ekran boyutunu etkilemeden paralaks hareketi sağlayacak şekilde tasarlanmıştır.

Bu yaklaşım için CSS aşağıdaki gibidir:

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

Aşağıdaki gibi bir HTML snippet'i varsayılır:

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

Perspektif için ölçek ayarlanıyor

Alt öğeyi geri itmek, öğenin öğe ile orantılı olarak küçülmesine neden olur. perspektif değeri. Ne kadar ölçeklendirmenin gerektiğini hesaplayabilirsiniz. şu denklem şu şekildedir: (perspektif - mesafe) / perspektif. Büyük olasılıkla, paralaks oluşturma öğesini paralaksa dönüştürmesini ancak oluşturduğumuz boyutta görünmesini istiyorsanız olduğu gibi bırakmak yerine bu şekilde ölçeklenmesi gerekir.

Yukarıdaki kodda, perspektif 1px, ve parallax-child adlı öğenin Z mesafesi -2 piksel'dir. Bu, ilgili öğenin 3x ölçeklendirilir (koda eklenen değer görebilirsiniz): scale(3).

translateZ değeri uygulanmamış içerikler için şunları yapabilirsiniz: yerine sıfır koyun. Bu da ölçeğin (perspektif - 0) / bakış açısı. Bu, 1 değerini netleştirir, yani ölçeklendirilmiştir. ne birikti ne de aşağısı. Çok kullanışlı, gerçekten.

Bu yaklaşımın işleyiş şekli

Bunun neden işe yaradığını net bir şekilde bilmek önemlidir, çünkü bunu anlatacağım. Kaydırma etkili bir dönüşümdür ve bu nedenle accelerated; Çoğunlukla GPU ile katmanların değiştirilmesini içerir. perspektif algısı olmayan tipik kaydırma, ilke, kaydırma öğesi ile alt öğeleri karşılaştırılırken 1:1 şekilde gerçekleşir. Bir öğeyi 300px kadar aşağı kaydırırsanız alt öğeleri yukarı dönüştürülür aynı miktarla: 300px.

Bununla birlikte, kaydırma öğesine bir perspektif değeri uygulandığında, bu süreç sayesinde; kaydırma dönüşümünün temelini oluşturan matrisleri değiştirir. Şu anda 300 piksellik bir kaydırma, alt öğeleri Seçtiğiniz perspective ve translateZ değerleri. Bir öğede translateZ değeri 0 ise 1:1'de (eski adıyla) kaydırılacak, ancak çocuk için geçerli olacak perspektif kaynağından uzağa Z içine itildiğinde farklı bir yönde puan! Net sonuç: paralaks hareket. Daha da önemlisi, bu tarayıcının dahili kaydırma makinesinin bir parçasını otomatik olarak oluşturur. Bu da, scroll etkinliklerini dinleme veya background-position öğelerini değiştirmeye gerek yoktur.

Mermer sinek: Mobile Safari

Her etkiyle ilgili uyarılar vardır ve dönüştürme işlemleri için önemli olanlardan biri korumasına dahil edilir. öğe ile paralaks alt öğeleri arasındaki hiyerarşiyi, 3D perspektif "düzeltilmiş" olur, yani etkinin kaybolur.

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

Yukarıdaki HTML'de .parallax-container yenidir ve perspective değerini düzeltirseniz paralaks etkisi kaybolur. Çözüm, oldukça basit bir işlemdir: transform-style: preserve-3d dönüşüm izleme bu şekilde, öğenin 3D efektlerin (ör. perspektifimiz) ve (değeri) daha yüksek olacaktır.

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

Ancak Mobile Safari söz konusu olduğunda işler biraz daha karmaşıktır. Kapsayıcı öğesine overflow-y: scroll uygulamak teknik olarak çalışır, ancak kaydırma öğesini hızlıca kaydırabilmenin maliyetini. Çözüm, -webkit-overflow-scrolling: touch olarak ayarlanmış ancak perspective paralaks oluşturmayacağız.

Progresif geliştirmeler açısından değerlendirildiğinde, bu büyük olasılıkla . Her durumda paralaks sağlayamasak da uygulamamız çalışmaya devam eder. geçici bir çözüm bulmak isteriz.

position: sticky kurtarın!

Hatta position: sticky biçiminde bir yardım vardır. öğelerin "yapışmasına" izin ver görüntü alanının veya belirli bir üst öğenin üstüne dikkat edin. Çoğu gibi teknik özellikler de oldukça derli toplu, ancak yardımcı olacak küçük bir cevher:

Bu, ilk bakışta çok büyük bir anlam ifade etmese de proje yönetiminde bir öğenin yapışkanlığını onunla aynı şekilde hesaplanır: "ayırma en yakın üst öğeye başvurularak hesaplanır görüntülenebilir. Başka bir deyişle, yapışkan öğeyi hareket ettirmek için (başka bir öğeye veya görüntü alanına ekli görünmesi için) herhangi bir dönüştürme uygulanmadan önce hesaplanır, hesaplamadan sonra hesaplanmaz. Bunun anlamı şudur: önceki kaydırma örneğinde olduğu gibi, ofset değeri hesaplanmışsa olduğundan, perspektifleri (veya başka bir dönüşümü) kullanmak için yeni bir fırsat herhangi bir yapışkan alana uygulanmadan önce bu 300 piksellik ofset değerini değiştirmek öğeler.

Paralaks oluşturma öğesine position: -webkit-sticky uygulayarak fiilen “ters çevir” -webkit-overflow-scrolling: touch'ın düzleştirici etkisi. Bu, paralaks öğesinin kaydırma kutusu olan üst öğe (bu örnekte .container değerini alır). Ardından, Öncekine benzer şekilde, .parallax-container bir perspective değeri uygular, bu da hesaplanan kaydırma ofsetini değiştirir ve bir paralaks efekti oluşturur.

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

Mobil Safari için paralaks efekti geri yüklenir. raunt!

Yapışkan konumlandırma uyarıları

Ancak burada bir fark vardır: position: sticky paralaks mekaniği. Yapışkan konumlandırma, öğeyi yapışkan olmayan sürümlerde ise bunu yapmaz. Bu, yapışkan paralaks, içermeyen paralaksın tersidir:

  • position: sticky kullanıldığında öğe, z=0 değerine ne kadar yakın olursa o kadar daha az olur anlamına gelir.
  • position: sticky olmadığında, öğe z=0'a ne kadar yakın olursa daha fazla olur hareket eder.

Tüm bunlar biraz soyut görünüyorsa Robert Flack'in bu demosuna göz atın. öğeler yapışkan olduğunda ve olmadığında nasıl farklı davrandığını gösterir yardımcı olabilir. Farkı görmek için Chrome Canary'ye (sürüm 56) ihtiyacınız var veya Safari'de kullanılabilir.

Paralaks perspektifi ekran görüntüsü

Rober Flack tarafından hazırlanan demoda position: sticky paralaks kaydırmayı etkiler.

Çeşitli hatalar ve geçici çözümler

Fakat her şeyde olduğu gibi, yine de olması gereken yumrular ve çıkıntılar vardır. yumuşatma:

  • Sürekli destek tutarsız. Şu dilde destek uygulanmaya devam ediyor: Chrome, Edge'de hiç destek yoktur ve Firefox'ta yapışkan yapışkan perspektif dönüşümleriyle birleştirildiğinde boyama hataları ortaya çıkar. Böyle bir durumda durumlarda, yalnızca position: sticky ( -webkit- önekli sürümü) gerekir (ör. Mobile Safari için) gerekir.
  • Bu işlem sadece işe yaramıyor" . Edge, Bu genellikle iyi bir şeydir. Ancak bu durumda, işletim sistemi seviyesinin perspektif değişikliklerini algılamasını sağlar. Bu sorunu düzeltmek için Edge'nin işletim sistemi dışında bir kaydırma yöntemine geçirdiği için sabit konumlu bir öğe ve bakış açısı değişikliklerinin hesaba katılmasını sağlar.
  • "Sayfanın içeriği çok arttı!" Birçok tarayıcı, ölçeğin Ama ne yazık ki Chrome ve Safari, sayfanın içeriğinin ne kadar büyük olduğuna karar verirken dikkate almayın. ODK bir öğeye 3x ölçeği uygulanırsa, bunu öğe 1x değerinde olsa bile, kaydırma çubukları ve benzerleri perspective uygulandı. Bu sorunu çözmek için öğeleri sağ alt köşeden (transform-origin: bottom right ile) ölçeklendirir. Bu yöntem, büyük boyutlu öğelerin "negatif bölge" kaydırılabilir alanın (genellikle sol üst kısmı) kaydırılabilir bölgeler, negatif bölgedeki içeriği hiçbir zaman görmenize veya bu içeriğe gitmenize izin vermez.

Sonuç

Paralaks, dikkatli bir şekilde kullanıldığında eğlenceli bir efekttir. Gördüğünüz gibi yüksek performanslı, kaydırmaya bağlı ve tarayıcılar arası bir şekilde uygulamaktır. Biraz matematiksel kıvrılma gerektirdiğinden oluşturmak için küçük bir yardımcı kitaplık hazırladık. ve örneği inceleyin. UI Element Samples GitHub depomuzda bulabilirsiniz.

Biraz oynayıp konu hakkında bize bilgi verin.