Холст, пиксели и система координат
Холст — это сетка из пикселей, а каждая точка на нём — пара чисел (x, y); освоишь эту сетку — и сможешь поставить любую часть цыплёнка ровно туда, куда задумал.
Система координат — это способ задавать точку на холсте парой чисел (x, y), где начало (0, 0) находится в левом верхнем углу, x растёт вправо, а y — вниз.
Зачем вообще знать, где у холста ноль
Представь, что ты открыл любимую игру и хочешь поставить персонажа в центр экрана. Ты же не говоришь компьютеру «ну, куда-то посередине, ты понял» — ты называешь точные координаты. В p5.js всё то же самое: чтобы нарисовать глаз цыплёнка, его клюв или зёрнышко рядом с ним, тебе нужно сказать ровно одно — в какой точке холста это будет. А точка задаётся двумя числами.
В прошлом уроке про setup() и draw() ты уже создал свой первый скетч и заставил его рисовать кадр за кадром. Но фигуры там появлялись как будто «сами собой» — мы не особо думали, почему круг оказался именно тут, а не там. Сегодня мы наведём порядок: ты поймёшь, по каким правилам p5.js расставляет всё на холсте, и научишься управлять этим до пикселя.
Вот к чему мы придём в конце урока — к аккуратно собранной мордочке цыплёнка, где каждая деталь стоит на своём месте не случайно, а потому что ты сам назначил ей координаты:
function setup() {
createCanvas(400, 400);
}
function draw() {
background(135, 206, 235); // небо
// тело
circle(200, 220, 160);
// голова
circle(200, 130, 110);
// глаза
circle(175, 115, 14);
circle(225, 115, 14);
// клюв
triangle(200, 130, 230, 145, 200, 160);
}Результат: на голубом небе — цыплёнок из двух кругов (тело внизу, голова сверху), с двумя маленькими глазками и треугольным клювом по центру. Всё симметрично и собрано, потому что мы заранее посчитали координаты.
Холст — это сетка из пикселей
Открой телефон и поднеси его к глазам очень близко. Если экран хороший, ты ничего не разглядишь, а если присмотреться к старому монитору или увеличить картинку в редакторе — увидишь, что изображение состоит из крошечных квадратиков. Каждый такой квадратик — это пиксель (от английского picture element, «элемент картинки»). Любая фотография, мем или кадр из игры — это просто сетка пикселей, каждый из которых светится своим цветом.
Холст (canvas) — это прямоугольная область на странице, внутри которой p5.js рисует всё изображение. По сути это лист в клетку, только клетки — это пиксели.
Когда ты пишешь createCanvas(400, 400), ты говоришь p5.js: «Дай мне лист шириной 400 пикселей и высотой 400 пикселей». Получается сетка 400 на 400 — это 160 000 маленьких квадратиков, каждым из которых ты можешь управлять. Звучит как много, но не пугайся: чаще всего ты рисуешь не по одному пикселю, а целыми фигурами — кругами, линиями, прямоугольниками — и p5.js сам закрашивает нужные пиксели за тебя.
Чем холст похож на тетрадь в клетку
Вспомни обычную тетрадь в клетку. Когда на уроке геометрии ты строил точку, ты отсчитывал клетки: столько-то вправо, столько-то вниз. Холст в p5.js работает точно так же, с одним важным отличием от того, что вы рисовали на математике.
Единственное, что стоит держать в голове: на холсте нет «полуклеток». Координата — это число пикселей (p5.js терпит и дробные, просто отрисовывает их с округлением). Поэтому, когда ты пишешь 200, это буквально «двухсотый пиксель по горизонтали», а не абстрактная точка где-то посередине. Очень удобно: ты всегда можешь точно сказать, где стоит каждая деталь, и измерить расстояние между ними обычным вычитанием — прямо как считал клетки между двумя точками в тетради.
Где находится начало координат
На уроках математики ты привык, что начало координат — где-то в центре, ось x идёт вправо, ось y — вверх. В p5.js (и почти во всей компьютерной графике) всё иначе, и это первое, что сбивает новичков с толку.
Начало координат — точка
(0, 0)— находится в левом верхнем углу холста. Ось x растёт вправо, а ось y растёт вниз.
Почему вниз, а не вверх? Это идёт ещё от старых экранов, которые рисовали картинку сверху вниз, строчка за строчкой — как ты читаешь текст на этой странице: слева направо, сверху вниз. Компьютер «читает» экран так же, поэтому считать пиксели удобнее именно от левого верхнего угла.
Запомни главное правило одной фразой: чем больше y, тем ниже точка на экране. Если хочешь опустить зёрнышко ниже к земле — увеличивай y. Если хочешь поднять цыплёнка к верхушке холста — уменьшай y вплоть до нуля.
| Точка (x, y) | Где окажется на холсте 400×400 |
| (0, 0) | Самый левый верхний угол |
| (400, 0) | Правый верхний угол |
| (0, 400) | Левый нижний угол |
| (400, 400) | Правый нижний угол |
| (200, 200) | Ровно центр холста |
Маленькая хитрость: центр холста — это всегда половина ширины и половина высоты. Для холста 400×400 центр в точке (200, 200). Это пригодится постоянно, когда захочешь поставить цыплёнка ровно посередине.
Разбираем на примерах
Пример 1. Одна точка на холсте
Начнём с самого маленького — поставим одну-единственную точку. Это будущий «зародыш» нашего цыплёнка, та самая точка из первого модуля.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(245); // светло-серый фон
strokeWeight(10); // толщина точки — 10 пикселей
point(200, 200); // точка в центре
}Результат: на светло-сером фоне ровно по центру холста — одна жирная чёрная точка. Если поменять point(200, 200) на point(50, 50), точка переедет ближе к левому верхнему углу.
Разберём по шагам:
createCanvas(400, 400)— создаём холст-сетку 400 на 400 пикселей.background(245)— заливаем весь холст светло-серым, чтобы точку было видно.strokeWeight(10)— говорим, что линии и точки будут толщиной 10 пикселей (иначе точка была бы крохотной, в один пиксель).point(200, 200)— рисуем точку в координатах x = 200, y = 200, то есть в центре.
Поиграй: подставь разные числа и попробуй мысленно предсказать, куда уедет точка, прежде чем посмотришь результат. Это лучший способ «почувствовать» сетку.
Пример 2. Голова и тело из двух кругов
Теперь соберём из точек что-то осмысленное. Функция circle(x, y, диаметр) рисует круг с центром в точке (x, y). Третий аргумент — это диаметр, то есть ширина круга в пикселях.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(245);
circle(200, 230, 160); // тело: центр чуть ниже середины
circle(200, 130, 110); // голова: центр выше тела
}Результат: на сером фоне — два круга, поставленные друг на друга столбиком: большой внизу (тело) и поменьше сверху (голова). Похоже на снеговика или на заготовку цыплёнка.
Обрати внимание на главное: у обоих кругов x одинаковый — 200. Поэтому они стоят строго друг под другом, по одной вертикали. А вот y разный: у тела 230 (ниже), у головы 130 (выше). Помнишь правило? Меньше y — выше на экране. Голова с y = 130 оказывается над телом с y = 230. Если бы ты случайно поставил голове y = 330, она бы уехала под тело — и цыплёнок встал бы на голову.
Пример 3. Добавляем глаза и клюв
Цыплёнку нужно лицо. Глаза — два маленьких круга, клюв — треугольник. Функция triangle(x1, y1, x2, y2, x3, y3) соединяет три точки и закрашивает фигуру между ними — то есть тебе нужно задать координаты всех трёх углов.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(245);
circle(200, 230, 160); // тело
circle(200, 130, 110); // голова
circle(180, 120, 16); // левый глаз
circle(220, 120, 16); // правый глаз
triangle(200, 132, 235, 150, 200, 168); // клюв
}Результат: та же пара кругов, но теперь у головы появились два глаза-точки симметрично от центра и небольшой треугольный клюв, торчащий вправо. Мордочка ожила.
Смотри, как работает симметрия. Центр головы — x = 200. Левый глаз стоит на x = 180 (на 20 пикселей левее центра), правый — на x = 220 (на те же 20 пикселей правее). Одинаковое смещение в обе стороны — и глаза смотрятся ровно. Это приём, который ты будешь использовать постоянно: чтобы что-то выглядело симметрично, отсчитывай равные расстояния влево и вправо от центральной линии.
Пример 4. Зерно на земле
Дадим цыплёнку, что поклевать. Положим зёрнышко внизу холста — а заодно убедимся, что мы поняли правило про большой y.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(245);
// земля внизу
fill(120, 200, 120);
rect(0, 360, 400, 40);
// зёрнышко на земле
fill(210, 160, 60);
ellipse(120, 350, 18, 12);
}Результат: снизу холста — зелёная полоса земли во всю ширину, а на ней — маленький овальный жёлто-коричневый зёрнышко слева. Земля прижата к нижнему краю, потому что её y = 360 — почти максимум для холста высотой 400.
Здесь два новых момента. Во-первых, rect(x, y, ширина, высота) рисует прямоугольник, но его точка (x, y) — это левый верхний угол, а не центр (в отличие от круга). Поэтому rect(0, 360, 400, 40) начинается у левого края (x = 0), от высоты 360 и тянется на 400 в ширину и 40 в высоту — ровно до нижнего края. Во-вторых, ellipse(x, y, ширина, высота) — это растянутый круг, у которого ширину и высоту задаёшь отдельно; центр у него, как у круга, в точке (x, y).
Частые ошибки и подводные камни
На этих граблях спотыкаются почти все новички. Прочитай заранее — сэкономишь себе час нервов.
- Путать x и y местами. Координаты всегда идут в порядке «сначала по горизонтали, потом по вертикали»:
circle(x, y, d). Если написатьcircle(50, 300, 40)вместоcircle(300, 50, 40), круг окажется совсем не там, где ты думал. Запомни как адрес: сначала «улица» (x — вправо), потом «этаж» (y — вниз). - Думать, что y растёт вверх. Самая частая ловушка после математики. Ты хочешь поднять фигуру выше — и увеличиваешь y, а она едет вниз. Повторяй мантру: больше y — ниже на экране.
- Рисовать за пределами холста. Если у тебя холст 400×400, а ты ставишь
circle(700, 700, 50), круг просто не появится — он целиком за краем. p5.js не ругается и не выдаёт ошибку, фигура молча исчезает. Если что-то «не рисуется», первым делом проверь, не уехали ли координаты за размер холста. - Забывать, что у прямоугольника точка — это угол, а у круга — центр.
rect(0, 0, 100, 100)прижмётся к левому верхнему углу, аcircle(0, 0, 100)покажет только свою правую нижнюю четвертинку, потому что его центр в самом углу, а остальное ушло за край. Это разное поведение, и о нём легко забыть. - Считать, что третий аргумент круга — это радиус. В
circle(x, y, d)третье число — это диаметр (вся ширина), а не радиус (половина). Если хотел круг шириной 80, пиши 80, а не 40.
Мини-проект: расставь цыплёнка сам
Пора применить всё на практике. Возьми за основу пример с головой и телом и доработай его сам — без подсказок, как настоящий автор скетча. Вот техзадание:
- Создай холст 500×500 (не 400 — придётся пересчитать центр самому: чему теперь равна середина?).
- Залей фон голубым небом через
background(135, 206, 235). - Поставь тело и голову цыплёнка точно по центру холста по горизонтали.
- Добавь два симметричных глаза и треугольный клюв.
- Положи внизу холста зелёную полосу земли и хотя бы два зёрнышка в разных местах.
- Бонус: подними цыплёнка чуть выше центра, чтобы он «стоял» на земле, а не висел в воздухе.
Подсказка по центру: для холста 500×500 середина по горизонтали — это 250. Значит, у тела, головы и клюва x должен крутиться вокруг 250, а глаза — симметрично слева и справа от него (например, 230 и 270). Не бойся подбирать числа методом «поменял — посмотрел»: именно так работают и настоящие художники-кодеры.
Если хочешь усложнить — добавь цыплёнку второе зёрнышко повыше, как будто оно ещё падает, и подумай, какой y сделает его «выше» в воздухе. Это и есть тот самый эксперимент, ради которого мы тут собрались.
Итоги
Сегодня ты разобрался с фундаментом, на котором держится вообще всё рисование в p5.js:
- Холст — это сетка из пикселей;
createCanvas(ширина, высота)задаёт её размер. - Начало координат
(0, 0)— в левом верхнем углу; x растёт вправо, y растёт вниз. - Любая точка задаётся парой чисел (x, y), и от этой пары зависит, куда попадёт фигура.
- У круга и эллипса точка (x, y) — это центр, а у прямоугольника — левый верхний угол.
- Симметрию делают через равные смещения влево и вправо от центральной линии.
Теперь твой цыплёнок — это не случайные кружочки, а аккуратно расставленные по координатам детали. В следующем уроке мы вдохнём в него цвет: научимся задавать заливку и обводку, разберёмся с моделями RGB и прозрачностью — и наш герой наконец-то станет жёлтым, с оранжевым клювом, как настоящий цыплёнок. А пока — поэкспериментируй с координатами из мини-проекта: чем больше ты «поломаешь» и подвигаешь, тем крепче ляжет в голову эта сетка.