CSS

CSS { Gerçek Hayatta }

Noel’den hemen sonra biraz eğlendim Codepen demosu Gerçekçi görünümlü kağıt kar tanelerini CSS’de ev yapımı dekorasyonlarımızdan esinlenerek yeniden yaratın! Noel uzak bir anı olabilir, ancak bu süreçten paylaşılması ilginç olabilecek pek çok öğrenme vardı.

Katlanmış kağıt efektleri

Lynn Fisher harika yayınladı harika kişisel sitenin yeniden tasarımının gözden geçirilmesi, bazı çok havalı kağıt katlama efektlerine sahip. (Tarayıcınızı çalışırken görmek için yeniden boyutlandırın!) Ayrıca, bu tür efektlerde varyasyonlar içeren bir dizi demo oluşturdu, örneğin: bu harika katlanmış poster, burada katmanlı arka plan gradyanlarını kullanarak katlama efektleri yaratır. Lynn’in çalışması, kağıt kar tanelerimin gerçek kağıttan kesilmiş gibi görünmesini sağlamak için gradyanları kullanmanın arkasında büyük bir ilham kaynağı oldu. kullandım conic-gradient ve radial-gradient ince bir ışık ve gölge efekti elde etmek için arka planlar. conic-gradient oldukça yakın zamanda yaygın bir tarayıcı desteği kazandı, ancak CSS’de bazı çarpıcı ve yaratıcı efektlere izin verdiği için onunla oynamak çok eğlenceli.

kırpılmış segmentler

İlk fikrim, her kar tanesi için tek bir element kullanmaya çalışmaktı, bu muhtemelen bazılarıyla mümkün olacaktı. çok gradyanların akıllıca kullanımı. Ancak erkenden çok elemanlı bir çözümün hedeflerime daha uygun olacağına karar verdim. Tek bir katlanmış parçadan kırpılan kar tanesinin bütünlüğünü korumak istedim ve bunu yapmak için kullanmaktan daha iyi bir yol olabilir mi? clip-path? Kar tanesinin her bir parçası, aynı şekilde kırpılmış ve bir kap içinde mutlak olarak konumlandırılmış tek bir elemandır. Segmentin genişliği ve yüksekliği %50’dir (Şekil 01). %100 genişlik ve yükseklikte bir öğe kullanabilirdim, ancak bu, kırpma sırasında (yüzde tabanlı clip-path poligon Çokgen değerlerimin %50’yi geçmemesi gerektiğini sürekli hatırlamam gerekiyordu ve bunun biraz rahatsız edici olacağını hissettim.

Bir kapsayıcının sağ üst çeyreğine yerleştirilmiş mutlak bir kare öğe
Şekil 01

Örnek olarak tek bir segmente bakalım. Başlangıçta, kesin değeri hesaplamak yerine clip-path biraz matematik gerektiren bir değer (buna daha sonra döneceğiz!), özel özellikler kullandım ve mask-image bir segmenti kesmek için. Maskeleme biraz kırpma gibidir, ancak bir öğeyi temiz çizgilerle kesmek yerine, alanları gizlemek veya ortaya çıkarmak için alfa saydamlığı ve hatta gradyanlı görüntüleri kullanabiliriz. düşünmeyi severim clip-path makasla kesmek gibi, oysa mask-image alttaki görüntüyü ortaya çıkarmak için kömürle kaplı bir yüzeyin alanlarını bir silgiyle ovalamaya benzer. Daha ince derecelendirmeye izin verir.

Özel özellikler

Her şeyden önce, segment sayısı için özel bir özellik belirledim. Sonra bunu, tek bir parçanın açısı için ikinci bir özel özelliği hesaplamak için kullandım:

.snowflake {
--totalSegments: 16;
--segment: calc(360deg / var(--totalSegments));
}

Maske olarak kullanmak istediğim konik gradyan açısı için bu segment özel özelliğini kullandım:

.snowflake {
--totalSegments: 16;
--segment: calc(360deg / var(--totalSegments));

--mask: conic-gradient(
from 0deg at 0 100%,
rgba(0, 0, 0, 1),
rgba(0, 0, 0, 1) var(--segment),
rgba(0, 0, 0, 0) var(--segment)
);
}

Bu bize, bir klip yolu kullanmaya çok benzer, temiz kenarlı, elemanın sol altından yayılan konik bir gradyan verir – ancak hiç matematik yapmak zorunda kalmıyorum. Bu, kar tanesinin her parçasında kullanacağımız maskedir ve üçgen bir şekil verir. (Şekil 02)

Uygulanan maskenin bir sonucu olarak üçgen eleman
Şekil 02

Maskeyi uygulamak

Maske için özel bir özellik ayarlıyorum, çünkü mask-image özelliğin birkaç tarayıcıda öneki olması gerekir – bu nedenle, tüm özellik değerini çoğaltmak yerine onu bir değişken olarak kullanabiliriz:

.segment {
--webkit-mask-image: var(--mask);
mask-image: var(--mask);
}

Bir segmenti kırpma

Şimdi, art arda çapraz olarak on altıya katlanmış bir kare kağıdı temsil eden bir segmentimiz var. kullanarak, makasla kesiyormuş gibi bölümleri kesmeye başlayabiliriz. clip-path. Bunu orijinal demoda tamamen gözle yaptım, onlardan memnun olana kadar değerleri değiştirdim. Kar tanesinin ölçeklenebilmesini istediğim için klip yolu noktaları için yüzde değerleri kullandım.

Sonunda, sağ taraftaki değerlerin maske sınırının hemen dışında olduğu bir çokgen buldum. (Şekil 03)

kırpılmış eleman
Şekil 03

(Uzman ipucu: Klip yolunuz üzerinde çalışırken degrade maskesinin şeffaf kısmının alfa değerini artırırsanız, yolunuzun maskenin arkasında tam olarak nereye düştüğünü görebilirsiniz.) Neden şimdi daha açık olabilir’ bir maskeyi yeniden kullanmak – bu, çokgen noktalarımızla bu kadar hassas olma ve bunları trigonometriyle hesaplama konusunda endişelenmemize gerek olmadığı anlamına gelir. Biraz sonra trigonometriye daha detaylı bakacağız ve bunun neden daha iyi bir çözüm olabileceğini göreceğiz.

Bizim clip-path poligon, takip edilmesi gereken oldukça fazla değer olmaktan çıkıyor. Bunları özel özelliklerle biraz daha kolay yönetebiliriz. Kırptığım her bölümü etkili bir şekilde takip etmek için özel özellikler kullandım. Yani (neredeyse) her özel özelliğin üç çift değeri vardır. Örneğin, sol taraftan kırpılan bir üçgen, kırpma yolu çokgeninde şu özel özelliklerle temsil edilebilir:

.snowflake {
--l1: 0 80%, 5% 75%, 0 60%;


--path: polygon(
0 0,
var(--r1),
var(--r2),
100% var(--y),
var(--center),
var(--l1),
var(--l2),
var(--l3)
);
}

Karşılık gelen değerleriyle vurgulanan üç klip yolu noktası
Şekil 04

Bu şekilde, ince ayar yaptığımız değerlerin hangi bölüm için geçerli olduğu çok daha açıktır. Bu, özellikle kar tanelerinin sonraki varyasyonlarını yaparken yardımcı oldu: Klip yolunun tamamı yerine yalnızca özel özelliklerde ince ayar yapmak zorunda kaldım.

dönüşümler

Şimdi her parçayı bir nokta etrafında döndürerek konumlandırabiliriz. ayarlayabiliriz transform-origin değer bottom leftveya 0 100%, bu yüzden (tahmin ettiniz) sol alttan döndürülecektir. Yine, özel özellikler burada bize yardımcı olabilir. Her segmente, dizinine karşılık gelen özel bir özellik atıyorum. Bunu üretken yönü olan pek çok proje için yapıyorum ve genellikle HTML’de yapmayı tercih ediyorum. (Bir şablonlama dili kullanıyorsanız özellikle kolaydır.) Bu, öğe ekler veya kaldırırsanız, CSS dosyanızı sürekli güncellemeniz gerekmediği anlamına gelir.

<div class="snowflake">
<div class="segment" style="--i: 1"></div>
<div class="segment" style="--i: 2"></div>
<div class="segment" style="--i: 3"></div>
<div class="segment" style="--i: 4"></div>
<div class="segment" style="--i: 5"></div>
<div class="segment" style="--i: 6"></div>
<div class="segment" style="--i: 7"></div>
<div class="segment" style="--i: 8"></div>
<div class="segment" style="--i: 9"></div>
<div class="segment" style="--i: 10"></div>
<div class="segment" style="--i: 11"></div>
<div class="segment" style="--i: 12"></div>
<div class="segment" style="--i: 13"></div>
<div class="segment" style="--i: 14"></div>
<div class="segment" style="--i: 15"></div>
<div class="segment" style="--i: 16"></div>
</div>

Artık her segmenti dizinine göre tek bir kod satırında dönüştürebiliriz:

.segment {
transform-origin: 0 100%;
transform: rotate(calc(var(--segment) * var(--i, 1)));
}
Bir nokta etrafında döndürülen özdeş parçalar
Şekil 05

Ancak tam olarak işimiz bitmedi, çünkü her başka segment tam olarak döndürülmelidir. y ekseni—yani bir ayna görüntüsü—tıpkı gerçek bir kağıt kar tanesini açtığınızda olduğu gibi:

.segment:nth-child(even) {
transform: rotateY(180deg) rotate(calc(var(--segment) * (var(--i, 1) - 1)));
}
Döndürme uygulandıktan sonra ortaya çıkan kar tanesi şekli
Şekil 06

Konik gradyan arka planı her segmente de uygulanır, bu nedenle çift segmentler için onu tersine çevireceğiz. Radyal gradyanla katmanlı bir konik gradyan kullanıyoruz, bu nedenle konik gradyanı özel bir özellik olarak ayarlarsak, çift segmentler için radyal gradyan değerini tekrarlamaktan kaçınarak kodumuzu biraz daha özlü hale getirebiliriz:

.snowflake {
--bg: repeating-conic-gradient(
from 0deg at 0 100%,
white,
rgba(200, 200, 200, 1) var(--segment)
);
}

.segment {
background: radial-gradient(
circle at 0% 100%,
rgba(200, 200, 200, 1),
transparent 40%
), var(--bg);
}

.snowflake:nth-child(even) {
--bg: repeating-conic-gradient(
from 0deg at 0 100%,
rgba(200, 200, 200, 1),
white var(--segment)
);
}

Düşen gölge

Son bir dokunuş olarak, tüm kar tanesine daha gerçekçi görünmesi için ince bir alt gölge ekleyebiliriz. drop-shadow filtre:

.snowflake {
filter: drop-shadow(1rem 1rem 1rem rgba(0, 0, 0, 0.9));
}

Bu, her parçayı kırpmanın avantajlarından biridir. clip-path“saydam” parçaların gerçekten şeffaf olmayabileceği degrade hilesine güvenmek yerine – alt gölgemiz, içindeki kırpılmış alanlar da dahil olmak üzere, kar tanesi gerçekten kağıttan kesilmiş gibi davranır.

Trigonometri ile daha iyi bir sonuç

İle birlikte bir degrade maskesi kullanma clip-path bu demo için iyi çalıştı, ancak biraz hile yapmak gibi geldi. Sonuçtan memnun olmama rağmen, bu, klip yolu çokgen noktalarımı belirlemek için büyük ölçüde deneme yanılma yöntemine güvendiğim anlamına geliyor. Bu bana %100 tatmin edici gelmedi. Çözümün trigonometri olması gerektiğini biliyordum, bu yüzden sonraki bir demoda onu klip yolu koordinatlarımı tam olarak hesaplamak için kullanmaya karar verdim.

Bir sonraki demom için kağıt kar tanesinin etkileşimli bir versiyonunu yaptım. Kullanıcılar, her seferinde benzersiz bir kar tanesi oluşturarak klip yolunu değiştirmek için tutamaçları sürükleyebilir. Demo Greensock’s kullanıyor sürüklenebilir Eklenti. İlk defa bununla uğraşıyordum ve oldukça basit bir şekilde kullanmama rağmen, kullanıcıların bir şeyleri hareket ettirebilecekleri arayüzler oluşturmak için çok yararlı görünüyor.

Kalemi Gör
Klip yolu trigonometrisi ile kar taneleri
Michelle Barker tarafından (@michellebarker) üzerinde kod kalemi.

Bunu nasıl yaptığımın adım adım ayrıntılarına girmeyeceğim, ancak gelecekteki bir gönderide trigonometrinin bana burada nasıl yardımcı olduğunu ve onu CSS ve Javascript’te kullanmanın bazı farklı yollarını paylaşacağım.

İlgili Makaleler

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Başa dön tuşu