Ellipse

Эллипс — один из базовых примитивов векторной графики, представляющий собой замкнутую кривую, задаваемую двумя осями: горизонтальной и вертикальной. В библиотеке Paper.js эллипсы реализуются как частный случай пути (Path), что позволяет применять к ним весь спектр операций: трансформации, стилизацию, анимацию и логические операции.


Создание эллипса

В Paper.js эллипс создаётся с помощью конструктора Path.Ellipse. Существует несколько способов задания параметров.

1. Через прямоугольную область:

var ellipse = new Path.Ellipse({
    rectangle: new Rectangle(new Point(50, 50), new Size(200, 100)),
    fillColor: 'blue'
});
  • rectangle определяет область, в которую вписывается эллипс
  • ширина и высота прямоугольника задают диаметры по осям

2. Через центр и радиусы:

var ellipse = new Path.Ellipse({
    center: [200, 200],
    radius: [100, 50],
    strokeColor: 'black'
});
  • center — координаты центра
  • radius — массив из двух значений: радиусы по X и Y

Геометрические свойства

Эллипс в Paper.js обладает всеми свойствами пути (Path), но при этом имеет специфические особенности:

  • Полуоси (радиусы) — определяют форму
  • Центр — позиция объекта
  • Bounds — ограничивающий прямоугольник
  • Segments — набор сегментов кривой Безье, аппроксимирующих эллипс

Пример доступа к границам:

console.log(ellipse.bounds);

Стилизация

Эллипсы поддерживают все стандартные стили:

ellipse.fillColor = 'red';
ellipse.strokeColor = 'black';
ellipse.strokeWidth = 5;
ellipse.opacity = 0.5;

Градиенты:

ellipse.fillColor = {
    gradient: {
        stops: ['yellow', 'orange']
    },
    origin: ellipse.bounds.leftCenter,
    destination: ellipse.bounds.rightCenter
};

Трансформации

Эллипс можно масштабировать, вращать и перемещать:

ellipse.scale(1.5);
ellipse.rotate(45);
ellipse.translate(new Point(100, 0));

Особенности:

  • масштабирование влияет на радиусы
  • вращение не меняет параметры radius, но визуально изменяет ориентацию

Работа с сегментами

Хотя эллипс создаётся как примитив, внутри он представлен кривыми Безье.

console.log(ellipse.segments.length);

Каждый сегмент содержит:

  • точку (point)
  • входящий и исходящий векторы (handleIn, handleOut)

Это позволяет:

  • деформировать эллипс
  • создавать произвольные формы

Пример деформации:

ellipse.segments[0].point.x += 20;

Анимация

Эллипсы часто используются в анимации:

function onFrame(event) {
    ellipse.scale(1 + Math.sin(event.time) * 0.01);
}

Другой пример — движение:

function onFrame(event) {
    ellipse.position.x += 1;
}

Логические операции

Эллипсы можно комбинировать с другими фигурами:

var circle = new Path.Circle({
    center: [250, 200],
    radius: 80
});

var result = ellipse.unite(circle);
result.fillColor = 'green';

Доступные операции:

  • unite — объединение
  • intersect — пересечение
  • subtract — вычитание

Клонирование и копирование

var copy = ellipse.clone();
copy.position.x += 150;

Клон наследует:

  • форму
  • стили
  • трансформации

Работа с координатами

Центр эллипса доступен через position:

ellipse.position = new Point(300, 300);

Также можно использовать:

  • bounds.center
  • bounds.topLeft

Преобразование в путь

Эллипс уже является Path, но может быть модифицирован:

ellipse.flatten(10);
  • flatten разбивает кривую на линейные сегменты
  • полезно для экспорта или анализа

Интерактивность

Эллипсы реагируют на события мыши:

ellipse.onCl ick = function(event) {
    this.fillColor = 'random';
};

Другие события:

  • onMouseEnter
  • onMouseLeave
  • onMouseDrag

Производительность

Особенности работы с большим количеством эллипсов:

  • использование Symbol для повторяющихся объектов
  • минимизация количества сегментов
  • избегание частых пересозданий

Пример с символом:

var symbol = new Symbol(ellipse);

for (var i = 0; i < 50; i++) {
    var instance = symbol.place([Math.random() * 500, Math.random() * 500]);
}

Практические применения

Эллипсы широко используются:

  • построение диаграмм (например, круговые и овальные элементы)
  • генерация органических форм
  • интерфейсные элементы (кнопки, индикаторы)
  • анимационные эффекты (пульсации, орбиты)

Взаимодействие с другими объектами

Эллипс можно использовать как маску:

var image = new Raster('image.jpg');
image.clipMask = true;
ellipse.addChild(image);

Или как путь движения:

var point = ellipse.getPointAt(ellipse.length / 2);

Точность и аппроксимация

Эллипсы в Paper.js не являются математически идеальными — они представлены кривыми Безье. Это даёт:

  • высокую визуальную точность
  • возможность редактирования формы

Но важно учитывать:

  • при сильных трансформациях возможны артефакты
  • для вычислений лучше использовать параметры bounds и radius

Управление порядком отрисовки

ellipse.bringToFront();
ellipse.sendToBack();

Это важно при наложении нескольких фигур.


Удаление

ellipse.remove();

Или очистка слоя:

project.activeLayer.removeChildren();

Комбинирование с группами

var group = new Group([ellipse]);
group.rotate(30);

Группы позволяют управлять несколькими объектами как единым целым.


Итерации и генерация

Создание сетки эллипсов:

for (var x = 0; x < 500; x += 60) {
    for (var y = 0; y < 500; y += 60) {
        new Path.Ellipse({
            center: [x, y],
            radius: [20, 10],
            fillColor: 'blue'
        });
    }
}

Работа с длиной пути

var length = ellipse.length;
var point = ellipse.getPointAt(length / 4);

Позволяет:

  • двигать объекты по траектории
  • вычислять позиции

Изменение формы на лету

function onFrame(event) {
    ellipse.scale(1, 1 + Math.sin(event.time) * 0.02);
}

Создаёт эффект “дыхания”.


Итоговая структура эллипса

Эллипс в Paper.js:

  • является Path
  • состоит из сегментов Безье
  • поддерживает все операции над путями
  • легко трансформируется и анимируется

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