可以内联PaintWorklet吗?

时间:2019-04-03 20:41:43

标签: css css-houdini css-paint-api

使用CSS Paint API的惯用方式似乎是:

  1. 创建一个xyz.js文件
    • 使用包含paint(ctx, geom, properties)函数的类填充
    • 调用registerPaint,将类作为参数传递
  2. 从您的CSS.paintWorklet.addModule('xyz.js')致电index.html
  3. background-image: paint(myPaintWorklet);一样在CSS中应用绘画工作集

此处有更多详细信息:https://developers.google.com/web/updates/2018/01/paintapi

但是必须加载一个单独的.js文件会影响性能。

是否可以内联PaintWorklet,从而不需要单独的.js文件?

1 个答案:

答案 0 :(得分:1)

一种方法是使用Data URLs。演示:(至少对我来说适用于chrome 73)。取自here

的示例

<style>
  textarea {
    background-image: paint(checkerboard);
  }
</style>
<textarea></textarea>
<script>
  CSS.paintWorklet.addModule(`data:application/javascript;charset=ut8,${encodeURIComponent(`
    // checkerboard.js
    class CheckerboardPainter {
      paint(ctx, geom, properties) {
        // Use "ctx" as if it was a normal canvas
        const colors = ['red', 'green', 'blue'];
        const size = 32;
        for(let y = 0; y < geom.height/size; y++) {
          for(let x = 0; x < geom.width/size; x++) {
            const color = colors[(x + y) % colors.length];
            ctx.beginPath();
            ctx.fillStyle = color;
            ctx.rect(x * size, y * size, size, size);
            ctx.fill();
          }
        }
      }
    }
  
    // Register our class under a specific name
    registerPaint('checkerboard', CheckerboardPainter);
  `)}`)
</script>

另一种方法是制作一个Blob并将Blob URL传递给addModule函数。这看起来不那么扎实。演示:

<style>
  textarea {
    background-image: paint(checkerboard);
  }
</style>
<textarea></textarea>
<script>
  CSS.paintWorklet.addModule(URL.createObjectURL(new Blob([`
    // checkerboard.js
    class CheckerboardPainter {
      paint(ctx, geom, properties) {
        // Use "ctx" as if it was a normal canvas
        const colors = ['red', 'green', 'blue'];
        const size = 32;
        for(let y = 0; y < geom.height/size; y++) {
          for(let x = 0; x < geom.width/size; x++) {
            const color = colors[(x + y) % colors.length];
            ctx.beginPath();
            ctx.fillStyle = color;
            ctx.rect(x * size, y * size, size, size);
            ctx.fill();
          }
        }
      }
    }
  
    // Register our class under a specific name
    registerPaint('checkerboard', CheckerboardPainter);
  `], {type: "application/javascript"})))
</script>