Gölgelendiriciler, örgüler ve filtreler dünyasında Canvas2D sizi heyecanlandırmayabilir. Ama doğrudur.
Web sayfalarının% 30-40'ında <canvas>
öğesi bulunur ve tüm tuvallerin% 98'inde Canvas2D oluşturma bağlamı kullanılır. Arabalarda, buzdolabında ve uzayda (gerçekten) Canvas2D'ler vardır.
Son teknoloji 2D çizimler söz konusu olduğunda API'nin biraz geride kaldığını belirtmek isteriz. Neyse ki Canvas2D'de yeni özellikleri uygulamak, CSS'ye ayak uydurmak, ergonomik kullanımı kolaylaştırmak ve performansı artırmak için yoğun şekilde çalışıyoruz.
1. Bölüm: CSS'ye ayak uydurma
CSS'nin Canvas2D'de bulunmayan birkaç çizim komutu var. Yeni API ile en çok istenen birkaç özelliği ekledik:
Yuvarlak dikdörtgen
Yuvarlatılmış dikdörtgenler: İnternet'in, bilgi işlemin, neredeyse medeniyetin temel taşı.
Her bakımdan, yuvarlatılmış dikdörtgenler son derece yararlıdır: Düğmeler, sohbet balonları, küçük resimler, konuşma balonları gibi. Canvas2D'de yuvarlak bir dikdörtgen oluşturmak her zaman mümkün olmuştur. Bu yüzden biraz karışık oluyordu:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'magenta';
const top = 10;
const left = 10;
const width = 200;
const height = 100;
const radius = 20;
ctx.beginPath();
ctx.moveTo(left + radius, top);
ctx.lineTo(left + width - radius, top);
ctx.arcTo(left + width, top, left + width, top + radius, radius);
ctx.lineTo(left + width, top + height - radius);
ctx.arcTo(left + width, top + height, left + width - radius, top + height, radius);
ctx.lineTo(left + radius, top + height);
ctx.arcTo(left, top + height, left, top + height - radius, radius);
ctx.lineTo(left, top + radius);
ctx.arcTo(left, top, left + radius, top, radius);
ctx.stroke();
Mütevazı, basit bir yuvarlak dikdörtgen için tüm bunlar gerekliydi:
Yeni API ile roundRect()
yöntemi kullanılabilir.
ctx.roundRect(upper, left, width, height, borderRadius);
Dolayısıyla yukarıdakiler tamamen şununla değiştirilebilir:
ctx.roundRect(10, 10, 200, 100, 20);
ctx.roundRect()
yöntemi ayrıca en fazla dört sayılık borderRadius
bağımsız değişkeni için bir dizi alır. Bu yarıçaplar, yuvarlatılmış dikdörtgenin dört köşesini CSS'de olduğu gibi kontrol eder. Örneğin:
ctx.roundRect(10, 10, 200, 100, [15, 50, 30]);
Konik Gradyan
Çizgisel renk geçişleri gördünüz:
const gradient = ctx.createLinearGradient(0, 0, 200, 100);
gradient.addColorStop(0, 'blue');
gradient.addColorStop(0.5, 'magenta');
gradient.addColorStop(1, 'white');
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 200, 100);
Dairesel renk geçişleri:
const radialGradient = ctx.createRadialGradient(150, 75, 10, 150, 75, 70);
radialGradient.addColorStop(0, 'white');
radialGradient.addColorStop(0.5, 'magenta');
radialGradient.addColorStop(1, 'lightblue');
ctx.fillStyle = radialGradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
Peki ama güzel bir konik gradyana ne dersiniz?
const grad = ctx.createConicGradient(0, 100, 100);
grad.addColorStop(0, 'red');
grad.addColorStop(0.25, 'orange');
grad.addColorStop(0.5, 'yellow');
grad.addColorStop(0.75, 'green');
grad.addColorStop(1, 'blue');
ctx.fillStyle = grad;
ctx.fillRect(0, 0, 200, 200);
Metin değiştiriciler
Canvas2D'nin metin oluşturma özelliklerinin çok gerisinde kaldı. Chrome, Canvas2D metin oluşturmaya birkaç yeni özellik ekledi:
- ctx.letterSpacing
- ctx.wordSpacing
- ctx.fontVariant
- ctx.fontKerning
- ctx.fontStretch
- ctx.textDecoration
- ctx.textUnderlinePosition
- ctx.textRendering
Bu özelliklerin tümü, aynı ada sahip CSS eşdeğerleriyle eşleşir.
2. bölüm: ergonomik ince ayarlar
Önceden, Canvas2D ile bazı şeyler mümkün olsa da uygulanması gereksiz derecede karmaşıktı. Burada, Canvas2D'yi kullanmak isteyen JavaScript geliştiricileri için bazı yaşam kalitesi iyileştirmelerini görebilirsiniz:
Bağlam sıfırlandı
Bir tuvalin nasıl temizlendiğini açıklamak üzere, retro deseni çizecek şekilde küçük bir işlevimiz var:
draw90sPattern();
İsteğinizi aldık. Bu desenle işim bittiğinde, kanvası temizlemek ve başka bir şey çizmek istiyorum.
Bir kanvas tekrar nasıl temizlenir? İşte bu! Tabii ki ctx.clearRect()
.
ctx.clearRect(0, 0, canvas.width, canvas.height);
Ne de olsa işe yaramadı. İşte bu! Önce dönüşümü sıfırlamam gerekiyor:
ctx.resetTransform();
ctx.clearRect(0, 0, canvas.width, canvas.height);
Mükemmel! Güzel bir boş tuval. Şimdi güzel bir yatay çizgi çizmeye başlayalım:
ctx.moveTo(10, 10);
ctx.lineTo(canvas.width, 10);
ctx.stroke();
Hırrrr! Doğru değil! 😡 O ekstra çizginin burada ne işi var? Bir de neden pembe? Tamam, şimdi StackOverflow'u kontrol edelim.
canvas.width = canvas.width;
Neden bu kadar gülünç? Neden bu kadar zor?
Ama artık durum yok. Yeni API'de çığır açıcı, sade ve şık bir tasarım var:
ctx.reset();
Bu işlem uzun sürdüğü için özür dileriz.
Filtreler
SVG filtreleri başlı başına ayrı bir dünyadır. Bu ekip sizi yeni kullanmaya başladıysa, muhteşem potansiyellerinden bazılarını gösteren The Art Of SVG Filtreler And Why It Is Awesome (SVG Sanatı Filtreleri ve Neden Başarılı Olunur?) adlı makaleyi okumanızı kesinlikle öneririm.
SVG stili filtreler Canvas2D için zaten kullanılabilir. Filtreyi, sayfadaki başka bir SVG filtre öğesine işaret eden URL olarak iletmeye istekli olmanız gerekir:
<svg>
<defs>
<filter id="svgFilter">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
<feConvolveMatrix kernelMatrix="-3 0 0 0 0.5 0 0 0 3" />
<feColorMatrix type="hueRotate" values="90" />
</filter>
</defs>
</svg>
const canvas = document.createElement('canvas');
canvas.width = 500;
canvas.height = 400;
const ctx = canvas.getContext('2d');
document.body.appendChild(canvas);
ctx.filter = "url('#svgFilter')";
draw90sPattern(ctx);
Bu da kalıbımızı bayağı bozuyor.
Ancak, yukarıdakileri yapmak ancak JavaScript'te kalmak ve dizelerle uğraşmak istememek isterseniz ne yapabilirsiniz? Yeni API ile bu tamamen mümkün.
ctx.filter = new CanvasFilter([
{ filter: 'gaussianBlur', stdDeviation: 5 },
{
filter: 'convolveMatrix',
kernelMatrix: [
[-3, 0, 0],
[0, 0.5, 0],
[0, 0, 3],
],
},
{ filter: 'colorMatrix', type: 'hueRotate', values: 90 },
]);
Çok kolay! Deneyin ve buradaki demoda yer alan parametrelerle oynayın.
3. Bölüm: Performans iyileştirmeleri
Yeni Canvas2D API ile mümkün olduğunda performansı artırmak da istedik. Geliştiricilerin web siteleri üzerinde daha ayrıntılı bir kontrole sahip olmasını sağlamak ve mümkün olan en hassas kare hızlarını sağlamak için birkaç özellik ekledik:
Sık okuyacakım
Piksel verilerini kanvastan geri okumak için getImageData()
uygulamasını kullanın. Çok yavaş olabilir. Yeni API, okuma amacıyla bir kanvası açıkça işaretlemenin bir yolunu sunar (örneğin, oluşturma efektler için).
Bu sayede, gelişmiş özellikleri optimize edebilir ve daha çeşitli kullanım alanları için kanvasın hızlı olmasını sağlayabilirsiniz. Bu özellik bir süredir Firefox'taydı ve nihayet tuval spesifikasyonunun bir parçası haline getiriyoruz.
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true });
Bağlam kaybı
Üzgün sekmeleri tekrar mutlu edelim! Bir istemcinin GPU belleğinin tükenmesi veya tuvalinize başka bir felaketin düşmesi durumunda artık geri arama alabilir ve gerektiğinde yeniden çizim yapabilirsiniz:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.addEventListener('contextlost', onContextLost);
canvas.addEventListener('contextrestored', redraw);
Tuval bağlamı ve kaybı hakkında daha fazla bilgi edinmek istiyorsanız WhatsApp'ın wiki'sinde iyi bir açıklaması bulunmaktadır.
Sonuç
Canvas2D'yi kullanmaya yeni başlamış, yıllardır kullanıyor veya yıllardır kullanmaktan kaçınmış olun, kanvasa başka bir görünüm kazandırmak için size yardımcı olmaya hazırız. Bu, en başından beri API'nin anahtarıydı.
Teşekkür
Unsplash'teki Sandie Clarke'ın lokomotif resmi.