Программная генерация изображений с помощью API CSS Painting

от автора

JavaScript API для динамического создания изображений в сочетании с CSS

Для будущих студентов курса «JavaScript Developer. Professional» подготовили перевод материала.

Также приглашаем посетить открытый вебинар на тему «Vue 3 — возможности новой версии одного из самых популярных фронтенд фреймворков». На занятии участники вместе с экспертом:
— рассмотрят ключевые отличия в синтаксисе vue2 от vue3;
— разберут, как работать с vue-router и VueX в новой версии фреймворка;
— попробуют создать проект на Vue 3 с нуля с помощью Vue-cli.
Присоединяйтесь!


Картинки вносят колорит в приложения. Однако, как мы все знаем, наличие большого количества изображений высокого разрешения влияет на время загрузки страницы. Для иллюстраций продуктов, сценариев и так далее, у нас нет другого выбора, кроме как добавить эти изображения и оптимизировать приложение путем их кэширования. Но если вам нужно геометрическое изображение в приложении, тогда не потребуется включать его в качестве дополнительного ресурса.

Вы можете программно генерировать геометрические изображения «на лету», используя API CSS Painting.

Давайте выясним, что это за API и как сгенерировать изображение с его помощью.

Введение в API CSS Painting

CSS Painting API позволяет разработчикам писать JavaScript-функции для отрисовки изображений в свойствах CSS, таких как background-image и border-image. Он предоставляет набор API, который дает разработчикам доступ к CSSOM. Это часть CSS Houdini (Houdini — коллекция новых API браузера, предоставляющая разработчикам доступ к самому CSS на более низком уровне).

Традиционный подход к добавлению изображения следующий:

div {   background-image: url('assets/background.jpg); }

С помощью CSS Painting API можно вызвать функцию paint() и передать ей ворклет (worklet), который написан с помощью JS, вместо вышеуказанного способа.

div {   background-image: paint(background); }

В этом случае рабочий процесс будет выглядеть следующим образом.

Возможно, вы столкнулись с неизвестными терминами в вышеуказанном разделе. Например, что это за worklets, о которых мы продолжаем говорить?

Вкратце, JavaScript-код, написанный для программной генерации изображения, называется Paint Worklet (Рабочий пакет для рисования). Worklet — это точка расширения в канале рендеринга браузера. Есть и другие типы ворклетов (worklets), помимо worklets для рисования, например, worklets анимации, макетирования и т.д.

Теперь давайте рассмотрим пошаговый подход к программной генерации изображения.

Использование API CSS Painting на практике

В этой статье мы рассмотрим, как создать пузырьковый фон.

Шаг 1: Добавить функцию paint() в CSS

Прежде всего, вам нужно добавить функцию paint() в свойство CSS, на котором должно быть изображение.

.bubble-background {   width: 400px;   height: 400px;   background-image: paint(bubble); }

bubble будет worklet, который мы создадим для генерации изображений. Это будет сделано в следующих нескольких шагах.

.           .           .

Совет: поделитесь своими многократно используемыми компонентами между проектами, используя Bit (Github).

Bit упрощает совместное использование, документирование и повторное использование независимых компонентов между проектами. Используйте его, чтобы максимизировать повторное использование кода, сохранить единый дизайн, ускорить доставку и построить приложения, которые будут расширяться.

Bit поддерживает Node, TypeScript, React, Vue, Angular и многое другое.

Анимация. Пример: исследование компонентов React многоразового использования, совместно используемых на Bit.dev.

.           .           .

Шаг 2: Создание ворклета (worklet)

Ворклеты (worklets) должны храниться во внешнем JS-файле. Ворклет для рисования (paint worklet) будет class. Например: - class Bubble { …. } . Этот ворклет (worklet) необходимо зарегистрировать с помощью метода registerPaint().

class Bubble {     paint(context, canvas, properties) {         ........     } } registerPaint('bubble', Bubble);

Первым параметром метода registerPaint() должна быть ссылка, которую вы включили в CSS.

Теперь нарисуем фон.

class Bubble {     paint(context, canvas, properties) {         const circleSize = 10;          const bodyWidth = canvas.width;         const bodyHeight = canvas.height;          const maxX = Math.floor(bodyWidth / circleSize);         const maxY = Math.floor(bodyHeight / circleSize);           for (let y = 0; y < maxY; y++) {           for (let x = 0; x < maxX; x++) {             context.fillStyle = '#eee';             context.beginPath();             context.arc(x * circleSize * 2 + circleSize, y * circleSize * 2 + circleSize, circleSize, 0, 2 * Math.PI, true);             context.closePath();             context.fill();           }        }     } } registerPaint('bubble', Bubble);

Логика создания изображения находится внутри метода paint(). Вам понадобится немного знаний о создании холста, чтобы рисовать изображения, как описано выше. Обратитесь к документации по  Canvas API, если вы не знакомы с ним.

Шаг 3: Запустите ворклет (worklet)

Последним шагом будет запуск ворклета (worklet) в HTML-файле.

<div class="bubble-background"></div> <script>  CSS.paintWorklet.addModule('https://codepen.io/viduni94/pen/ZEpgMja.js'); </script>

Готово!

Вы программно сгенерировали изображение всего за 3 шага.

Сгенерированное изображение

Результат того, что мы создали, будет выглядеть следующим образом.

View in Editor (просмотр в редакторе)

Что еще мы можем сделать с помощью этого API CSS Painting?

Возможности CSS Painting API еще не исчерпаны. Есть другие вещи, которые вы можете с ним сделать.

1. Вы можете создавать динамические изображения

Например, можно динамически изменять цвет пузырьков. Для этого применяются переменные CSS. Чтобы применить CSS-переменные, браузер должен заранее знать, что мы их используем. Для этого мы можем задействовать метод inputProperties().

registerPaint('bubble', class {   static get inputProperties() {    return ['--bubble-size', '--bubble-color'];   }    paint() {     /* ... */   } });

Переменные могут быть назначены с помощью третьего параметра, переданного в метод paint().

paint(context, canvas, properties) {    const circleSize = parseInt(properties.get('--bubble-size').toString());    const circleColor = properties.get('--bubble-color').toString();    const bodyWidth = canvas.width;    const bodyHeight = canvas.height;     const maxX = Math.floor(bodyWidth / circleSize);    const maxY = Math.floor(bodyHeight / circleSize);      for (let y = 0; y < maxY; y++) {      for (let x = 0; x < maxX; x++) {        context.fillStyle = circleColor;        context.beginPath();        context.arc(x * circleSize * 2 + circleSize, y * circleSize * 2 + circleSize, circleSize, 0, 2 * Math.PI, true);        context.closePath();        context.fill();      }    } }

2. Вы можете генерировать случайные изображения с помощью Math.random() в методе paint().

// CSS body {   width: 200px;   height: 200px;   background-image: paint(random); } // JS function getRandomHexColor() {   return '#'+ Math.floor(Math.random() * 16777215).toString(16) } class Random {   paint(context, canvas) {     const color1 = getRandomHexColor();     const color2 = getRandomHexColor();      const gradient = context.createLinearGradient(0, 0, canvas.width, 0);     gradient.addColorStop(0, color1);     gradient.addColorStop(1, color2);      context.fillStyle = gradient;     context.fillRect(0, 0, canvas.width, canvas.height);   } } registerPaint('random', Random);

Если вы хотите узнать больше о том, как это реализовать, дайте мне знать в разделе комментариев ниже.

Это потрясающе, не так ли?

Но каждая хорошая вещь имеет хотя бы одну плохую сторону. Этот API имеет очень ограниченную поддержку в браузерах.

Поддержка браузеров

Источник: Can I Use
Источник: Can I Use

Большинство браузеров, включая Firefox, не поддерживают CSS Paint API. Только браузеры на основе Chrome и Chromium пока что имеют полную поддержку. Будем надеяться, что поддержка браузеров улучшится в ближайшем будущем.

Резюме

CSS Paint API чрезвычайно полезен для сокращения времени отклика сетевых запросов. Это достигается путем генерации некоторых изображений программно, а не путем их получения через сетевые запросы.

Кроме того, основные преимущества, на мой взгляд, следующие.

  • Возможность создавать полностью настраиваемые изображения в отличие от статических.

  • Создание изображений, не зависящих от разрешения (больше никаких изображений плохого качества на вашем сайте).

Важным моментом является то, что вы можете использовать полифил (polyfill) в качестве обходного пути для поддержки таких браузеров, как Firefox, которые еще не реализовали CSS Painting API.

Сообщите ваши мысли по этому поводу тоже. Спасибо за чтение!


Узнать подробнее о курсе «JavaScript Developer. Professional».

Смотреть открытый вебинар на тему «Vue 3 — возможности новой версии одного из самых популярных фронтенд фреймворков».

ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/546170/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *