Generative Art. Пишем картины на канвасе
- 14 марта 2019
- 26 981
Привет! Меня зовут Илья Борисов, я фронтенд-разработчик. Кроме работы, у меня есть хобби, о котором я и хочу немного рассказать. Возможно для вас это станет открытием новой сферы применения языков программирования, в частности, JavaScript.
Возможности программирования
Фронтенд часто ассоциируется только с вёрсткой сайтов и разработкой приложений. Но это только верхушка айсберга под названием «программирование». Это бесконечные возможности для самореализации и выражения идей и мыслей, и невероятный инструмент в руках творческого человека. Я говорю про Generative Art (генеративное искусство) и визуализацию аудио.
Я давно занимаюсь музыкой и всегда интересовался возможностью её визуализации. Так, исследуя это направление, наткнулся на несколько статей про генеративное искусство и увлёкся им. Теперь это моё хобби и возможность самовыражения. Ниже пара примеров, а остальное можно найти в моём Инстаграме:


Если объяснять простыми словами: вы пишете код, генерирующий определённое изображение с помощью придуманных вами же алгоритмов, оставляя при этом некоторую свободу в виде случайных значений.
Таким образом, каждое новое сгенерированное изображение будет уникально и, в то же время, будет сохранять идентичность, которую вы ему задали.
Это направление появилось вместе с возможностью визуализировать код и становится всё популярнее. С развитием генеративного искусства появились инструменты и фреймворки для людей, «программирующих искусство». В том или ином виде они есть практически для всех языков программирования. Для С++ — это Openframeworks, для JAVA — Processing, для Python и JavaScript — его модифицированные версии.
Конечно, не все используют готовые библиотеки, кто-то пишет на нативном коде, а кто-то даже разрабатывает свои инструменты. Я использую p5.js, о нём и пойдёт речь.
Для того чтобы глубже вникнуть в процесс разработки, давайте разберём одну из работ известного артиста в сфере генеративного искусства. Это художник из Аргентины Маноло Гамбоа. В качестве примера я взял одну из его последних и интересных работ, её вариации можно увидеть на странице Behance.
Как правило, художники выкладывают несколько сгенерированных работ, чтобы было понятно, что именно и как меняется с каждой итерацией.

Попробуем сами
Давайте я покажу, как создать похожую работу шаг за шагом.
Начнём с настройки окружения для работы с p5.js. Все примеры будут в CodePen, поэтому я просто подключу к нему последнюю версию p5.js и lodash
и напишу основные функции для работы.
В p5.js, как и в processing основные функции — setup()
и draw()
.
setup()
— здесь мы настраиваем и подготавливаем всё для работы.draw()
— отрисовывает результат. Стоит оговориться, что эта функция основана наrequestAnimationFrame
и мы можем не использовать её, если работаем только со статикой.
See the Pen Generative Art Demo by shvembldr (@Shvembldr) on CodePen.
Из рисунка видно, что это сетка с симметрично расположенными элементами. Давайте для начала реализуем один из них. Основная фигура — это квадрат со своеобразной окантовкой, прорисованной под углом, и создающей впечатление выпуклости.
Пробуем нарисовать квадрат:
See the Pen Generative Art Demo by shvembldr (@Shvembldr) on CodePen.
Мне понадобился квадрат со сторонами, разбитыми на 30 точек. Я написал функцию square()
, в которой использовал формулу для рисования круга по радиусу, только с четырьмя точками. Если бы точек, например, было 100, эта фигура была бы уже кругом.
Потом, используя эти вершины, вычислил 30 точек между ними, используя функцию lerp()
, которая возвращает расстояние между двумя точками в соотношении к третьей переменной.
А дальше я прошёлся по массиву из получившихся точек и создал фигуру между каждой точкой, центром квадрата и соседней точкой. И покрасил чётные в один цвет, а нечётные — в другой.
У нас есть основа нашей фигуры. Давайте посмотрим на рисунок. Внутри квадрата расположена равносторонняя сетка, похожая на шахматное поле.
Попробуем её реализовать:
See the Pen Generative Art Demo by shvembldr (@Shvembldr) on CodePen.
Я написал два цикла, чтобы показать каким образом можно построить сетку. В нашем случае сетка с равными сторонами ячеек и её сторона состоит из 7 квадратов, как в той версии рисунка, который мы хотим повторить. Но её легко модифицировать и задать любой размер и параметры.
На своём рисунке Маноло Гамбоа использует два вида квадратов. Давайте попробуем реализовать каждый из них.
See the Pen Generative Art Demo by shvembldr (@Shvembldr) on CodePen.
Первый тип квадратов состоит из двух треугольников, один из которых залит градиентом.
Так как p5.js не имеет функции для заливки градиентом, пришлось написать её подобие через доступ к getDrawingContext()
.
Помимо двух треугольников также есть большой внешний круг, внутренний круг и его «тень», чуть сдвинутая вниз и влево, и две пересекающиеся линии.
Второй тип — основной квадрат, внутренний, его тень, и самый маленький посередине.
Выглядит не очень, поэтому самое время подобрать цвета. У меня нет цели полностью скопировать работу Маноло. Так что палитру выберу сам и постараюсь сделать так, чтобы вы и сами смогли поменять её по своему вкусу.
See the Pen Generative Art Demo by shvembldr (@Shvembldr) on CodePen.
Для веб-разработчика удобно пользоваться hex-цветами, но для градиентов и прозрачности нужен rgba. Я сделал преобразование и заполнил все фигуры соответствующими заливками, используя функции lodash
для рандомизации. Уже немного похоже, но мы ещё используем все детали в каждом элементе.
Пришло время добавить случайности и в структуру!
See the Pen Generative Art Demo by shvembldr (@Shvembldr) on CodePen.
Уже очень похоже на оригинал. Естественно, Маноло более тщательно подходил к выбору цветов, углам градиентов и тому, где и какая вероятность возможна. Но моя цель всего лишь показать, каким образом реализуются подобные вещи.
Наш центральный элемент готов, давайте вынесем его в отдельную функцию и завершим построение паттерна.
See the Pen Generative Art Demo by shvembldr (@Shvembldr) on CodePen.
Итак, я построил глобальную сетку, повернул всё на 45 градусов и расположил наш основной элемент в каждую ячейку. Пришлось передать в него заданные цвета для каймы элемента, чтобы получился нужный эффект. Можно развернуть этот пример на весь экран и генерировать новую итерацию, нажимая на кнопку g
.
Ваша очередь
У Маноло ещё меняется размер внутренней сетки при каждой генерации. Вы можете сделать форк моего проекта в CodePen и попробовать реализовать это самостоятельно.
Эта работа не самая сложная с точки зрения техники, но если вы посмотрите на работы известных художников, то заметите, как много разнообразных техник и приёмов. Кстати, помимо владения языком программирования может пригодиться геометрия и алгебра.
Обязательно попробуйте что-нибудь сделать, это очень захватывающе. Многие испытывают дефицит идей в начале пути, и хороший способ это преодолеть — вдохновляться произведениями людей, уже успешных в этой сфере. По хештегу #generativeArt в Инстаграме вы найдёте множество работ.

Кстати, об этом, не забудьте его поставить, когда будете выкладывать свою. И помните: произведением искусства считается то, что считаете таковым вы и ещё один человек. Так что если ваша работа понравилась маме... :)
Больше информации
Если мне удалось вас заинтересовать, то вот ещё небольшой список полезных материалов по теме:
- Coding Train by Daniel Shiffman — канал одного из авторов Processing. Талантливый и весёлый учитель, который изменит ваше представление о преподавании.
- Сборник ссылок для Creative Coding — не убегайте сразу, увидев такое количество, это бесценные знания.
- Openprocessing — место с песочницей, где люди делятся работами в Processing и p5.js.
- курсы Progamming Graphics от Johua Davis — невероятный учитель рассказывает о Creative coding c помощью Processing.