LEARN X · ЗА 14 МИН

p5.js

p5.js за 14 минут: setup и draw, холст, фигуры, цвета, координаты, мышь, анимация, текст, random и noise, частицы — творческое кодирование в комментариях.

p5.js — это библиотека JavaScript для творческого кодирования: рисования, анимации и генеративного арта прямо в браузере. Весь тур уместился в комментариях к рабочему коду — читай сверху вниз.

Что такое p5.js

Порт Processing на веб: пишешь простой код — получаешь графику на <canvas>. Идеально для скетчей, визуализаций и арта.

// Комментарии начинаются с двух слэшей
/* или вот так —
   многострочный блок */

// Подключение в HTML:
// <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js"></script>
// <script src="sketch.js"></script>

// p5.js даёт десятки готовых функций: rect, ellipse, fill...
// Их не нужно импортировать — они уже доступны глобально.

Две главные функции: setup и draw

Скетч держится на двух функциях. setup() выполняется один раз, draw() — снова и снова, кадр за кадром.

function setup() {
  // Вызывается ОДИН раз при старте.
  // Здесь создают холст и задают начальные настройки.
  createCanvas(400, 400);
}

function draw() {
  // Вызывается ~60 раз в секунду — это игровой цикл.
  // Всё, что должно двигаться и обновляться, живёт здесь.
  background(220);   // перерисовываем фон каждый кадр
  ellipse(200, 200, 80, 80); // круг в центре
}

Холст

Холст — прямоугольник, на котором всё рисуется. Размеры в пикселях.

function setup() {
  createCanvas(600, 400); // ширина 600, высота 400
  // createCanvas(windowWidth, windowHeight); // на весь экран
}

function draw() {
  background(30);        // тёмно-серый фон (одно число = оттенок серого 0..255)
  // background(255, 0, 0); // или красный через R, G, B
  // background(30, 50);  // второе число — прозрачность (шлейф!)
}

Фигуры

function draw() {
  background(240);

  rect(20, 20, 100, 60);      // прямоугольник: x, y, ширина, высота
  square(150, 20, 60);        // квадрат: x, y, сторона

  ellipse(300, 50, 80, 50);   // эллипс: x, y, ширина, высота
  circle(420, 50, 60);        // круг: x, y, диаметр

  line(20, 150, 200, 200);    // линия: от (x1,y1) к (x2,y2)
  point(250, 180);            // точка: x, y

  triangle(300, 200, 360, 120, 420, 200); // треугольник: 3 вершины
}

Цвета

fill — заливка, stroke — обводка. Действуют на все фигуры ниже по коду, пока не сменишь.

function draw() {
  background(255);

  fill(255, 0, 0);        // заливка: R, G, B (0..255)
  stroke(0, 0, 255);      // цвет обводки
  strokeWeight(4);        // толщина обводки в пикселях
  rect(50, 50, 100, 100);

  noStroke();             // без обводки
  fill(0, 200, 0, 120);   // 4-е число — альфа (прозрачность 0..255)
  ellipse(250, 100, 120, 120);

  noFill();               // только контур, без заливки
  stroke(0);
  circle(400, 100, 100);

  // colorMode(HSB, 360, 100, 100); // переключиться на тон/насыщенность/яркость
  // fill(200, 80, 90);             // удобно для радуг и плавных переходов
}

Система координат

Начало координат (0, 0) — левый верхний угол. X растёт вправо, Y — вниз. translate и rotate двигают саму систему.

function draw() {
  background(240);

  push();              // сохранить текущую систему координат
  translate(200, 200); // перенести начало координат в (200, 200)
  rotate(PI / 4);      // повернуть на 45 градусов (углы в радианах)
  rectMode(CENTER);    // рисовать прямоугольник от центра
  rect(0, 0, 100, 100);// рисуем уже в новой системе
  pop();               // вернуть всё как было

  // angleMode(DEGREES); // если хочешь градусы вместо радиан
}

Переменные кадра

p5.js сам обновляет полезные переменные перед каждым кадром.

function draw() {
  background(240);

  // width и height — размеры холста
  // frameCount — сколько кадров уже отрисовано (0, 1, 2, ...)
  // mouseX, mouseY — текущая позиция курсора
  // pmouseX, pmouseY — позиция курсора в прошлом кадре

  let d = 50 + 30 * sin(frameCount * 0.05); // пульсирующий диаметр
  ellipse(width / 2, height / 2, d, d);

  fill(0);
  text("кадр: " + frameCount, 10, 20); // счётчик кадров
}

Ввод мыши и клавиатуры

function draw() {
  // mouseIsPressed — true, пока зажата кнопка мыши
  if (mouseIsPressed) {
    fill(0);
  } else {
    fill(255);
  }
  ellipse(mouseX, mouseY, 40, 40); // круг следует за курсором
}

function mousePressed() {
  // Срабатывает один раз в момент клика
  console.log("клик в", mouseX, mouseY);
}

function keyPressed() {
  // key — последняя нажатая клавиша (символ)
  // keyCode — код для спецклавиш (UP_ARROW, LEFT_ARROW, ENTER...)
  if (key === " ") background(random(255));
  if (keyCode === LEFT_ARROW) console.log("влево");
}

Движение и анимация

Анимация = переменные, которые меняются между кадрами. Объявляй их снаружи, меняй внутри draw.

let x = 0;      // позиция
let speed = 3;  // скорость

function setup() {
  createCanvas(400, 200);
}

function draw() {
  background(240);
  ellipse(x, 100, 40, 40);

  x = x + speed;            // двигаем каждый кадр
  if (x > width || x < 0) { // достигли края?
    speed = -speed;         // развернуть направление (отскок)
  }
}

Текст

function draw() {
  background(30);

  fill(255);              // цвет текста — это тоже fill
  textSize(32);           // размер шрифта
  textAlign(CENTER, CENTER); // выравнивание по гориз. и верт.
  text("Привет, p5!", width / 2, height / 2); // текст, x, y

  textSize(14);
  textAlign(LEFT, TOP);
  text("подпись слева сверху", 10, 10);
  // textFont("Courier New"); // сменить шрифт
}

Случайность и шум

random даёт резкий разброс, noise (шум Перлина) — плавные, «природные» изменения. Основа генеративного арта.

function draw() {
  // random() — число от 0 до 1
  // random(10) — от 0 до 10
  // random(5, 15) — от 5 до 15
  let r = random(255);
  fill(r, 100, 200);

  // random(массив) — случайный элемент
  let c = random(["red", "green", "blue"]);

  // noise(t) — плавное число 0..1, зависящее от аргумента
  let n = noise(frameCount * 0.01); // меняется мягко, без скачков
  let y = n * height;
  ellipse(width / 2, y, 30, 30); // плавно «дышащее» движение
}

Массивы объектов

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

let particles = []; // массив частиц

function setup() {
  createCanvas(400, 400);
  for (let i = 0; i < 50; i++) {
    // каждая частица — объект со своими свойствами
    particles.push({
      x: random(width),
      y: random(height),
      vx: random(-2, 2), // скорость по X
      vy: random(-2, 2), // скорость по Y
    });
  }
}

function draw() {
  background(20, 40); // полупрозрачный фон даёт шлейфы
  fill(255);
  noStroke();
  for (let p of particles) { // обойти все частицы
    p.x += p.vx;
    p.y += p.vy;
    // завернуть с края на край
    if (p.x > width) p.x = 0;
    if (p.x < 0) p.x = width;
    if (p.y > height) p.y = 0;
    if (p.y < 0) p.y = height;
    ellipse(p.x, p.y, 6, 6);
  }
}

Интерактивный пример: рисовалка

Собираем всё вместе — рисуем мышью, пробел очищает холст.

function setup() {
  createCanvas(600, 400);
  background(20);
}

function draw() {
  // Рисуем, только пока зажата мышь
  if (mouseIsPressed) {
    // цвет зависит от позиции — плавная радуга
    stroke(mouseX % 256, mouseY % 256, 200);
    strokeWeight(8);
    // линия от прошлой позиции курсора к текущей —
    // получается непрерывный штрих
    line(pmouseX, pmouseY, mouseX, mouseY);
  }
}

function keyPressed() {
  if (key === " ") {
    background(20); // пробел — очистить холст
  }
}

// Готово! Открой в браузере и води мышью с зажатой кнопкой.
// Дальше: rotate для спиралей, noise для генеративных пейзажей,
// массивы объектов для систем частиц и игр.
Поддержать проект