Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /html/canvas/offscreen/manual/draw-element-image/ink-overflow-worker.tentative.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<html class="reftest-wait">
<title>drawElementImage with ink overflow, in a worker thread.</title>
<meta charset="utf-8" />
<link rel="match" href="ink-overflow-worker-ref.html" />
<link rel="stylesheet" href="/html/canvas/resources/draw-element-image-styles.css" />
<script src="/html/canvas/resources/color-grid-component.js"></script>
<script src="/html/canvas/resources/wait-for-canvas-paint.js"></script>
<script src="/common/reftest-wait.js"></script>
<style>
body {
display: grid;
grid: 256px / 1fr 1fr 1fr;
align-items: start;
--blur-radius: 20px;
--spread: 10px;
}
canvas {
width: 256px;
height: 256px;
}
color-grid {
width: 100px;
height: 100px;
}
.box-shadow {
box-shadow: 0px 0px var(--blur-radius) var(--spread) hotpink;
}
.outline {
outline: 5px solid salmon;
}
</style>
<canvas layoutsubtree>
<div class="draw-element-wrapper box-shadow" outset="50" offset="20">
<color-grid></color-grid>
</div>
</canvas>
<canvas layoutsubtree>
<div class="draw-element-wrapper box-shadow" outset="50" offset="-50">
<color-grid></color-grid>
</div>
</canvas>
<canvas layoutsubtree>
<div class="draw-element-wrapper outline" xscale="1" yscale="1" outset="10" offset="30">
<color-grid></color-grid>
</div>
</canvas>
<canvas layoutsubtree>
<div class="draw-element-wrapper outline" outset="10" offset="-10">
<color-grid></color-grid>
</div>
</canvas>
<canvas layoutsubtree>
<div class="draw-element-wrapper outline" outset="-10" offset="20">
<color-grid></color-grid>
</div>
</canvas>
<script type="module">
import {
computeScaledDestinationSize,
resizeToPixelGrid
} from "/html/canvas/resources/draw-element-image-utils.js";
const workerCode = `
let ctx;
self.onmessage = function(e) {
if (e.data.canvas) {
ctx = e.data.canvas.getContext('2d');
}
if (e.data.elementImage) {
if (e.data.args.length === 8) {
ctx.drawElementImage(e.data.elementImage,
e.data.args[0], e.data.args[1], e.data.args[2], e.data.args[3],
e.data.args[4], e.data.args[5], e.data.args[6], e.data.args[7]);
} else {
ctx.drawElementImage(e.data.elementImage,
e.data.args[0], e.data.args[1], e.data.args[2], e.data.args[3],
e.data.args[4], e.data.args[5]);
}
self.postMessage('done');
}
};
`;
const workerUrl = URL.createObjectURL(new Blob([workerCode], { type: 'application/javascript' }));
(async () => {
const worker = new Worker(workerUrl);
for (const cvs of document.querySelectorAll("canvas")) {
await resizeToPixelGrid(cvs);
await new Promise(setTimeout);
const target = cvs.firstElementChild;
const targetStyle = getComputedStyle(target);
const targetWidth = Number.parseFloat(targetStyle.width);
const targetHeight = Number.parseFloat(targetStyle.height);
// `outset` is in CSS pixels, `offset` is in canvas grid
const outset = Number.parseFloat(target.getAttribute("outset") || "0");
const offset = Number.parseFloat(target.getAttribute("offset") || "0");
let args = [];
if (target.hasAttribute("xscale") && target.hasAttribute("yscale")) {
const scaleX = Number.parseFloat(target.getAttribute("xscale"));
const scaleY = Number.parseFloat(target.getAttribute("yscale"));
const [destWidth, destHeight] =
computeScaledDestinationSize(cvs, target, scaleX, scaleY, 2 * outset, 2 * outset);
args = [-outset, -outset,
targetWidth + 2 * outset, targetHeight + 2 * outset,
offset, offset, destWidth, destHeight];
} else {
args = [-outset, -outset,
targetWidth + 2 * outset, targetHeight + 2 * outset,
offset, offset];
}
const offscreen = cvs.transferControlToOffscreen();
worker.postMessage({ canvas: offscreen }, [offscreen]);
await new Promise(resolve => {
worker.onmessage = () => {
resolve();
};
const elementImage = cvs.captureElementImage(target);
worker.postMessage({ elementImage: elementImage, args: args }, [elementImage]);
});
}
})().then(async () => {
// Wait for the worker thread to update before taking a screenshot.
await waitForCanvasPaint(document.querySelector("canvas"));
takeScreenshot();
});
</script>