Привет! Меня зовут Илья Борисов, я фронтенд-разработчик в Медузе. Кроме работы, у меня есть хобби, о котором я и хочу немного рассказать. Возможно для вас это станет открытием новой сферы применения языков программирования, в частности, JavaScript.

«Из Инстаграма Shvembldr.»

Возможности программирования

Фронтенд часто ассоциируется только с вёрсткой сайтов и разработкой приложений. Но это только верхушка айсберга под названием «программирование». Это бесконечные возможности для самореализации и выражения идей и мыслей, и невероятный инструмент в руках творческого человека. Я говорю про Generative Art (генеративное искусство) и визуализацию аудио.

Я давно занимаюсь музыкой и всегда интересовался возможностью её визуализации. Так, исследуя это направление, наткнулся на несколько статей про генеративное искусство и увлёкся им. Теперь это моё хобби и возможность самовыражения. Ниже пара примеров, а остальное можно найти в моём Инстаграме:

Generative Art s
hvembldr
«Из Инстаграма Shvembldr.»
Generative Art shvembldr
«Из Инстаграма Shvembldr.»

Если объяснять простыми словами: вы пишете код, генерирующий определённое изображение с помощью придуманных вами же алгоритмов, оставляя при этом некоторую свободу в виде случайных значений.

Таким образом, каждое новое сгенерированное изображение будет уникально и, в то же время, будет сохранять идентичность, которую вы ему задали.

Это направление появилось вместе с возможностью визуализировать код и становится всё популярнее. С развитием генеративного искусства появились инструменты и фреймворки для людей, «программирующих искусство». В том или ином виде они есть практически для всех языков программирования. Для С++ — это Openframeworks, для JAVA — Processing, для Python и JavaScript — его модифицированные версии.

Конечно, не все используют готовые библиотеки, кто-то пишет на нативном коде, а кто-то даже разрабатывает свои инструменты. Я использую p5.js, о нём и пойдёт речь.

Для того чтобы глубже вникнуть в процесс разработки, давайте разберём одну из работ известного артиста в сфере генеративного искусства. Это художник из Аргентины Маноло Гамбоа. В качестве примера я взял одну из его последних и интересных работ, её вариации можно увидеть на странице Behance.

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

Generative Art Manolo Gamboa Naon
«Из публичного профиля на Behance Manolo Gamboa Naon.»

Попробуем сами

Давайте я покажу, как создать похожую работу шаг за шагом.

Начнём с настройки окружения для работы с 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.