0

我正面临 css paint worklet 的问题,我想知道它是浏览器错误还是我做错了什么。在 worklet 中,我正在绘制几个矩形。如果其中一个覆盖了整个区域,那么当我更改缩放级别时,其他的就会开始消失。但是当我删除所有东西时,context.fillRect(0, 0, width, height)一切都像魅力一样。

这是我为更好地说明问题而准备的沙箱代码:https ://codesandbox.io/s/magical-villani-py8x2

有背景

在此处输入图像描述

4

1 回答 1

0

这确实看起来像是 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>

于 2020-05-07T14:26:18.467 回答