CSS Paint API'sı

Chrome 65'teki yeni olanaklar

CSS Paint API ("CSS Özel Boyama" veya "Houdini'nin boyama işleti" olarak da bilinir) Chrome 65'ten itibaren varsayılan olarak etkindir. Bu nedir? Ne işe yarar? Peki, YouTube Create'in işleyişi nasıldır? O zaman okumaya devam edin...

CSS Paint API, CSS mülkü resim beklediğinde programatik olarak bir görüntü oluşturmanıza olanak tanır. background-image veya border-image gibi özellikler, resim dosyası yüklemek için genellikle url() ile veya linear-gradient() gibi yerleşik CSS işlevleriyle kullanılır. Bunları kullanmak yerine artık paint(myPainter) kullanarak boya iş akışına referansta bulunabilirsiniz.

Boyama çalışma alanı yazma

myPainter adında bir boyama iş akışı tanımlamak için CSS.paintWorklet.addModule('my-paint-worklet.js') kullanarak CSS boyama iş akışı dosyası yüklememiz gerekiyor. Bu dosyada registerPaint işlevini kullanarak bir boya iş akışı sınıfı kaydedebiliriz:

class MyPainter {
  paint(ctx, geometry, properties) {
    // ...
  }
}

registerPaint('myPainter', MyPainter);

paint() geri çağırmasında ctx öğesini, <canvas> ürününden bildiğimiz şekilde CanvasRenderingContext2D kullanabiliriz. <canvas> çizmeyi biliyorsanız boyalı iş akışında çizim yapabilirsiniz. geometry, elimizdeki kanvasın genişliğini ve yüksekliğini belirtir. properties Bu makalenin devamında açıklayacağım.

Tanıtım örneği olarak, dama tahtası boyama iş akışı yazalım ve bunu bir <textarea> öğesinin arka plan resmi olarak kullanalım. (Varsayılan olarak yeniden boyutlandırılabileceği için bir 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.

Arka plan resmi olarak dama tahtası desenli metin alanı
Arka plan resmi olarak dama tahtası desenli metin alanı.

Burada yaygın olarak kullanılan bir arka plan resmi kullanmanın farkı, desenin kullanıcı metin alanını yeniden boyutlandırdığında istek üzerine yeniden çizilmesidir. Bu şekilde, arka plan resmi her zaman olması gerektiği kadar büyük olur. Yüksek yoğunluklu ekranlar için dengeleme hizmeti de buna dahildir.

Bu gerçekten çok güzel bir şey ama aynı zamanda oldukça durağan. Aynı deseni her istediğimizde ancak farklı boyutlarda karelere sahip yeni bir iş akışı mı yazmak isterdik? Yanıtım hayır.

İş akışınızı parametre haline getirme

Neyse ki, boyama 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 de dahil olmak üzere herhangi bir CSS mülkünde yapılan değişikliklere abone olabilirsiniz. Değerler, size properties parametresi üzerinden 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 tüm farklı dama tahtaları için kullanabiliriz. Ama daha da iyisi, doğru görünümü bulana kadar Geliştirici Araçları'na gidip değerlerle uğraşabiliriz.

Boyama iş uygulamasını desteklemeyen tarayıcılar

Yazma sırasında yalnızca Chrome'da boyama iş uygulaması bulunuyordu. Diğer tüm tarayıcı tedarikçilerinden olumlu sinyaller olsa da fazla bir ilerleme yok. Güncel kalmak için Is Houdini Henüz Hazır mı? sayfasını düzenli olarak kontrol edin. Bu süre zarfında, boyama iş akışı için destek olmasa bile kodunuzun çalışmaya devam etmesi için aşamalı geliştirme kullandığınızdan emin olun. İşlerin beklendiği gibi çalıştığından emin olmak için kodunuzu iki yerde ayarlamanız gerekir: CSS ve JS.

JS'de boyama işçisi desteği, CSS nesnesi kontrol edilerek yapılabilir: js if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('mystuff.js'); } CSS tarafında iki seçeneğiniz vardır. @supports aşağıdakileri kullanabilirsiniz:

@supports (background: paint(id)) {
  /* ... */
}

CSS'nin geçersiz kılındığı ve ardından bilinmeyen bir işlev varsa özellik bildiriminin tamamını yoksaydığı gerçeği, daha kompakt bir yöntemdir. Bir özelliği, önce boya iş akışı olmadan ve ardından boya iş akışıyla olmak üzere iki kez belirtirseniz aşamalı bir geliştirme elde edersiniz:

textarea {
  background-image: linear-gradient(0, red, blue);
  background-image: paint(myGradient, red, blue);
}

Boyama iş akışı destekleyen tarayıcılarda ikinci background-image bildirimi ilkinin üzerine yazılır. Boyama iş akışı desteklenmeyen tarayıcılarda ikinci beyan geçersizdir ve silinir. Bu da ilk bildirimin geçerli olmasını sağlar.

CSS Boya Polyfilli

Birçok kullanım için, modern tarayıcılara CSS Özel Boyama ve Boyama İş Akışı desteği ekleyen CSS Boyama Çoklu Doldurma yöntemi de kullanılabilir.

Kullanım alanları

Boyama iş akışları için birçok kullanım alanı vardır. Bu örneklerden bazıları diğerlerinden daha belirgindir. Bunlardan biri, DOM'nizin boyutunu küçültmek için boyama iş akışı kullanmaktır. Çoğu zaman öğeler sadece CSS kullanarak süslemeler oluşturmak için eklenir. Örneğin, Materyal Tasarım Lite'ta dalga efektli düğme, dalganın kendisini uygulamak için 2 ek <span> öğesi içerir. Çok sayıda düğmeniz varsa bu durum, çok sayıda DOM öğesi ekleyebilir ve mobil cihazlarda performansın düşmesine yol açabilir. Bunun yerine dalga efektini boyama iş akışı kullanarak uygularsanız 0 ek öğe ve yalnızca bir boyama işliğiniz olur. Ayrıca, özelleştirmek ve parametreleştirmek çok daha kolay olan bir öğeniz vardır.

Boyama iş uygulamasını kullanmanın bir başka olumlu tarafı da, çoğu senaryoda, boya iş akışı kullanan bir çözümün bayt açısından küçük olmasıdır. Elbette bir dezavantaj vardır: Tuvalin boyutu veya parametrelerden herhangi biri değiştiğinde boyama kodunuz çalışır. Bu nedenle kodunuz karmaşıksa ve uzun sürüyorsa soruna yol açabilir. Chrome, boya iş akışlarını ana iş parçacığından taşımak için çalışmaktadır. Böylece, uzun süre çalışan boyama iş akışları bile ana iş parçacığının yanıt verme hızını etkilemez.

Bana göre en heyecan verici potansiyel, boyama iş akışının, bir tarayıcıda henüz sahip olmadığı CSS özelliklerinin etkili bir şekilde çoklu doldurulmasına olanak sağlaması. Örneğin, Chrome'a yerel olarak inene kadar konik gradyanları çoklu dolduracak şekilde uygulayabilirsiniz. Başka bir örnek: Bir CSS toplantısında, artık birden fazla kenarlık renginiz olabileceğine karar verildi. Toplantı hâlâ devam ederken iş arkadaşım Ian Kilpatrick, boya iş uygulaması kullanarak bu yeni CSS davranışı için bir çoklu dolgu yazdı.

"Kalıpların" dışında düşünme

Çoğu kişi boya iş parçacığı hakkında bilgi edinirken arka plan resimleri ve kenarlık resimleri hakkında düşünmeye başlar. DOM öğelerinin rastgele şekillere sahip olmasını sağlamak için mask-image, boyama işleticisinde daha az sezgisel bir kullanım alanı olabilir. Örneğin, bir elmas:

Elmas şeklindeki bir DOM öğesi.
Elmas şeklindeki bir DOM öğesi.

mask-image, öğenin boyutuyla aynı boyutta bir resim çeker. Maske resminin şeffaf ve öğenin şeffaf olduğu alanlar. Maske resminin opak, öğe opak olduğu alanlar.

Artık Chrome'da

Boya çalışma alanı bir süredir Chrome Canary'de bulunuyor. Chrome 65'te, varsayılan olarak etkindir. Devam edin ve boya işçisinin açtığı yeni olasılıkları deneyin ve neler yaptığınızı bize gösterin! Daha fazla ilham almak için Vincent De Oliveira'nın koleksiyonuna göz atın.