add official Chrome feature demos

This commit is contained in:
2026-06-14 15:22:32 +08:00
parent 500217f2fd
commit de690f85fa
32 changed files with 2376 additions and 567 deletions
+69
View File
@@ -0,0 +1,69 @@
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const drawElement = document.getElementById('draw-element');
const statusPanel = document.getElementById('support-status');
const demoForm = document.getElementById('demo-form');
const hasHtmlInCanvas =
typeof ctx.drawElementImage === 'function' &&
typeof canvas.requestPaint === 'function';
function setStatus(state, message) {
statusPanel.dataset.state = state;
statusPanel.textContent = message;
}
function resizeCanvas(entry) {
const dpcSize = entry.devicePixelContentBoxSize?.[0];
const nextWidth = dpcSize?.inlineSize ?? Math.round(entry.contentRect.width * window.devicePixelRatio);
const nextHeight = dpcSize?.blockSize ?? Math.round(entry.contentRect.height * window.devicePixelRatio);
if (canvas.width !== nextWidth) {
canvas.width = nextWidth;
}
if (canvas.height !== nextHeight) {
canvas.height = nextHeight;
}
}
function paint() {
ctx.reset();
ctx.fillStyle = '#101820';
ctx.fillRect(0, 0, canvas.width, canvas.height);
const x = canvas.width / 25;
const y = canvas.height / 25;
const transform = ctx.drawElementImage(drawElement, x, y);
drawElement.style.transform = transform.toString();
}
demoForm.addEventListener('submit', (event) => {
event.preventDefault();
setStatus('ok', '表单提交事件来自真实 DOM:发射指令已拦截,demo 仍停留在当前页面。');
});
if (!hasHtmlInCanvas) {
document.body.dataset.api = 'fallback';
setStatus(
'fail',
'当前浏览器未暴露 drawElementImage/requestPaint。请使用 Chrome Canary 149+ 并开启 canvas-draw-element flag。'
);
} else {
document.body.dataset.api = 'native';
setStatus('ok', '已检测到 HTML-in-Canvas 实验 API,可以操作 canvas 中绘制的 DOM 表单。');
canvas.onpaint = paint;
const supportsDevicePixelContentBox =
typeof ResizeObserverEntry !== 'undefined' &&
'devicePixelContentBoxSize' in ResizeObserverEntry.prototype;
const resizeOptions = supportsDevicePixelContentBox ? { box: 'device-pixel-content-box' } : {};
const observer = new ResizeObserver(([entry]) => {
resizeCanvas(entry);
canvas.requestPaint();
});
observer.observe(canvas, resizeOptions);
canvas.requestPaint();
}