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 имеет очень ограниченную поддержку в браузерах.
Поддержка браузеров
Большинство браузеров, включая Firefox, не поддерживают CSS Paint API. Только браузеры на основе Chrome и Chromium пока что имеют полную поддержку. Будем надеяться, что поддержка браузеров улучшится в ближайшем будущем.
Резюме
CSS Paint API чрезвычайно полезен для сокращения времени отклика сетевых запросов. Это достигается путем генерации некоторых изображений программно, а не путем их получения через сетевые запросы.
Кроме того, основные преимущества, на мой взгляд, следующие.
Возможность создавать полностью настраиваемые изображения в отличие от статических.
Создание изображений, не зависящих от разрешения (больше никаких изображений плохого качества на вашем сайте).
Важным моментом является то, что вы можете использовать полифил (polyfill) в качестве обходного пути для поддержки таких браузеров, как Firefox, которые еще не реализовали CSS Painting API.
Сообщите ваши мысли по этому поводу тоже. Спасибо за чтение!
Узнать подробнее о курсе "JavaScript Developer. Professional".
Смотреть открытый вебинар на тему «Vue 3 — возможности новой версии одного из самых популярных фронтенд фреймворков».
Zavtramen
С одной стороны здорово, что добавляется такой функционал, иногда он может быть полезен. Но мне кажется, увеличивающаяся сложность самого браузера слишком большая цена за все эти интересные, но прямо скажем необязательные штуки.