Chrome 65'teki yeni imkanlar
CSS Paint API ("CSS Custom Paint" veya "Houdini'nin boya iş uygulaması" olarak da bilinir) Chrome 65'ten itibaren varsayılan olarak etkindir. Bu nedir? Bununla ne yapabilirsin? İşleyiş şekli Öyleyse okumaya devam edin...
CSS Paint API, bir CSS özelliği resim beklediğinde programatik olarak resim oluşturmanıza olanak tanır. background-image
veya border-image
gibi özellikler, bir resim dosyasını yüklemek için genellikle url()
ile veya linear-gradient()
gibi yerleşik CSS işlevleriyle kullanılır. Bunları kullanmak yerine artık bir boya iş akışına referans vermek için paint(myPainter)
kullanabilirsiniz.
Boyama iş uygulaması yazma
myPainter
adlı bir boyama iş uygulaması tanımlamak için CSS.paintWorklet.addModule('my-paint-worklet.js')
kullanarak CSS boyama iş uygulaması dosyası yüklememiz gerekir. Bu dosyada, bir boya işçisi sınıfını kaydetmek için registerPaint
işlevini kullanabiliriz:
class MyPainter {
paint(ctx, geometry, properties) {
// ...
}
}
registerPaint('myPainter', MyPainter);
paint()
geri çağırması içinde ctx
ifadesini, <canvas>
sağlayıcısından bildiğimiz CanvasRenderingContext2D
ile aynı şekilde kullanabiliriz. <canvas>
çizmeyi biliyorsanız boya işçisi yapabilirsiniz. geometry
, elimizdeki kanvasın genişliğini ve yüksekliğini bize bildirir. properties
Bu makalenin ilerleyen kısımlarında
açıklayacağım.
Giriş örneği olarak, dama tahtası boyama işçisi yazalım ve bunu bir <textarea>
arka plan resmi olarak kullanalım. (Varsayılan olarak yeniden boyutlandırılabilir olduğundan
metin alanı kullanıyorum.):
<!-- index.html -->
<!doctype html>
<style>
textarea {
background-image: paint(checkerboard);
}
</style>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
paint(ctx, geom, properties) {
// Use `ctx` as if it was a normal canvas
const colors = ['red', 'green', 'blue'];
const size = 32;
for(let y = 0; y < geom.height/size; y++) {
for(let x = 0; x < geom.width/size; x++) {
const color = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.fillStyle = color;
ctx.rect(x * size, y * size, size, size);
ctx.fill();
}
}
}
}
// Register our class under a specific name
registerPaint('checkerboard', CheckerboardPainter);
Geçmişte <canvas>
kullandıysanız bu kod size tanıdık gelecektir. Canlı demoyu buradan izleyin.
Burada ortak bir arka plan resmi kullanmanın farkı, kullanıcı metin alanını yeniden boyutlandırdığında kalıbın isteğe bağlı olarak yeniden çizilmesidir. Bu, arka plan resminin, yüksek yoğunluklu ekranlar için gereken ücret de dahil olmak üzere her zaman tam olarak olması gereken büyüklükte olduğu anlamına gelir.
Bu çok iyi bir özellik ama aynı zamanda da çok hareketsiz. Aynı deseni farklı boyutlarda karelere sahip her seferinde yeni bir iş akışı mı yazmak istedik? Yanıtım hayır!
İş akışınızı parametre olarak ayarlama
Neyse ki boya iş akışı, diğer CSS özelliklerine erişebilir. Bu durumda, properties
ek parametresi devreye girer. Sınıfa statik bir inputProperties
özelliği vererek özel özellikler dahil olmak üzere herhangi bir CSS özelliğinde yapılan değişikliklere abone olabilirsiniz. Değerler size properties
parametresiyle verilir.
<!-- index.html -->
<!doctype html>
<style>
textarea {
/* The paint worklet subscribes to changes of these custom properties. */
--checkerboard-spacing: 10;
--checkerboard-size: 32;
background-image: paint(checkerboard);
}
</style>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
// inputProperties returns a list of CSS properties that this paint function gets access to
static get inputProperties() { return ['--checkerboard-spacing', '--checkerboard-size']; }
paint(ctx, geom, properties) {
// Paint worklet uses CSS Typed OM to model the input values.
// As of now, they are mostly wrappers around strings,
// but will be augmented to hold more accessible data over time.
const size = parseInt(properties.get('--checkerboard-size').toString());
const spacing = parseInt(properties.get('--checkerboard-spacing').toString());
const colors = ['red', 'green', 'blue'];
for(let y = 0; y < geom.height/size; y++) {
for(let x = 0; x < geom.width/size; x++) {
ctx.fillStyle = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.rect(x*(size + spacing), y*(size + spacing), size, size);
ctx.fill();
}
}
}
}
registerPaint('checkerboard', CheckerboardPainter);
Artık aynı kodu farklı dama tahtası türlerinin tamamında kullanabiliriz. Ama daha da iyisi, artık Geliştirici Araçları'na gidip doğru görünümü bulana kadar değerlerle uğraşabiliriz.
Boyama iş uygulamasını desteklemeyen tarayıcılar
Yazıldığı sırada yalnızca Chrome'a boyama iş uygulaması uygulanmaktadır. Diğer tüm tarayıcı tedarikçilerinden olumlu sinyaller olsa da pek bir ilerleme yaşanmamıştır. Son gelişmelerden haberdar olmak için düzenli olarak Houdini Hazır mı? sayfasını kontrol edin. Bu sırada, boya işçisi desteği olmasa bile kodunuzun çalışmaya devam etmesi için progresif geliştirme (pwa) kullandığınızdan emin olun. Her şeyin beklendiği gibi çalıştığından emin olmak için kodunuzu iki yerde düzenlemeniz gerekir: CSS ve JS.
JS'de boya iş uygulaması desteğini algılamak için CSS
nesnesini kontrol edebilirsiniz:
js
if ('paintWorklet' in CSS) {
CSS.paintWorklet.addModule('mystuff.js');
}
CSS tarafında iki seçeneğiniz vardır. @supports
kullanabilirsiniz:
@supports (background: paint(id)) {
/* ... */
}
Daha kapsamlı bir yöntem ise CSS'nin, içinde bilinmeyen bir işlev varsa özellik bildiriminin tamamını geçersiz kılıp ardından yoksaydığı gerçeğini kullanmaktır. Bir özelliği iki kez belirtirseniz (önce boya iş uygulaması olmadan ve ardından boya iş parçacığı ile) progresif geliştirme elde edersiniz:
textarea {
background-image: linear-gradient(0, red, blue);
background-image: paint(myGradient, red, blue);
}
Boya iş parçacığını destekleyen tarayıcılarda ikinci background-image
bildirimi ilkinin üzerine yazılır. Boyama iş akışı desteği olmayan tarayıcılarda ikinci beyan geçersiz olur ve silinir. İlk açıklama geçerli olur.
CSS Boya Polyfill'i
Birçok kullanım için modern tarayıcılara CSS Özel Boya ve Boyama İşletleri desteğini ekleyen CSS Paint Polyfill'i de kullanmak mümkündür.
Kullanım alanları
Boya iş parçacıklarının birçok kullanım alanı vardır. Bunlardan bazıları
diğerlerinden daha barizdir. Bunlardan en bariz olanlardan biri, DOM'nizin boyutunu küçültmek için
boya iş uygulamasıdır. Öğeler sadece CSS kullanarak süslemeler oluşturmak için genellikle eklenir. Örneğin, Material Design Lite'ta dalga efektli düğme, dalganın kendisini uygulamak için 2 ek <span>
öğesi içerir. Çok sayıda düğmeniz olması, çok sayıda DOM öğesinin eklenmesine neden olabilir ve mobil cihazlarda performansın düşmesine yol açabilir. Bunun yerine dalga efektini boya iş uygulaması kullanarak uygularsanız 0 ek öğe ve yalnızca bir boya iş uygulaması elde edersiniz.
Ayrıca, özelleştirilmesi ve parametreleştirilmesi çok daha kolay olan bir özelliğe sahipsiniz.
Boyama iş akışı kullanmanın bir diğer avantajı da (çoğu senaryoda), boya iş akışı kullanan bir çözümün bayt bakımından küçük olmasıdır. Elbette bu dengenin bir farkı vardır: Tuvalin boyutu veya parametrelerden herhangi biri her değiştiğinde boya kodunuz çalışır. Dolayısıyla, kodunuz karmaşıksa ve uzun sürerse jank'ın ortaya çıkmasına neden olabilir. Chrome, uzun süre çalışan boya iş parçacıklarının bile ana iş parçacığının duyarlılığını etkilememesi için boya iş parçacıklarını ana iş parçacığının dışına taşımaya çalışmaktadır.
Bana göre en heyecan verici potansiyel, boyama işinin, CSS özelliklerinin daha verimli bir şekilde çoklu doldurulmasına olanak vermesi. Bu özellik, tarayıcıda henüz bulunmayan bir özellik. Buna örnek olarak, yerel olarak Chrome'a gelene kadar konik renk geçişlerini çoklu doldurmak verilebilir. Başka bir örnek: Bir CSS toplantısında, artık birden fazla kenarlık rengi olabileceğine karar verilmiş. İş arkadaşım Ian Kilpatrick bu yeni CSS davranışı için boya işçisi kullanarak bir çoklu dolgu yazdı.
Kalıpların dışına çıkmak
Çoğu kişi boya iş uygulaması hakkında bilgi edindiğinde
arka plan ve kenarlık resimlerini düşünmeye başlar. Boyama iş öğesinin kullanımı daha az kolay bir kullanım alanı, DOM öğelerinin rastgele şekillere sahip olmasını sağlamak için mask-image
işlevidir. Örneğin, elmas:
mask-image
, öğenin boyutunda bir resim çeker. Maske resminin şeffaf, öğenin şeffaf olduğu alanlar. Maske resminin opak, öğenin opak olduğu alanlar.
Şimdi Chrome'da
Boyama iş akışı, bir süredir Chrome Canary'de. Chrome 65'te ise varsayılan olarak etkindir. Haydi, boya iş parçacığının sunduğu yeni olanakları deneyin ve ne yaptığınızı bize gösterin! Daha fazla ilham almak için Vincent De Oliveira'nın koleksiyonuna göz atın.