【问题标题】:Can the PaintWorklet be inlined?PaintWorklet 可以内联吗?
【发布时间】:2020-04-25 09:45:45
【问题描述】:

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

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

更多细节在这里:https://developers.google.com/web/updates/2018/01/paintapi

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

有没有办法内联 PaintWorklet 以便不需要单独的 .js 文件?

【问题讨论】:

  • 嗯...也许一种解决方法是使用像 data:application/javascript,<code> 这样的数据 url 而不是文件 url...未尝试但可能有效...
  • @DevanshJ 我刚试过。我在 Chrome 中得到了一个 Uncaught (in promise) DOMException,尽管我可以在开发工具的网络选项卡中看到请求是 200
  • 我发布了一个工作演示

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


【解决方案1】:

一种方法是使用Data URLs。演示:(至少在 chrome 73 上对我有用)。示例取自here

<style>
  textarea {
    background-image: paint(checkerboard);
  }
</style>
<textarea></textarea>
<script>
  CSS.paintWorklet.addModule(`data:application/javascript;charset=utf8,${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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 2011-08-24
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多