Chrome 150 ve 155 sürümlerinde, HTML-in-Canvas API'de çeşitli değişiklikler yapıldı. Bu değişiklikler, API'nin ergonomisini iyileştirmek amacıyla topluluk ve standartlardan gelen geri bildirimlere yanıt olarak yapıldı. Bu blog yayınında değişiklikler ve uygulamanızın bu değişikliklere uygun olduğundan nasıl emin olabileceğiniz açıklanmaktadır.
Güncellemeler arasında özelliklerin ve yöntemlerin yeniden adlandırılması, doku belleğinin önceden açıkça ayrılmasının zorunlu kılınması ve DOM senkronizasyon modellerinin güncellenmesi yer alıyor. Ayrıca, HTML-in-Canvas Origin Denemesi'nin süresi uzatıldı. Aşağıda, nelerin değiştiği, neden değiştiği ve kod tabanınızı nasıl güncelleyeceğiniz açıklanmaktadır.
Chrome 150'deki değişiklikler
Chrome 150'de, WebGL ve WebGPU'daki bağımsız değişken imzalarını değiştirerek gereksiz tekrarları ortadan kaldırdık ve modern grafik kurallarına uygun hale getirdik.
WebGL
texElementImage2D işlevinden gereksiz bağımsız değişkenleri (level, srcFormat, destType) kaldırdık
(daha fazla bilgi için WebGL tartışmasına bakın):
// Old implementation (Chrome < 150)
const level = 0;
const internalFormat = gl.RGBA;
const srcFormat = gl.RGBA;
const destType = gl.UNSIGNED_BYTE;
gl.texElementImage2D(
gl.TEXTURE_2D,
level,
internalFormat,
srcFormat,
destType,
element
);
// New implementation (from Chrome 150)
const internalFormat = gl.RGBA8;
gl.texElementImage2D(gl.TEXTURE_2D, internalFormat, element);
WebGPU
copyElementImageToTextureparametrelerini sourceDict ve destDict nesneleri olarak standartlaştırdık (bkz. GPUWeb PR#6250):
// Old implementation (Chrome < 150)
GPUQueue.copyElementImageToTexture(
element,
width,
height,
{ texture: texture }
);
// New implementation (from Chrome 150)
const sourceDict = { source: element };
const destDict = {
destination: { texture: texture },
width: width,
height: height
};
GPUQueue.copyElementImageToTexture(sourceDict, destDict);
Chrome 155'teki değişiklikler
Chrome 155, geliştiricilerden gelen geri bildirimlere dayalı olarak daha fazla iyileştirme sunuyor. Yöntem adlarını güncelliyoruz, doku belleğinin açıkça önceden ayrılmasını zorunlu kılıyoruz, karmaşık DOM alt ağaçlarını destekliyoruz ve DOM senkronizasyonunu ayırıyoruz.
WebGPU
WebGPU yöntemi, copyElementImageToTexture olan adından drawElementImageToTexture olarak yeniden adlandırıldı. Yeniden adlandırmanın yanı sıra parametre koordinatları genişletilir (sourceX, sourceWidth) ve hedef sınırları standart bir size (GPUExtent3D) nesnesinde gruplandırılır:
// BEFORE (Chrome 150)
const sourceDict = {
source: myElement,
sx: 0,
sy: 0,
swidth: 100,
sheight: 100
};
const destDict = {
destination: { texture: myTexture },
width: 300,
height: 200
};
queue.copyElementImageToTexture(sourceDict, destDict);
// AFTER (Chrome 155+)
const sourceDict = {
source: myElement,
sourceX: 0,
sourceY: 0,
sourceWidth: 100,
sourceHeight: 100
};
const destDict = {
texture: myTexture,
size: { width: 300, height: 200 }
};
queue.drawElementImageToTexture(sourceDict, destDict);
WebGL
HTML-in-Canvas için WebGL'deki değişikliklerin üç yönü vardır:
- Yöntem adı
texElementImage2DyerinetexElementSubImage2Dolarak değişir.` - Yöntem imzası değişir. En önemlisi, öğenin çizileceği hedef dokuda isteğe bağlı olarak bir ofset belirtmeye olanak tanımak için
xoffsetveyoffsetbağımsız değişkenleri eklenir. - Bu yöntem artık hedef doku için otomatik olarak arabellek depolama alanı ayırmıyor. Depolama alanı, API kullanılmadan önce açıkça ayrılmalıdır. Bu,
texSubImage2Ddavranışına benzer.
// 1. Capture natural layout size of the element
const elementImage = canvas.captureElementImage(element);
// 2. Pre-allocate texture backing once (or when element resizes)
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA8,
Math.ceil(elementImage.width),
Math.ceil(elementImage.height),
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
null // null reserves VRAM without uploading pixels
);
// 3. Upload DOM into pre-allocated VRAM
gl.texElementSubImage2D(
gl.TEXTURE_2D,
0, // level
0, // xoffset
0, // yoffset
element // pass DOM element
);
Tuval özellikleri ve çizilebilir alt öğeler
Canvas'ınızı HTML oluşturmaya hazırlama şeklinizi güncelliyoruz.
layoutsubtree dosyasını content="drawable" olarak yeniden adlandırma
HTML özelliği adlandırma kurallarına uygun olması için <canvas> öğesindeki boole layoutsubtree özelliği content="drawable" olarak yeniden adlandırıldı (Ayrıntılı tartışma için WICG Sorunu #169'a bakın).
Alt öğeler için drawable özelliği
Daha önce yalnızca bir tuvalin doğrudan alt öğeleri oluşturuluyordu. İşaretlemeyi düzleştirmeden karmaşık DOM hiyerarşilerini desteklemek için artık bağımsız olarak çizmek istediğiniz tüm alt öğelere drawable özelliğini açıkça ekleyebilirsiniz:
<!-- BEFORE -->
<canvas layoutsubtree>
<div id="badge">
<h2>Player Stats</h2>
<button id="actionBtn">Equip</button>
</div>
</canvas>
<!-- AFTER (Chrome 155+) -->
<canvas content="drawable">
<!-- Subtree A (Body and heading) -->
<div id="badge" drawable>
<h2>Player Stats</h2>
<!-- Subtree B (Excluded from Subtree A; drawn and animated independently) -->
<button id="actionBtn" drawable>Equip</button>
</div>
</canvas>
drawable içeren bir öğe, drawable belirten iç içe yerleştirilmiş alt öğeler hariç olmak üzere alt ağacının tamamını yakalar. Bu sayede üst kapsayıcılar ve düğmeler gibi alt öğeler ayrı çizim çağrılarıyla animasyonlandırılabilir ve çizilebilir.
Şarkı önerisi testlerinin senkronizasyonu
Daha önce geliştiricilerin, çizim yöntemlerinden döndürülen değeri yakalaması ve element.style.transform içine aktarması gerekiyordu. drawElementImage() yöntemi artık void değerini döndürüyor ve senkronizasyon bağlama bağlı.
2D Bağlamlar: Otomatik Senkronizasyon
2D tuvalde tarayıcı, DOM isabet testi sınırlarını ve ekran okuyucu odak halkalarını çizilen koordinatlarla otomatik olarak senkronize eder. Tüm manuel dönüştürme borularını kaldırabilirsiniz:
// BEFORE
const transform = ctx.drawElementImage(element, x, y);
element.style.transform = transform.toString();
// AFTER (Chrome 155+)
ctx.drawElementImage(element, x, y);
// No style update needed: position & hit-testing sync automatically
Geometriyi 2D'de manuel olarak yönetmek için { preserveElementGeometry: true } değerini drawElementImage() öğesine iletin ve canvas.updateElementGeometry() kullanarak dönüştürme uygulayın.
3D Bağlamlar: Uygunsuz updateElementGeometry()
WebGL veya WebGPU bağlamlarında DOM'u senkronize etmek için bir DOMMatrix transform
oluşturun ve bunu canvas.updateElementGeometry()'a iletin:
canvas.addEventListener('paint', () => {
// 1. Upload element snapshot to GPU texture
device.queue.drawElementImageToTexture({ source: element }, { texture });
// 2. Render 3D scene...
drawScene();
// 3. Construct transform matrix as needed
const canvasTransform = new DOMMatrix().translate(x, y);
// 4. Update DOM hit-testing and accessibility bounding boxes
canvas.updateElementGeometry(element, { canvasTransform });
});
Sürümler arası uyumluluk
Uygulamanız geçiş dönemi boyunca birden fazla Chrome sürümündeki kullanıcıları desteklemeliyse prototiplerinde güncellenmiş yöntemlerin olup olmadığını kontrol edin ve uygulamanızı buna göre ayarlayın.
Her tarayıcı sürümü için doğru <canvas> öğe özelliklerini ayarladığınızdan emin olun:
// ============================================================================
// Cross-version canvas markup
// ============================================================================
if (!canvas.hasAttribute('content') && !canvas.hasAttribute('layoutsubtree')) {
if ('content' in HTMLCanvasElement.prototype) {
// Chrome 155+ (New standardized attribute)
canvas.setAttribute('content', 'drawable');
} else {
// Chrome < 155 (Legacy boolean attribute)
canvas.setAttribute('layoutsubtree', '');
}
}
2D bağlam için drawElementImage() işlevinin dönüş değerini inceleyin ve her iki sürümü de desteklemek üzere kanvas prototipi özelliklerini kontrol edin:
// ============================================================================
// Cross-version 2D drawing & synchronization
// ============================================================================
function draw2DElement(ctx, element, x, y) {
// Execute the 2D draw call
const result = ctx.drawElementImage(element, x, y);
if (result !== undefined && typeof result?.toString === 'function') {
// Chrome < 155: drawElementImage returned a DOMMatrix
// Requires manual transform piping to align DOM hit-test bounds:
element.style.transform = result.toString();
} else {
// Chrome 155+: drawElementImage returns void / undefined
// The browser automatically aligns DOM positioning, clicks, and a11y bounds!
// If you previously had element.style.transform logic here, clear it:
if (element.style.transform) {
element.style.transform = "";
}
}
}
WebGPU için uyumlu yöntem imzasını ve adı kullanın:
// ============================================================================
// WebGPU cross-version support
// ============================================================================
if ('drawElementImageToTexture' in GPUQueue.prototype) {
// Chrome 155+ (Latest implementation)
queue.drawElementImageToTexture(
{ source: element, sourceX: 0, sourceY: 0, sourceWidth: w, sourceHeight: h },
{ texture: myTexture, size: { width: w, height: h } }
);
} else if (typeof queue.copyElementImageToTexture === "function") {
// Chrome 150 - 154: Try the Chrome 150+ dictionary signature first,
// then fall back to the Chrome < 150 signature
try {
queue.copyElementImageToTexture(
{ source: element },
{ destination: { texture: myTexture }, width: w, height: h }
);
} catch (err) {
// Chrome < 150
queue.copyElementImageToTexture(element, { texture: myTexture });
}
}
WebGL için tarayıcı uyumluluğunu kontrol ettiğinizden emin olun:
// ============================================================================
// WebGL cross-version support
// ============================================================================
if ('texElementSubImage2D' in WebGL2RenderingContext.prototype) {
// Chrome 155+ (Explicit pre-allocation + sub-image)
gl.texElementSubImage2D(gl.TEXTURE_2D, 0, 0, 0, element);
} else if (gl.texElementImage2D && gl.texElementImage2D.length === 3) {
// Chrome 150-154 (3-argument signature)
gl.texElementImage2D(gl.TEXTURE_2D, gl.RGBA8, element);
} else if (gl.texElementImage2D) {
// Chrome < 150 (6-argument signature)
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, element);
}
Origin Trial uzantısı
HTML-in-Canvas kaynak denemesi, Chrome 160'a kadar uzatıldı. Kullanıcılarınıza tuvalde HTML özelliğini sunmaya devam etmek için kaynak deneme jetonunuzu yenilediğinizden emin olun. Daha fazla bilgi için Origin denemesi makalesini inceleyin.
Görüşlerinizi paylaşın
Bu güncellemelerin uygulamalarınızda nasıl çalıştığını WICG GitHub deposunda sorun bildirerek bize bildirin. Canvas'ta HTML ile ilgili haberlerden haberdar olmak için geliştirici bültenine abone olun.