Экспорт, GIF и публикация
Ты собрал генеративный аватар цыплёнка — теперь научимся вытаскивать его из браузера наружу: картинкой, гифкой и ссылкой, которую можно кинуть друзьям.
saveCanvas() — команда p5.js, которая сохраняет текущий кадр холста в файл-картинку на твоём компьютере.
Зачем вообще что-то экспортировать
Представь: ты полночи крутил числа в мини-проекте с генеративным аватаром CodeChick, поймал идеальный кадр — перья легли красиво, фон мерцает закатом, клюв смотрит ровно туда, куда надо. И вот ты закрываешь вкладку. Всё. Скетч живёт только пока открыт браузер: закрыл — и картинка испарилась, как несохранённая игра без чекпоинта.
Обидно, правда? Ты не можешь поставить такую работу на аватарку в Telegram, не можешь скинуть другу в личку, не можешь выложить в сторис «смотрите, что я закодил». Картинка есть на экране, но её как будто и нет: она нарисована заново каждый кадр и нигде не хранится файлом.
Этот урок — про то, как достать работу из браузера в реальный мир. Мы научимся трём вещам: сохранять кадр картинкой (как скриншот, только чистый, без рамок браузера), записывать короткий GIF (зацикленную анимацию, которую любят мессенджеры и соцсети) и публиковать скетч онлайн по ссылке, чтобы любой человек открыл твоего живого цыплёнка прямо в браузере. К концу урока у тебя на руках будет картинка, гифка и ссылка — полный набор, чтобы показать миру CodeChick.
И ещё одна мысль, ради которой стоит дочитать до конца. Любая твоя работа существует в двух состояниях: пока она только у тебя на экране — это просто упражнение, тренировка для себя. А вот как только ты её сохранил и показал хотя бы одному человеку — она превращается в результат, которым можно гордиться, который добавляют в портфолио, под которым ставят лайки и который репостят. Художники, музыканты, монтажёры — все рано или поздно учатся не только творить, но и публиковать. Для творческого кодера экспорт — это ровно тот мостик между «я что-то наклепал» и «смотрите, что я сделал». Поэтому относись к этому уроку не как к скучной технической добавке, а как к финальному штриху, без которого работа остаётся незаконченной.
Картинка, гифка и ссылка — три разных «сувенира»
Сначала разберёмся, чем эти три способа отличаются, чтобы ты выбирал правильный под задачу. Метафора простая: ты сходил на классный концерт. Можно сделать фотку (один момент, статика), можно записать короткое видео (движение, но файл потяжелее), а можно дать другу ссылку на трансляцию, чтобы он сам всё посмотрел вживую. Вот те же три варианта для скетча.
| Способ | Что получаешь | Когда брать |
| Картинка (PNG) | Один застывший кадр | Аватарка, обложка, постер |
| GIF | Короткая зацикленная анимация | Сторис, стикер, демо движения |
| Публикация (ссылка) | Живой скетч в браузере | Показать интерактив, портфолио |
Картинка — самый лёгкий и универсальный сувенир. GIF показывает движение, но весит больше и обычно короткий — пара секунд. А ссылка — единственный способ передать интерактив: если твой цыплёнок бегает за мышкой, в картинке и гифке этого не покажешь, а по ссылке друг сам подвигает курсор и всё увидит.
Картинка — это фотка момента. GIF — короткое видео без звука. Ссылка — живая трансляция, где зритель сам управляет.
Разбираем на примерах
Пример 1. Сохраняем кадр через saveCanvas()
Самый частый запрос: «хочу просто красивую картинку моего цыплёнка». Для этого есть команда saveCanvas(). Она берёт текущее содержимое холста и кладёт его в файл на компьютере — чисто, без рамок браузера и без курсора, в отличие от обычного скриншота кнопкой Print Screen.
function setup() {
createCanvas(400, 400);
noStroke();
}
function draw() {
background(255, 180, 120); // тёплый закат
fill(255, 221, 51); // жёлтое тело
circle(200, 240, 120);
circle(200, 150, 80); // голова
fill(255, 140, 0);
triangle(200, 150, 230, 165, 200, 175); // клюв
}
function keyPressed() {
if (key === 's') {
saveCanvas('codechick', 'png'); // нажми S — скачается codechick.png
}
}Результат: на экране цыплёнок на закатном фоне. Пока ты ничего не нажимаешь — просто картинка. Как только ты жмёшь клавишу S, браузер скачивает файл codechick.png с ровно этим кадром, без рамок и курсора.
Разберём по строчкам. Рисование тела и головы тебе уже знакомо с первых уроков. Главное здесь — функция keyPressed(): это специальная функция p5.js, которую библиотека вызывает каждый раз, когда ты нажимаешь любую клавишу. Внутри мы проверяем условием if (key === 's'), что нажата именно буква S. Если да — выполняется saveCanvas('codechick', 'png'). Первый аргумент — имя файла (без точки и расширения), второй — формат: 'png' для картинки с прозрачностью или 'jpg' для фотографий.
Почему мы повесили сохранение на клавишу, а не просто написали saveCanvas() внутри draw()? Потому что draw() повторяется десятки раз в секунду — и если сохранять в нём, браузер за секунду попытается скачать тебе полсотни файлов и захлебнётся. Сохранять нужно по событию: один раз, когда ты сам решил. Нажатие клавиши — идеальный момент.
Маленькая, но важная деталь про размер картинки. Файл сохранится ровно в том разрешении, в котором создан холст: createCanvas(400, 400) даст картинку 400 на 400 точек. Для аватарки в мессенджере этого хватит, а вот для постера на стену или обложки альбома 400 пикселей — маловато, картинка будет мыльной при увеличении. Хочешь крупнее и резче — просто задай холст побольше, например createCanvas(1080, 1080) (популярный квадрат для соцсетей), и пересчитай координаты фигур под новый размер. Правило простое: какой холст — такая и картинка, p5.js ничего не дорисовывает за тебя.
И ещё про форматы. 'png' хорош тем, что умеет хранить прозрачность: если у тебя фон не залит, вокруг цыплёнка будет прозрачная область, и его удобно вставлять на любой цвет. 'jpg' прозрачности не умеет и слегка «съедает» резкие края, зато даёт файл поменьше — он создан для фотографий, а не для графики с чёткими линиями. Для рисунков кодом почти всегда бери 'png': цыплёнок останется чётким, а края — ровными.
Пример 2. Сохраняем именно тот кадр, который понравился
Если твой скетч анимированный — цыплёнок прыгает, перья летят — то «тот самый» кадр поймать сложно: пока тянешься к клавише, момент ушёл. Удобный приём — поставить анимацию на паузу, выбрать кадр спокойно, а потом сохранить.
let y = 0;
let paused = false;
function setup() {
createCanvas(400, 400);
noStroke();
}
function draw() {
background(135, 206, 235);
if (!paused) {
y = y + 2; // цыплёнок падает вниз
if (y > 300) y = 0; // и снова прыгает наверх
}
fill(255, 221, 51);
circle(200, y, 80); // тело движется по Y
}
function keyPressed() {
if (key === ' ') {
paused = !paused; // пробел — пауза/продолжить
}
if (key === 's') {
saveCanvas('codechick-frame', 'png');
}
}Результат: цыплёнок падает сверху вниз и перепрыгивает обратно наверх по кругу. Нажимаешь пробел — движение замирает на текущем кадре. Спокойно жмёшь S — скачивается codechick-frame.png с той позицией, которую ты выбрал. Ещё раз пробел — анимация снова поехала.
Тут работает переменная состояния paused: она хранит между кадрами, стоим мы на паузе или нет. Строка paused = !paused — это переключатель: знак ! означает «наоборот», поэтому каждое нажатие пробела меняет true на false и обратно, как кнопка света. Пока paused равно true, условие if (!paused) не выполняется, и координата y не меняется — кадр застывает. Очень удобно для охоты за идеальным моментом.
Заметь тонкость: на паузе мы перестаём двигать цыплёнка, но draw() всё равно крутится и продолжает перерисовывать кадр — просто с одними и теми же числами. Поэтому холст не гаснет и не зависает, картинка остаётся живой, ты её спокойно рассматриваешь. Это другой подход, чем команда noLoop(), которая вообще останавливает draw(): с ней холст замораживается жёстко, и потом сложнее снова всё запустить. Для нашей задачи «замри — сохрани — поехали дальше» переключатель-флаг гибче и понятнее. Кстати, на пробел мы повесили паузу не случайно: в плеерах и играх пробел почти всегда значит «пауза/продолжить», так что твой скетч сразу ощущается привычно.
Пример 3. Записываем короткий GIF
Картинка — это здорово, но движение цыплёнка хочется показать в движении. Тут выручает GIF — зацикленная анимация без звука, родной формат мемов и стикеров. В свежих версиях p5.js есть готовая команда saveGif(): ты говоришь, как назвать файл и сколько секунд записывать, а библиотека сама склеит кадры в гифку.
let angle = 0;
function setup() {
createCanvas(400, 400);
noStroke();
}
function draw() {
background(135, 206, 235);
fill(255, 221, 51);
push();
translate(200, 200); // центр холста
rotate(angle); // вращаем систему координат
circle(0, 60, 40); // цыплёнок кружит вокруг центра
pop();
angle = angle + 0.05; // каждый кадр чуть-чуть поворачиваем
}
function keyPressed() {
if (key === 'g') {
saveGif('codechick-loop', 3); // нажми G — запишется 3 секунды GIF
}
}Результат: жёлтый цыплёнок по кругу облетает центр холста на голубом фоне. Когда ты нажимаешь клавишу G, p5.js пару секунд молча записывает анимацию, а затем скачивает файл codechick-loop.gif — зацикленную гифку, где цыплёнок бесконечно нарезает круги.
Разберём ключевое. saveGif('codechick-loop', 3) принимает имя файла и длительность в секундах — здесь 3. Записывать стоит коротко: гифка на 10 секунд весит очень много и грузится медленно, а зацикленные 2–4 секунды выглядят аккуратно и легко расходятся по мессенджерам. Чтобы петля смотрелась бесшовно, движение лучше делать таким, чтобы конец совпадал с началом — например, полный оборот по кругу, как здесь с rotate.
Обрати внимание на пару push() / pop() вокруг трансформаций: push() запоминает систему координат, мы её сдвигаем и крутим, рисуем цыплёнка, а pop() возвращает всё обратно — чтобы поворот не накапливался на других фигурах. Это та самая защита настроек, которую ты проходил в уроке про трансформации.
Пара слов о том, что происходит «под капотом» при записи. Команда saveGif() не снимает экран в реальном времени, как видеозапись игры. Она работает умнее: на несколько секунд берёт управление и быстро прогоняет твой draw() кадр за кадром, складывая каждый кадр в стопку, а потом склеивает их в один зацикленный файл. Поэтому во время записи скетч может на мгновение «задуматься» и не реагировать на мышь — это нормально, библиотека просто занята сборкой гифки. Дождись, пока файл скачается, и всё снова оживёт.
Если в твоей версии p5.js команды saveGif() вдруг не оказалось (в совсем старых сборках её ещё не было), не расстраивайся: GIF всегда можно записать и сторонними способами — например, бесплатным экранным рекордером, который снимает кусочек экрана в гифку. Но если редактор свежий, проще и чище всё-таки родная saveGif(): она снимает именно холст, без лишних краёв и в точном размере.
Пример 4. Публикуем скетч в онлайн-редакторе
Картинку и гифку ты уже умеешь скачивать. Но самый эффектный способ поделиться интерактивным цыплёнком — дать ссылку на живой скетч. Тут код почти не нужен: публикация делается не командой, а через сервис. Самый простой — официальный p5.js Web Editor (editor.p5js.org), где ты, скорее всего, и писал свои скетчи.
Порядок такой:
- Зайди в аккаунт на editor.p5js.org (регистрация бесплатная, можно через почту).
- Открой свой скетч и нажми Save — скетч сохранится в облаке, привязанный к твоему аккаунту.
- Нажми кнопку Share. Редактор даст три ссылки: Present (только картинка-результат на весь экран), Edit (открыть с кодом) и Embed (вставить на сайт).
- Скопируй ссылку Present и кидай другу — он откроет твоего живого цыплёнка прямо в браузере, ничего не устанавливая.
Почему это лучше скриншота для интерактивных работ? Потому что по ссылке скетч реально исполняется на устройстве зрителя: если цыплёнок реагирует на мышь или клавиши, друг сам это почувствует. Картинка такого не передаст. А ещё Present-ссылка прячет код и показывает только результат на весь экран — выглядит как готовое приложение, а не как «домашка».
Кроме официального редактора есть и другие площадки: OpenProcessing (галерея творческого кода, где работы лайкают и форкают, как посты), CodePen (универсальная песочница для веб-кода) и GitHub Pages (если хочешь выложить как настоящую страницу со своим адресом). Для старта хватает p5.js Web Editor — остальное освоишь, когда захочешь собрать портфолио.
Зачем вообще нужна ссылка Embed, которую мы пока отложили? Она пригодится, когда у тебя появится свой сайт, блог или страница в школьном проекте: Embed позволяет вставить живой скетч прямо в чужую страницу, как вставляют ролик с видеохостинга. Посетитель твоего сайта увидит работающего цыплёнка, не уходя никуда. Для подростка это звучит далеко, но запомни, что такая возможность есть — однажды захочется собрать портфолио на собственной страничке, и тогда Embed окажется ровно тем, что нужно.
И последнее про этикет публикации. Когда выкладываешь работу на площадку вроде OpenProcessing, по-доброму подписать её: дать название, пару слов, что это и как с ней взаимодействовать («двигай мышкой», «нажми пробел»). Зрителю гораздо приятнее, когда понятно, что перед ним и что можно потрогать. А если ты вдохновлялся чьим-то чужим скетчем или взял кусок кода из примера — упомяни автора. В сообществе творческого кода так принято, и это та мелочь, которая отличает уважительного автора от того, кто просто копипастит.
Частые ошибки и подводные камни
На экспорте новички спотыкаются почти одинаково. Пробеги глазами заранее — сбережёшь нервы.
- Вызывать saveCanvas() прямо в draw(). Поскольку
draw()крутится десятки раз в секунду, браузер попытается скачать тебе лавину файлов и подвиснет. Всегда вешай сохранение на событие — нажатие клавиши вkeyPressed()или клик мыши. - Делать слишком длинный GIF. Гифка на 8–10 секунд весит десятки мегабайт, медленно записывается и тормозит при отправке. Держись 2–4 секунд и зацикливай движение, чтобы конец совпадал с началом.
- Путать скриншот и saveCanvas. Кнопка Print Screen снимает весь экран с рамками браузера и курсором.
saveCanvas()сохраняет только чистый холст в точном разрешении — для аватарки и постера это намного лучше. - Делиться ссылкой Edit вместо Present для готовой работы. Ссылка Edit открывает код и редактор — друг увидит «кухню», а не результат. Для показа бери Present: чистый скетч на весь экран.
- Забыть нажать Save перед Share. Если скетч не сохранён в облаке, ссылка либо не появится, либо будет вести на пустой проект. Сначала Save, потом Share — порядок важен.
- Ждать кнопку «Запустить» в наших уроках. Напомним: p5.js работает с холстом в браузере и в учебном раннере не исполняется. Код здесь мы читаем и представляем по описанию, а запускаешь и экспортируешь ты в настоящем редакторе p5.js.
Мини-практика: собери набор «сувениров» CodeChick
Возьми свой генеративный аватар из прошлого урока (или любой скетч с цыплёнком) и доведи его до публикации. Сделай по шагам:
- Добавь в скетч функцию
keyPressed()с сохранением по клавише S черезsaveCanvas('moy-codechick', 'png'). Поймай красивый кадр и скачай картинку. - Если аватар анимированный, добавь паузу на пробел (как в примере 2), застынь на лучшем моменте и сохрани именно его.
- Запиши короткий GIF на 3 секунды через
saveGif('codechick-loop', 3)по клавише G. Постарайся, чтобы движение зацикливалось без рывка. - Сохрани скетч в p5.js Web Editor, нажми Share и скопируй ссылку Present. Отправь её другу или выложи в сторис.
Цель — чтобы у тебя на руках оказались три формата одной работы: картинка, гифка и ссылка. Это и есть мини-портфолио из одного цыплёнка. Попробуй угадать заранее, какой формат друзья оценят больше — а потом проверь на практике.
Итоги
Сегодня ты научился вытаскивать работу из браузера в реальный мир:
- saveCanvas('имя', 'png') сохраняет текущий кадр чистой картинкой — вешай его на нажатие клавиши, а не в
draw(). - Пауза через переменную состояния помогает поймать и сохранить именно тот кадр анимации, который понравился.
- saveGif('имя', секунды) записывает короткую зацикленную анимацию — держи её на 2–4 секунды и делай движение бесшовным.
- Публикация в p5.js Web Editor через Save → Share → ссылку Present даёт живой интерактивный скетч, который друг откроет в браузере без установки.
- Картинка — для статики, GIF — для движения, ссылка — для интерактива. Выбирай сувенир под задачу.
Твой цыплёнок прошёл путь от одинокой точки в первом уроке до генеративного аватара, который теперь можно скачать, зациклить и выложить в сеть. В следующем уроке мы поговорим о том, как собрать из своих скетчей настоящее портфолио и оформить страницу с работами — чтобы CodeChick стал визитной карточкой твоего творческого кода. Бери лучшие кадры с собой.