Может ли PaintWorklet быть встроенным? - PullRequest
1 голос
/ 03 апреля 2019

Идиоматический способ использования API CSS Paint выглядит следующим образом:

  1. Создание файла xyz.js
    • Заполнение классом, содержащим функцию paint(ctx, geom, properties)
    • Вызов registerPaint, передача класса в качестве аргумента
  2. Вызов CSS.paintWorklet.addModule('xyz.js') из вашего index.html
  3. Применение рабочего процесса рисования в CSS как background-image: paint(myPaintWorklet);

Подробнее об этом здесь: https://developers.google.com/web/updates/2018/01/paintapi

Но загрузка отдельного файла .js - это снижение производительности.

Есть ли способвстроить PaintWorklet, чтобы отдельный файл .js не требовался?

1 Ответ

1 голос
/ 03 апреля 2019

Один из способов сделать это - использовать URL данных . Демо: (работает у меня по крайней мере на хроме 73). Пример взят из здесь

<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 и передать 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>
...