Gölgelendiriciler, ağlar ve filtreler dünyasında Canvas2D sizi heyecanlandırmayabilir. Ancak bu şekilde olmalıdır.
Web sayfalarının% 30-40'ında bir <canvas>
öğesi bulunur ve tüm kanvasların% 98'inde Canvas2D oluşturma bağlamı kullanılır. Canvas2D'ler arabalarda, buzdolaplarında ve uzaydaki cihazlarda (evet, gerçekten) bulunur.
API'nin, en son teknoloji 2D çizim konusunda biraz geride olduğu kabul edilmelidir. Neyse ki CSS'ye yetişmek, ergonomiyi kolaylaştırmak ve performansı artırmak için Canvas2D'de yeni özellikler uygulamak üzere yoğun bir şekilde çalışıyoruz.
1. Bölüm: CSS'yi yakalama
CSS'de, Canvas2D'de eksik olan birkaç çizim komutu vardır. Yeni API ile en çok istenen özelliklerden birkaçını ekledik:
Yuvarlak dikdörtgen
Köşeleri yuvarlatılmış dikdörtgenler: internetin, bilgisayarcılığın ve hatta uygarlığın temel taşı.
Yuvarlatılmış dikdörtgenler, düğme, sohbet balonu, küçük resim, konuşma balonu gibi pek çok alanda son derece kullanışlıdır. Canvas2D'de yuvarlatılmış dikdörtgen oluşturmak her zaman mümkündü, ancak bu işlem biraz karmaşıktı:
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();
Bunların hepsi, daha küçük boyutlu, basit ve yuvarlak bir dikdörtgen için gerekliydi:
Yeni API'de roundRect()
yöntemi vardır.
ctx.roundRect(upper, left, width, height, borderRadius);
Bu nedenle, yukarıdaki kod tamamen şu şekilde değiştirilebilir:
ctx.roundRect(10, 10, 200, 100, 20);
ctx.roundRect()
yöntemi ayrıca en fazla dört sayıya sahip 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 güzel bir konik gradyan nasıl olur?
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 özellikleri çok geride 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 karşılıklarıyla eşleşir.
2. Bölüm: ergonomik düzenlemeler
Daha önce Canvas2D ile bazı özelliklerin kullanılması mümkündü ancak bu özelliklerin uygulanması fazlasıyla karmaşıktı. Canvas2D kullanmak isteyen JavaScript geliştiricileri için bazı yaşam kalitesi iyileştirmeleri aşağıda verilmiştir:
Bağlam sıfırlama
Bir kanvası temizlemeyi açıklamak için retro desen çizen küçük ve saçma bir işlev yazdım:
draw90sPattern();
Mükemmel! Bu deseni tamamladığıma göre tuvali temizleyip başka bir şey çizmek istiyorum.
Bir tuvali tekrar nasıl temizleyeceğiz? İşte bu! ctx.clearRect()
, elbette.
ctx.clearRect(0, 0, canvas.width, canvas.height);
Bu işlem çalışmadı. Evet. Öncelikle dönüşümü sıfırlamamız gerekiyor:
ctx.resetTransform();
ctx.clearRect(0, 0, canvas.width, canvas.height);
Mükemmel! Güzel, boş bir tuval. Şimdi güzel bir yatay çizgi çizmeye başlayalım:
ctx.moveTo(10, 10);
ctx.lineTo(canvas.width, 10);
ctx.stroke();
Hırrrr! Bu doğru değil. 😡 O fazladan hattın burada anlamı nedir? Ayrıca, neden pembe? Tamam, StackOverflow'u kontrol edelim.
canvas.width = canvas.width;
Bu neden çok saçma? Bu neden bu kadar zor?
Ama artık değil. Yeni API ile basit, zarif ve güzel bir yeniliğe kavuştuk:
ctx.reset();
Bu kadar uzun sürdüğü için özür dilerim.
Filtreler
SVG filtreleri başlı başına bir dünyadır. SVG filtreleri sizin için yeniyse SVG Filtrelerinin Sanatı ve Neden Muhteşem Olduğu başlıklı makaleyi okumanızı öneririz. Bu makalede, SVG filtrelerinin şaşırtıcı potansiyelinden bazıları gösterilmektedir.
SVG stil filtreleri Canvas2D için kullanıma sunuldu. Filtreyi, sayfadaki başka bir SVG filtresi öğesine işaret eden bir URL olarak iletmeniz yeterlidir:
<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 modelimizi iyice karıştırıyor:
Ancak yukarıdakileri yapmak istiyorsanız ancak JavaScript'te kalmak ve dizelerle uğraşmak istemiyorsanız ne olur? Yeni API ile bu tamamen mümkündür.
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 },
]);
Bu kadar kolay. Bu demoda parametrelerle oynayarak deneyebilirsiniz.
3. Bölüm: Performans iyileştirmeleri
Yeni Canvas2D API ile mümkün olduğunda performansı da artırmak istedik. Geliştiricilerin web siteleri üzerinde daha ayrıntılı kontrol sahibi olması ve mümkün olan en yüksek kare hızlarını elde etmesi için birkaç özellik ekledik:
Sık sık okuyacak
Bir kanvastaki piksel verilerini geri okumak için getImageData()
işlevini kullanın. Çok yavaş olabilir. Yeni API, bir kanvası tekrar okumak için açıkça işaretlemenize olanak tanır (ör. üretken efektler için).
Bu sayede, arka planda optimizasyon yapabilir ve kanvası daha fazla kullanım alanı için hızlı tutabilirsiniz. Bir süredir Firefox'ta bulunan bu özelliği artık kanvas 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ği tükenirse veya tuvalinizde başka bir felaket meydana gelirse artık geri arama alabilir ve gerektiği gibi yeniden çizebilirsiniz:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.addEventListener('contextlost', onContextLost);
canvas.addEventListener('contextrestored', redraw);
Kanvas bağlamı ve kaybı hakkında daha fazla bilgi edinmek isterseniz WhatWG'nin wiki'sinde iyi bir açıklaması vardır.
Sonuç
Canvas2D'yi kullanmaya yeni başlayanlar, yıllardır kullanıyor veya yıllardır kullanmaktan kaçınıyor olabilirsiniz. Her durumda tuvale yeniden bir görünüm kazandırmanızı istiyorum. O da hep yanımızda olan API'dir.