PaintWorklet 可以内联吗?
Can the PaintWorklet be inlined?
使用 CSS 画图 API 的惯用方法似乎是:
- 创建
xyz.js
文件
- 使用包含
paint(ctx, geom, properties)
函数的 class 进行填充
- 调用
registerPaint
,将 class 作为参数传递
- 从您的
index.html
呼叫 CSS.paintWorklet.addModule('xyz.js')
- 像
background-image: paint(myPaintWorklet);
一样在CSS中应用paint worklet
这里有更多详细信息:https://developers.google.com/web/updates/2018/01/paintapi
但是必须加载单独的 .js 文件会影响性能。
有没有办法内联 PaintWorklet,从而不需要单独的 .js 文件?
一种方法是使用 Data URLs. Demo: (works for me atleast on chrome 73). Example taken from 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>
使用 CSS 画图 API 的惯用方法似乎是:
- 创建
xyz.js
文件- 使用包含
paint(ctx, geom, properties)
函数的 class 进行填充 - 调用
registerPaint
,将 class 作为参数传递
- 使用包含
- 从您的
index.html
呼叫 - 像
background-image: paint(myPaintWorklet);
一样在CSS中应用paint worklet
CSS.paintWorklet.addModule('xyz.js')
这里有更多详细信息:https://developers.google.com/web/updates/2018/01/paintapi
但是必须加载单独的 .js 文件会影响性能。
有没有办法内联 PaintWorklet,从而不需要单独的 .js 文件?
一种方法是使用 Data URLs. Demo: (works for me atleast on chrome 73). Example taken from 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>