Перейти к основному содержимому

P5Js

Скетчи p5.js: генеративное искусство, шейдеры, интерактив, 3D.

Метаданные навыка​

ИсточникВстроенный (установлен по умолчанию)
Путьskills/creative/p5js
Версия1.0.0
Платформыlinux, macos, windows
Тегиcreative-coding, generative-art, p5js, canvas, interactive, visualization, webgl, shaders, animation
Связанные навыкиascii-video, manim-video, excalidraw

Справочник: полный SKILL.md​

к сведению

Ниже приведено полное описание навыка, которое VibeOS загружает при его активации. Агент видит эти инструкции, когда навык активен.

Производственный конвейер p5.js

Когда использовать​

Используйте, когда пользователи запрашивают: скетчи p5.js, креативное программирование, генеративное искусство, интерактивные визуализации, анимации на canvas, браузерное визуальное искусство, визуализацию данных, шейдерные эффекты или любой проект на p5.js.

Что внутри​

Производственный конвейер для интерактивного и генеративного визуального искусства с использованием p5.js. Создаёт браузерные скетчи, генеративное искусство, визуализации данных, интерактивные впечатления, 3D-сцены, аудиореактивные визуалы и моушн-графику — экспортируется в HTML, PNG, GIF, MP4 или SVG. Охватывает: 2D/3D-рендеринг, шумовые и частичные системы, поля потоков, шейдеры (GLSL), манипуляции с пикселями, кинетическую типографику, сцены WebGL, анализ аудио, взаимодействие с мышью/клавиатурой и безголовый экспорт в высоком разрешении.

Творческий стандарт​

Это визуальное искусство, отображаемое в браузере. Холст — это среда; алгоритм — это кисть.

Прежде чем написать хотя бы одну строку кода, сформулируйте творческую концепцию. О чём говорит эта работа? Что заставляет зрителя остановить скроллинг? Что отличает её от примера из туториала по коду? Запрос пользователя — это отправная точка; интерпретируйте его с творческой амбицией.

Качество первого рендера — не подлежит обсуждению. Результат должен быть визуально впечатляющим при первой загрузке. Если он выглядит как упражнение из туториала по p5.js, стандартная конфигурация или «сгенерированное ИИ креативное программирование» — это неправильно. Переосмыслите, прежде чем сдавать.

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

Будьте проактивно креативны. Если пользователь просит «систему частиц», выдайте систему частиц с эмерджентным роевым поведением, шлейфами-призраками, смещённым по палитре туманом глубины и дышащим фоновым шумовым полем. Включите как минимум одну визуальную деталь, о которой пользователь не просил, но которую оценит.

Плотно, многослойно, продуманно. Каждый кадр должен вознаграждать внимание. Никогда не используйте плоские белые фоны. Всегда композиционная иерархия. Всегда осмысленный цвет. Всегда микродетали, которые заметны только при близком рассмотрении.

Целостная эстетика важнее количества функций. Все элементы должны служить единому визуальному языку — общая цветовая температура, согласованная толщина линий, гармоничные скорости движения. Скетч с десятью несвязанными эффектами хуже, чем один с тремя, которые сочетаются друг с другом.

Режимы​

РежимВходные данныеРезультатСправочник
Генеративное искусствоСид / параметрыПроцедурная визуальная композиция (статичная или анимированная)references/visual-effects.md
Визуализация данныхНабор данных / APIИнтерактивные диаграммы, графики, пользовательские отображения данныхreferences/interaction.md
Интерактивный опытНет (управляет пользователь)Скетч, управляемый мышью/клавиатурой/сенсоромreferences/interaction.md
Анимация / моушн-графикаТаймлайн / раскадровкаВременные последовательности, кинетическая типографика, переходыreferences/animation.md
3D-сценаОписание концепцииГеометрия WebGL, освещение, камера, материалыreferences/webgl-and-3d.md
Обработка изображенийФайл(ы) изображенийМанипуляции с пикселями, фильтры, мозаика, пуантилизмreferences/visual-effects.md § Манипуляции с пикселями
АудиореактивныйАудиофайл / микрофонГенеративные визуалы, управляемые звукомreferences/interaction.md § Аудиовход

Стек​

Один самодостаточный HTML-файл на проект. Этап сборки не требуется.

СлойИнструментНазначение
Ядроp5.js 1.11.3 (CDN)Рендеринг canvas, математика, трансформации, обработка событий
3DРежим WebGL p5.js3D-геометрия, камера, освещение, шейдеры GLSL
Аудиоp5.sound.js (CDN)FFT-анализ, амплитуда, вход с микрофона, осцилляторы
ЭкспортВстроенные saveCanvas() / saveGif() / saveFrames()Вывод PNG, GIF, последовательности кадров
ЗахватCCapture.js (опционально)Детерминированный захват видео с фиксированной частотой кадров (WebM, GIF)
БезголовыйPuppeteer + Node.js (опционально)Автоматизированный рендеринг в высоком разрешении, MP4 через ffmpeg
SVGp5.js-svg 1.6.0 (опционально)Векторный вывод для печати — требует p5.js 1.x
Натуральные медиаp5.brush (опционально)Акварель, уголь, перо — требует p5.js 2.x + WEBGL
Текстураp5.grain (опционально)Зернистость плёнки, текстурные наложения
ШрифтыGoogle Fonts / loadFont()Пользовательская типографика через OTF/TTF/WOFF2

Примечание о версиях​

p5.js 1.x (1.11.3) используется по умолчанию — стабильная, хорошо документированная версия с наибольшей совместимостью библиотек. Используйте её, если проект не требует функций 2.x.

p5.js 2.x (2.2+) добавляет: async setup() вместо preload(), цветовые режимы OKLCH/OKLAB, splineVertex(), API .modify() для шейдеров, вариативные шрифты, textToContours(), события указателя. Требуется для p5.brush. См. references/core-api.md § p5.js 2.0.

Конвейер​

Каждый проект проходит один и тот же 6-этапный путь:

КОНЦЕПЦИЯ → ДИЗАЙН → КОД → ПРЕДПРОСМОТР → ЭКСПОРТ → ПРОВЕРКА
  1. КОНЦЕПЦИЯ — Сформулируйте творческое видение: настроение, цветовой мир, словарь движений, что делает это уникальным
  2. ДИЗАЙН — Выберите режим, размер холста, модель взаимодействия, цветовую систему, формат экспорта. Сопоставьте концепцию с техническими решениями
  3. КОД — Напишите один HTML-файл со встроенным p5.js. Структура: глобалы → preload() → setup() → draw() → хелперы → классы → обработчики событий
  4. ПРЕДПРОСМОТР — Откройте в браузере, проверьте визуальное качество. Протестируйте в целевом разрешении. Проверьте производительность
  5. ЭКСПОРТ — Захватите результат: saveCanvas() для PNG, saveGif() для GIF, saveFrames() + ffmpeg для MP4, Puppeteer для безголового пакетного рендеринга
  6. ПРОВЕРКА — Соответствует ли результат концепции? Визуально ли он впечатляет в предполагаемом размере отображения? Вы бы поместили его в рамку?

Творческое направление​

Эстетические измерения​

ИзмерениеВариантыСправочник
Цветовая системаHSB/HSL, RGB, именованные палитры, процедурная гармония, градиентная интерполяцияreferences/color-systems.md
Словарь шумаШум Перлина, симплекс, фрактальный (октавный), варпинг домена, curl-шумreferences/visual-effects.md § Шум
Системы частицФизические, роевые, рисующие шлейфы, управляемые аттракторами, следующие полю потокаreferences/visual-effects.md § Частицы
Язык формГеометрические примитивы, пользовательские вершины, кривые Безье, пути SVGreferences/shapes-and-geometry.md
Стиль движенияСглаженное, пружинное, шумовое, физическая симуляция, lerp-интерполяция, ступенчатоеreferences/animation.md
ТипографикаСистемные шрифты, загруженные OTF, textToPoints() для частичного текста, кинетическаяreferences/typography.md
Шейдерные эффектыФрагментные/вершинные шейдеры GLSL, фильтр-шейдеры, постобработка, петли обратной связиreferences/webgl-and-3d.md § Шейдеры
КомпозицияСетка, радиальная, золотое сечение, правило третей, органический разброс, мозаикаreferences/core-api.md § Композиция
Модель взаимодействияСледование за мышью, спавн по клику, перетаскивание, состояние клавиатуры, управление скроллом, вход с микрофонаreferences/interaction.md
Режимы наложенияBLEND, ADD, MULTIPLY, SCREEN, DIFFERENCE, EXCLUSION, OVERLAYreferences/color-systems.md § Режимы наложения
НаслоениеВнеэкранные буферы createGraphics(), альфа-композитинг, маскированиеreferences/core-api.md § Внеэкранные буферы
ТекстураПоверхность Перлина, стиплинг, штриховка, полутон, сортировка пикселейreferences/visual-effects.md § Генерация текстур

Правила вариации для каждого проекта​

Никогда не используйте стандартные конфигурации. Для каждого проекта:

  • Пользовательская цветовая палитра — никогда не используйте сырое fill(255, 0, 0). Всегда продуманная палитра из 3–7 цветов
  • Пользовательский словарь толщины линий — тонкие акценты (0.5), средняя структура (1–2), жирное выделение (3–5)
  • Обработка фона — никогда не используйте просто background(0) или background(255). Всегда текстурированный, градиентный или многослойный
  • Разнообразие движения — разные скорости для разных элементов. Основные на 1x, второстепенные на 0.3x, фоновые на 0.1x
  • Как минимум один изобретённый элемент — пользовательское поведение частиц, новое применение шума, уникальная реакция на взаимодействие

Проектно-специфичное изобретение​

Для каждого проекта изобретите как минимум одно из:

  • Пользовательская цветовая палитра, соответствующая настроению (не предустановка)
  • Новая комбинация шумовых полей (например, curl-шум + варпинг домена + обратная связь)
  • Уникальное поведение частиц (пользовательские силы, пользовательские шлейфы, пользовательский спавн)
  • Механика взаимодействия, которую пользователь не запрашивал, но которая возвышает работу
  • Композиционный приём, создающий визуальную иерархию

Философия дизайна параметров​

Параметры должны вытекать из алгоритма, а не из универсального меню. Спросите: «Какие свойства этой системы должны быть настраиваемыми?»

Хорошие параметры раскрывают характер алгоритма:

  • Количества — сколько частиц, ветвей, ячеек (контролирует плотность)
  • Масштабы — частота шума, размер элементов, расстояние (контролирует текстуру)
  • Скорости — темп, скорость роста, затухание (контролирует энергию)
  • Пороги — когда поведение меняется? (контролирует драматизм)
  • Соотношения — пропорции, баланс между силами (контролирует гармонию)

Плохие параметры — это универсальные элементы управления, не связанные с алгоритмом:

  • «color1», «color2», «size» — бессмысленны без контекста
  • Тумблеры для несвязанных эффектов
  • Параметры, которые меняют только внешний вид, а не поведение

Каждый параметр должен менять то, как алгоритм думает, а не только то, как он выглядит. Параметр «турбулентность», меняющий октавы шума, — хорош. Ползунок «размер частиц», меняющий только радиус ellipse(), — поверхностен.

Рабочий процесс​

Шаг 1: Творческое видение​

До любого кода сформулируйте:

  • Настроение / атмосфера: Что должен чувствовать зритель? Задумчивость? Энергию? Беспокойство? Игривость?
  • Визуальная история: Что происходит со временем (или при взаимодействии)? Построение? Распад? Трансформация? Колебание?
  • Цветовой мир: Тёплый/холодный? Монохромный? Комплементарный? Какой доминирующий оттенок? Акцент?
  • Язык форм: Органические кривые? Острая геометрия? Точки? Линии? Смешанный?
  • Словарь движений: Медленный дрейф? Взрывной всплеск? Дышащий пульс? Механическая точность?
  • Что делает ЭТО особенным: Что является той самой уникальной чертой этого скетча?

Сопоставьте запрос пользователя с эстетическими выборами. «Расслабляющий генеративный фон» требует совершенно другого подхода, чем «глитч-визуализация данных».

Шаг 2: Технический дизайн​

  • Режим — какой из 7 режимов из таблицы выше
  • Размер холста — альбомный 1920x1080, портретный 1080x1920, квадратный 1080x1080 или адаптивный windowWidth/windowHeight
  • Рендерер — P2D (по умолчанию) или WEBGL (для 3D, шейдеров, продвинутых режимов наложения)
  • Частота кадров — 60fps (интерактивный), 30fps (фоновая анимация) или noLoop() (статический генеративный)
  • Цель экспорта — отображение в браузере, PNG-кадр, GIF-петля, MP4-видео, SVG-вектор
  • Модель взаимодействия — пассивная (без ввода), управляемая мышью, управляемая клавиатурой, аудиореактивная, управляемая скроллом
  • Интерфейс зрителя — для интерактивного генеративного искусства начинайте с templates/viewer.html, который предоставляет навигацию по сидам, ползунки параметров и загрузку. Для простых скетчей или экспорта видео используйте чистый HTML

Шаг 3: Напишите скетч​

Для интерактивного генеративного искусства (исследование сидов, настройка параметров): начинайте с templates/viewer.html. Сначала прочитайте шаблон, сохраните фиксированные секции (навигация по сидам, действия), замените алгоритм и элементы управления параметрами. Это даёт пользователю навигацию по сидам (пред/след/случайный/переход), ползунки параметров с обновлением в реальном времени и загрузку PNG — всё уже настроено.

Для анимаций, экспорта видео или простых скетчей: используйте чистый HTML:

Один HTML-файл. Структура:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Название проекта</title>
<script>p5.disableFriendlyErrors = true;</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.min.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/addons/p5.sound.min.js"></script> -->
<!-- <script src="https://unpkg.com/p5.js-svg@1.6.0"></script> --> <!-- Экспорт SVG -->
<!-- <script src="https://cdn.jsdelivr.net/npm/ccapture.js-npmfixed/build/CCapture.all.min.js"></script> --> <!-- Захват видео -->
<style>
html, body { margin: 0; padding: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script>
// === Конфигурация ===
const CONFIG = {
seed: 42,
// ... параметры, специфичные для проекта
};

// === Цветовая палитра ===
const PALETTE = {
bg: '#0a0a0f',
primary: '#e8d5b7',
// ...
};

// === Глобальное состояние ===
let particles = [];

// === Preload (шрифты, изображения, данные) ===
function preload() {
// font = loadFont('...');
}

// === Setup ===
function setup() {
createCanvas(1920, 1080);
randomSeed(CONFIG.seed);
noiseSeed(CONFIG.seed);
colorMode(HSB, 360, 100, 100, 100);
// Инициализация состояния...
}

// === Цикл Draw ===
function draw() {
// Рендер кадра...
}

// === Вспомогательные функции ===
// ...

// === Классы ===
class Particle {
// ...
}

// === Обработчики событий ===
function mousePressed() { /* ... */ }
function keyPressed() { /* ... */ }
function windowResized() { resizeCanvas(windowWidth, windowHeight); }
</script>
</body>
</html>

Ключевые паттерны реализации:

  • Случайность на основе сида: Всегда используйте randomSeed() + noiseSeed() для воспроизводимости
  • Цветовой режим: Используйте colorMode(HSB, 360, 100, 100, 100) для интуитивного управления цветом
  • Разделение состояния: CONFIG для параметров, PALETTE для цветов, глобалы для изменяемого состояния
  • Сущности на основе классов: Частицы, агенты, фигуры как классы с методами update() + display()
  • Внеэкранные буферы: createGraphics() для многослойной композиции, шлейфов, масок

Шаг 4: Предпросмотр и итерация​

  • Откройте HTML-файл прямо в браузере — сервер не нужен для базовых скетчей
  • Для loadImage()/loadFont() из локальных файлов: используйте scripts/serve.sh или python3 -m http.server
  • Вкладка Performance в Chrome DevTools для проверки 60fps
  • Тестируйте в целевом разрешении экспорта, а не только в размере окна
  • Настраивайте параметры, пока визуал не совпадёт с концепцией из Шага 1

Шаг 5: Экспорт​

ФорматМетодКоманда
PNGsaveCanvas('output', 'png') в keyPressed()Нажмите 's' для сохранения
High-res PNGБезголовый захват Puppeteernode scripts/export-frames.js sketch.html --width 3840 --height 2160 --frames 1
GIFsaveGif('output', 5) — захватывает N секундНажмите 'g' для сохранения
Последовательность кадровsaveFrames('frame', 'png', 10, 30) — 10с при 30fpsЗатем ffmpeg -i frame-%04d.png -c:v libx264 output.mp4
MP4Захват кадров Puppeteer + ffmpegbash scripts/render.sh sketch.html output.mp4 --duration 30 --fps 30
SVGcreateCanvas(w, h, SVG) с p5.js-svgsave('output.svg')

Шаг 6: Проверка качества​

  • Соответствует ли это видению? Сравните результат с творческой концепцией. Если выглядит шаблонно, вернитесь к Шагу 1
  • Проверка разрешения: Чётко ли изображение в целевом размере отображения? Нет ли артефактов алиасинга?
  • Проверка производительности: Держит ли 60fps в браузере? (Минимум 30fps для анимаций)
  • Проверка цвета: Сочетаются ли цвета? Протестируйте на светлых и тёмных мониторах
  • Крайние случаи: Что происходит на краях холста? При изменении размера? После 10 минут работы?

Критические замечания по реализации​

Производительность — сначала отключите FES​

Система дружественных ошибок (FES) добавляет до 10x накладных расходов. Отключайте её в каждом рабочем скетче:

p5.disableFriendlyErrors = true;  // ДО setup()

function setup() {
pixelDensity(1); // предотвращает 2x-4x перерисовку на retina
createCanvas(1920, 1080);
}

В горячих циклах (частицы, пиксельные операции) используйте Math.* вместо обёрток p5 — это заметно быстрее:

// В горячих путях draw() или update():
let a = Math.sin(t); // не sin(t)
let r = Math.sqrt(dx*dx+dy*dy); // не dist() — или лучше: пропустите sqrt, сравнивайте magSq
let v = Math.random(); // не random() — когда сид не нужен
let m = Math.min(a, b); // не min(a, b)

Никогда не используйте console.log() внутри draw(). Никогда не манипулируйте DOM в draw(). См. references/troubleshooting.md § Производительность.

Случайность на основе сида — всегда​

Каждый генеративный скетч должен быть воспроизводим. Тот же сид — тот же результат.

function setup() {
randomSeed(CONFIG.seed);
noiseSeed(CONFIG.seed);
// Все вызовы random() и noise() теперь детерминированы
}

Никогда не используйте Math.random() для генеративного контента — только для критичного по производительности невизуального кода. Всегда используйте random() для визуальных элементов. Если нужен случайный сид: CONFIG.seed = floor(random(99999)).

Поддержка платформ генеративного искусства (fxhash / Art Blocks)​

Для платформ генеративного искусства замените PRNG p5 на детерминированную случайность платформы:

// Соглашение fxhash
const SEED = $fx.hash; // уникально для каждого минта
const rng = $fx.rand; // детерминированный PRNG
$fx.features({ palette: 'warm', complexity: 'high' });

// В setup():
randomSeed(SEED); // для noise() p5
noiseSeed(SEED);

// Замените random() на rng() для детерминизма платформы
let x = rng() * width; // вместо random(width)

См. references/export-pipeline.md § Экспорт на платформы.

Цветовой режим — используйте HSB​

HSB (Оттенок, Насыщенность, Яркость) значительно проще в работе, чем RGB, для генеративного искусства:

colorMode(HSB, 360, 100, 100, 100);
// Теперь: fill(оттенок, насыщенность, яркость, альфа)
// Поворот оттенка: fill((baseHue + offset) % 360, 80, 90)
// Уменьшение насыщенности: fill(оттенок, sat * 0.3, яркость)
// Затемнение: fill(оттенок, sat, яркость * 0.5)

Никогда не хардкодьте сырые значения RGB. Определите объект палитры, процедурно создавайте вариации. См. references/color-systems.md.

Шум — многооктавный, не сырой​

Сырой noise(x, y) выглядит как гладкие пятна. Наслаивайте октавы для естественной текстуры:

function fbm(x, y, octaves = 4) {
let val = 0, amp = 1, freq = 1, sum = 0;
for (let i = 0; i < octaves; i++) {
val += noise(x * freq, y * freq) * amp;
sum += amp;
amp *= 0.5;
freq *= 2;
}
return val / sum;
}

Для текучих органических форм используйте варпинг домена: подавайте выход шума обратно как координаты входа шума. См. references/visual-effects.md.

createGraphics() для слоёв — не опционально​

Плоский однопроходный рендеринг выглядит плоско. Используйте внеэкранные буферы для композиции:

let bgLayer, fgLayer, trailLayer;
function setup() {
createCanvas(1920, 1080);
bgLayer = createGraphics(width, height);
fgLayer = createGraphics(width, height);
trailLayer = createGraphics(width, height);
}
function draw() {
renderBackground(bgLayer);
renderTrails(trailLayer); // постоянный, затухающий
renderForeground(fgLayer); // очищается каждый кадр
image(bgLayer, 0, 0);
image(trailLayer, 0, 0);
image(fgLayer, 0, 0);
}

Производительность — векторизуйте где возможно​

Вызовы отрисовки p5.js дороги. Для тысяч частиц:

// МЕДЛЕННО: отдельные фигуры
for (let p of particles) {
ellipse(p.x, p.y, p.size);
}

// БЫСТРО: одна фигура с beginShape()
beginShape(POINTS);
for (let p of particles) {
vertex(p.x, p.y);
}
endShape();

// САМОЕ БЫСТРОЕ: пиксельный буфер для огромных количеств
loadPixels();
for (let p of particles) {
let idx = 4 * (floor(p.y) * width + floor(p.x));
pixels[idx] = r; pixels[idx+1] = g; pixels[idx+2] = b; pixels[idx+3] = 255;
}
updatePixels();

См. references/troubleshooting.md § Производительность.

Режим экземпляра для нескольких скетчей​

Глобальный режим загрязняет window. Для продакшена используйте режим экземпляра:

const sketch = (p) => {
p.setup = function() {
p.createCanvas(800, 800);
};
p.draw = function() {
p.background(0);
p.ellipse(p.mouseX, p.mouseY, 50);
};
};
new p5(sketch, 'canvas-container');

Требуется при встраивании нескольких скетчей на одну страницу или интеграции с фреймворками.

Особенности режима WebGL​

  • createCanvas(w, h, WEBGL) — начало координат в центре, а не в левом верхнем углу
  • Ось Y инвертирована (положительный Y идёт вверх в WEBGL, вниз в P2D)
  • translate(-width/2, -height/2) для получения координат, подобных P2D
  • push()/pop() вокруг каждой трансформации — стек матриц переполняется молча
  • texture() перед rect()/plane() — не после
  • Пользовательские шейдеры: createShader(vert, frag) — тестируйте в нескольких браузерах

Экспорт — соглашение о горячих клавишах​

Каждый скетч должен включать это в keyPressed():

function keyPressed() {
if (key === 's' || key === 'S') saveCanvas('output', 'png');
if (key === 'g' || key === 'G') saveGif('output', 5);
if (key === 'r' || key === 'R') { randomSeed(millis()); noiseSeed(millis()); }
if (key === ' ') CONFIG.paused = !CONFIG.paused;
}

Безголовый экспорт видео — используйте noLoop()​

Для безголового рендеринга через Puppeteer скетч обязан использовать noLoop() в setup. Без него цикл draw p5 работает свободно, пока скриншоты делаются медленно — скетч убегает вперёд, и вы получаете пропущенные/дублированные кадры.

function setup() {
createCanvas(1920, 1080);
pixelDensity(1);
noLoop(); // скрипт захвата управляет продвижением кадров
window._p5Ready = true; // сигнал готовности скрипту захвата
}

Встроенный scripts/export-frames.js обнаруживает _p5Ready и вызывает redraw() один раз за захват для точного соответствия 1:1. См. references/export-pipeline.md § Детерминированный захват.

Для многосценных видео используйте архитектуру «один клип — один HTML»: один HTML на сцену, рендерите независимо, склеивайте с помощью ffmpeg -f concat. См. references/export-pipeline.md § Архитектура клипов.

Рабочий процесс агента​

При создании скетчей p5.js:

  1. **На