That indeed looks like a bug in Chrome "experimental" implementation, you might want to let them know on their issue tracker, since that should work.
Now, while you are not doing anything bad per se, note that if instead of the non-standard zoom
we do use the transform
property, then the bug would not occur:
(()=> {
if( !CSS.paintWorklet ) {
return console.error('CSS Paint API is not supported in this browser, you may have to enable it from chrome://flags/#enable-experimental-web-platform-features');
}
const worklet_script = document.querySelector('[type="paint-worklet"]').textContent;
const worklet_blob = new Blob([worklet_script], { type: 'text/javascript' });
CSS.paintWorklet.addModule(URL.createObjectURL(worklet_blob));
window.addEventListener("DOMContentLoaded", () => {
const slider = document.getElementById("slider");
slider.addEventListener("input", () => {
const el = document.querySelector(".content");
el.style.transform = `scale(${slider.value},${slider.value})`;
});
});
})();
.content {
background: paint(sandbox);
border: 1px solid black;
height: 200px;
width: 200px;
transform-origin: top left;
}
<input type="range" id="slider" min="0.5" max="4" value="1" step="0.1" />
<div class="content"></div>
<script type="paint-worklet">
class SandboxPaintWorklet {
paint(context, geometry, properties) {
const { width, height } = geometry;
// background
context.fillStyle = "#8866aa";
context.fillRect(0, 0, width, height);
context.fillStyle = "#000000";
context.beginPath();
// vertical line
context.fillRect((width * 3) / 4, 0, 1, height);
// horizontal lines
const distance = Math.ceil(height / 20);
for (let i = 0; i < 20; ++i) {
context.fillRect(0, i * distance, width / 2, 1);
}
}
}
registerPaint("sandbox", SandboxPaintWorklet);
</script>
And even with zoom
, if instead of that many fillRect
, if we do fill a single sub-path by using rect()
instead, then that would also work.
(()=> {
if( !CSS.paintWorklet ) {
return console.error('CSS Paint API is not supported in this browser, you may have to enable it from chrome://flags/#enable-experimental-web-platform-features');
}
const worklet_script = document.querySelector('[type="paint-worklet"]').textContent;
const worklet_blob = new Blob([worklet_script], { type: 'text/javascript' });
CSS.paintWorklet.addModule(URL.createObjectURL(worklet_blob));
window.addEventListener("DOMContentLoaded", () => {
const slider = document.getElementById("slider");
slider.addEventListener("input", () => {
const el = document.querySelector(".content");
el.style.zoom = slider.value;
});
});
})();
.content {
background: paint(sandbox);
border: 1px solid black;
height: 200px;
width: 200px;
}
<input type="range" id="slider" min="0.5" max="4" value="1" step="0.1" />
<div class="content"></div>
<script type="paint-worklet">
class SandboxPaintWorklet {
paint(context, geometry, properties) {
const { width, height } = geometry;
// background
context.fillStyle = "#8866aa";
context.fillRect(0, 0, width, height);
context.fillStyle = "#000000";
context.beginPath();
// vertical line
context.rect((width * 3) / 4, 0, 1, height);
// horizontal lines
const distance = Math.ceil(height / 20);
for (let i = 0; i < 20; ++i) {
context.rect(0, i * distance, width / 2, 1);
}
context.fill();
}
}
registerPaint("sandbox", SandboxPaintWorklet);
</script>