Görünüm geçişiyle çok fazla oynadıysanız, iki sayfa arasındaki 3B geçişlerin (yani belgeler arası görünüm geçişleri) işe yaramadığını fark etmiş olabilirsiniz. Yani, en azından tarayıcıların önce işleri düzleştirmesi olmadan.
Görüntü öğeleri bunu gösteren en iyi örnektir çünkü bir tarayıcının görünüm geçişinde öncesi-sonrası durumlarının anlık görüntüleri gibi, görüntüler de öğelerin yerini alır, dolayısıyla teorik olarak bunları 3D animasyonlar için bir tür azaltılmış test durumu olarak kullanabilmemiz gerekir. Örneğin, tıklandığında bir görseli çevirerek diğerini ortaya çıkarmak şuna benzer:
CodePen Yerleştirme Geri Dönüşü
Animasyonun düzgün çalışması için görüntünün ana kapsayıcısında perspektif özelliğini ayarlamamız gerektiğini unutmamak önemlidir (bizim durumumuzda bu, .scene öğesidir). Aksi halde 3 boyutlu dönüşüm yalnızca düzdür. Bir nevi öğenin görünümüne açı verir:
Nasıl Önlem Alınmalı?
CodePen Yerleştirme Geri Dönüşü
Gelecekte Ne Bekleniyor?
CSS'de ebeveynin bakış açısı kendisi hariç tüm çocuklarına uygulanır:
.scene { perspektif: 1200 piksel; .card { /* bakış açısı kazanır */ } }
Sonuç ve Değerlendirme
Burada önemli olan HTML yapısıdır. Özellikle .scene kapsayıcısının alt .card öğelerinin üzerine nasıl yerleştirildiği ve 3D efektinin nasıl hayata geçirildiği ve kapağın nasıl olması gerektiği gibi göründüğü:
Teknik Analiz
Belki de .cards'ı çevirmeye yönelik ana kare animasyonumuz şunun gibi bir şeydir:
Önemli Gelişmeler
@keyframes flipOut { from { transform: rotaryY(0deg); } - { dönüşümü: döndürmeY(-90 derece); } }
Uzmanların Görüşleri
Bunu .cards'a şu şekilde uyguluyoruz:
.card.flip-out { animasyon: flipOut 5,2s kübik-bezier(0,4, 0, 0,2, 1) ileri; } .card.flip-in { animasyon: flipOut 5,2s kübik-bezier(0,4, 0, 0,2, 1) ileri geri; }
Sistem Güvenliği
…burada .flip-out sınıfı .card'a eklendiğinde animasyonlar ileri doğru çalışır (JavaScript'in bir tıklamayı izlemesi sayesinde) ve .flip-in sınıfı eklendiğinde ters yönde çalışır.
Belgeler arası görünüm geçişinin de nasıl çalışması gerektiğine ilişkin kurulum bu, değil mi? Bir görüntü bir 3B animasyonu destekliyorsa, görünüm geçişlerinin anlık görüntüsü de aynısını yapmalıdır. Hadi şuna bir bakalım.
Detaylar ve Etkileri
Görünüm geçişini ayarlama
İlk olarak, gezinme tanımlayıcısını auto olarak ayarlayarak her iki sayfada da @view-transition kuralını kullanarak geçişleri görüntülemeyi seçmeliyiz:
@view-transition { gezinme: otomatik; }
Başka hiçbir şey yapmazsak, ikisi arasında gezinirken bir sayfa diğerine geçiş yapıyor. Tüm belgeler arası görünüm geçişleri arasında en temel olanıdır.
Bir şeyleri nasıl özelleştirebiliriz? ::view-transition-old() ve ::view-transition-new() sözde sınıflarını kullanırız; birincisi "eski" anlık görüntüdür ve ikincisi "yeni" anlık görüntüdür. Son örnekte kullandığımız .card öğeleri gibi, ana kare animasyonunu da burada ayarlıyoruz:
::view-transition-old(root) { /* animasyon buraya gider */ } ::view-transition-new(root) { /* animasyon buraya gider */ }
Kök parametresi, görünüm geçişine, tüm sayfayı ve görünüm geçişinin varsayılan anlık görüntü grubu tarafından oluşturulan (ve oluşturulmamış) tüm öğeleri hedeflemesini söyler.
Diyelim ki aynı 3D çevirmeyi web sayfasının tamamına uygulamak istiyoruz; burada "eski" sayfanın anlık görüntüsü "yeni" sayfaya dönüşüyor. Yine 3 boyutlu bir animasyon bizden iki şey ister:
Ana öğedeki perspektif özelliği, böylece çocuklarının bu 3D efektini elde etmesini sağlar Görünüm geçişinin ne zaman gerçekleşeceğini gösteren sayfada bir animasyon
Ancak: Buradaki ana öğenin ne olduğu konusunda perspektifi tam olarak neye ayarlıyoruz?
Görünüm geçişleri tüm web sayfasının anlık görüntülerini aldığından, (mantıksal olarak) bunun öğesi (veya :root ) olacağını varsayabiliriz, değil mi? Demek istediğim, bir görünüm geçişi mevcut olduğunda DOM ağacı şöyle görünür:
html ├─ ::view-transition │ ├─ ::view-transition-group(card) │ │ └─ ::view-transition-image-pair(kart) │ │ ├─ ::view-transition-eski(kart) │ │ └─ ::view-transition-new(card) │ └─ ::view-transition-group(name) │ └─ ::view-transition-image-pair(name) │ ├─ ::view-transition-old(name) │ └─ ::view-transition-new(name) ├─ head └─ body └─ …
Yani anlık görüntünün tamamı perspektifi koyduğumuz yerde olmalıdır. Sağ? Hayır.
Aslında hiçbir şey yapmıyor! Daha önce kartlarda kullanabildiğimiz güzel 3 boyutlu çevirme yerine bununla baş başa kaldınız:
İşte üzerinde çalıştığım kod:
/* Belgeler Arası Görünüm Geçişi seçeneği */ @view-transition { navigasyon: auto; } /* 3B çevirme: Eski sayfa ters çevrilir, yeni sayfa içe doğru çevrilir */ @keyframes ters çevrilir { 0% { transform: rotaryY(0deg); opaklık: 1; } %100 { tra nsform: döndürY(-90 derece); opaklık: 0; } } @keyframes çevirmeli { 0% { transform: rotaryY(90deg); opaklık: 0; } 100% { dönüşüm: döndürmeY(0 derece); opaklık: 1; } } ::view-transition-old(root) { animasyon: 0,3s kübik-bezier(0,4, 0, 1, 1) ileri doğru çevir; dönüşüm-kökeni: merkez merkez; } ::view-transition-new(root) { animasyon: çevirme 0,3s kübik-bezier(0, 0, 0,6, 1) 0,3s geriye; dönüşüm-kökeni: merkez merkez; }
Not: -90 dereceye ve ardından 90 dereceye döndüğümüz için buradaki animasyonu tersine çevirmedim. Tam olarak aynı değil!
Ve perspektif ister html'de ister :root'ta olsun işe yaramıyor:
/* 👎 */ html { perspektif: 1100px; } /* 👎 */ :root { perspektif: 1100px; }
Biraz araştırma yaptım ve perspektifin (ve genel olarak 3 boyutlu dönüşümlerin) alışılmadık bir etki yaratabilecek çeşitli CSS özelliklerinden biri olduğunu keşfettim. (Cevabı Bramus'a bırakın!)
Peki... Ne yapacağız? Aklıma bazı fikirler geldi ama ne yazık ki başarısız oldum:
Perspektif özelliğini gövdeye ayarlamayı denedim.
üzerindeki mülk. ::view-transition-group(root) içinde perspektif ayarlamayı denedim.
içeri . ::view-transition sözde içinde perspektif ayarlamayı denedim.
Aslında bunun çok basit bir çözümü var ve bunu anlamanın bu kadar uzun sürdüğüne inanamıyorum; perspektifi hiç kullanmayın!
Kısa hikaye: perspektif özelliği yerine perspektif() fonksiyonunu kullanmamız gerekiyor. Ve beklediğiniz gibi ::view-transition-* sözdelerinin hiçbirinin içinde değil, @keyframes animasyonunun içinde:
@keyframes ters çevirme { 0% { transform: perspektif(1100 piksel) döndürmeY(0 derece); opaklık: 1; } 100% { dönüşüm: perspektif(1100 piksel) döndürmeY(-90 derece); opaklık: 0; } } @keyframes çevirmeli { 0% { transform: perspektif(1100 piksel) döndürmeY(90 derece); opaklık: 0; } 100% { transform: perspektif(1100 piksel) döndürmeY(0 derece); opaklık: 1; } }
Bu basit ama büyük değişiklik, sahneyi düz bir meh'den güzel bir ah evet'e taşıyor:
Görünüşe göre nedeni bu. Görünüm geçişi sözde öğe ağacı normal HTML akışının dışında oluşturulur. Daha spesifik olarak, görünüm geçiş ağacının tamamı DOM'un üzerinde kendi katmanında oluşturulur. Bununla birlikte, özellikle ::view-transition için durumun neden böyle olduğundan pek emin değilim, ancak en iyi tahminim, her görünüm geçiş grubunun otomatik olarak kendi konumu ve dönüşüm değerlerinin tarayıcı tarafından geçersiz kılındığıdır; dolayısıyla perspektife müdahale ediliyor.
Perspektif ve perspektif() arasındaki fark nedir? Perspektif özelliği ana öğeye uygulanırken perspektif() doğrudan öğenin kendisine uygulanan bir dönüştürme özelliği işlevidir. Ve görünüm geçişi sözde ağacının gerçek bir ebeveyni olmadığından, bir ebeveyn gerektirmediğinden perspektif() kullanmamız gerekir. Vay be.