我正面临 css paint worklet 的问题,我想知道它是浏览器错误还是我做错了什么。在 worklet 中,我正在绘制几个矩形。如果其中一个覆盖了整个区域,那么当我更改缩放级别时,其他的就会开始消失。但是当我删除所有东西时,context.fillRect(0, 0, width, height)
一切都像魅力一样。
这是我为更好地说明问题而准备的沙箱代码:https ://codesandbox.io/s/magical-villani-py8x2
我正面临 css paint worklet 的问题,我想知道它是浏览器错误还是我做错了什么。在 worklet 中,我正在绘制几个矩形。如果其中一个覆盖了整个区域,那么当我更改缩放级别时,其他的就会开始消失。但是当我删除所有东西时,context.fillRect(0, 0, width, height)
一切都像魅力一样。
这是我为更好地说明问题而准备的沙箱代码:https ://codesandbox.io/s/magical-villani-py8x2
这确实看起来像是 Chrome“实验”实现中的一个错误,你可能想让他们知道他们的问题跟踪器,因为这应该可以工作。
现在,虽然您本身并没有做任何坏事,但请注意,如果zoom
我们使用该transform
属性而不是非标准的,那么该错误将不会发生:
(()=> {
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>
即使使用zoom
, if 而不是那么多fillRect
,如果我们确实通过使用来填充单个子路径rect()
,那么这也可以。
(()=> {
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>