AreaText

В Paper.js класс PointText используется для вывода текста на холсте, однако для работы с текстом, который должен автоматически переноситься и вписываться в заданную область, требуется использование концепции AreaText. AreaText позволяет задавать текст внутри геометрической фигуры и управлять его поведением при изменении размера или формы области.


Основы AreaText

В Paper.js нет встроенного класса AreaText, как в некоторых других графических библиотеках. Реализация AreaText строится на основе сочетания:

  • Path — задает форму области текста.
  • PointText — выводит отдельные строки текста.
  • Логики переноса текста — вычисляет, какие слова помещаются в текущую строку.

Принцип работы такой:

  1. Создается Path, определяющий контур области текста.
  2. Текст разбивается на слова.
  3. Слова последовательно добавляются в текущую строку до тех пор, пока ширина строки не превысит границ области.
  4. Если строка заполнена, создается новая строка, а ее координата Y смещается вниз на размер шрифта.

Определение области текста

var area = new Path.Rectangle({
    point: [50, 50],
    size: [400, 300],
    strokeColor: 'black'
});
  • point — координаты верхнего левого угла.
  • size — ширина и высота прямоугольника.
  • strokeColor — цвет рамки для визуализации области.

Область может быть любой формы, не только прямоугольником. Например, можно использовать Path.Circle или сложный многоугольник для создания текстового облака нестандартной формы.


Создание текстового объекта

Текст создается через PointText, но его позиция рассчитывается динамически:

var content = "Paper.js позволяет создавать AreaText с переносом слов по границам фигуры.";
var fontSize = 18;
var lineHeight = fontSize * 1.2;
var y = area.bounds.top + fontSize;

var words = content.split(' ');
var line = '';

for (var i = 0; i < words.length; i++) {
    var testLine = line + words[i] + ' ';
    var testText = new PointText({
        point: [area.bounds.left + 5, y],
        content: testLine,
        fontSize: fontSize,
        visible: false
    });

    if (testText.bounds.width > area.bounds.width - 10) {
        new PointText({
            point: [area.bounds.left + 5, y],
            content: line,
            fontSize: fontSize
        });
        line = words[i] + ' ';
        y += lineHeight;
    } else {
        line = testLine;
    }
}

if (line.length > 0) {
    new PointText({
        point: [area.bounds.left + 5, y],
        content: line,
        fontSize: fontSize
    });
}

Ключевые моменты:

  • lineHeight определяет межстрочный интервал.
  • area.bounds используется для проверки, помещается ли строка в ширину области.
  • Последняя строка добавляется отдельно, если она осталась после цикла.

Работа с многострочными текстовыми блоками

Для AreaText важно учитывать вертикальные границы области:

if (y + lineHeight > area.bounds.bottom) {
    break; // остановка добавления строк, если достигнут нижний предел области
}

Это предотвращает выход текста за пределы области.


Динамическое обновление текста

Для интерактивных приложений полезно изменять текст на лету. Для этого необходимо удалять старые PointText объекты перед добавлением новых. Например:

function updateAreaText(area, content) {
    project.activeLayer.children.forEach(function(item) {
        if (item instanceof PointText) {
            item.remove();
        }
    });
    createAreaText(area, content); // функция с логикой переноса текста
}

Использование AreaText в произвольных формах

Для нестандартных форм (круги, полигоны) проверка вхождения слова в область выполняется через метод contains:

if (area.contains(new Point(area.bounds.left + widthOffset, y))) {
    // добавляем слово
} else {
    // перенос на следующую строку
}

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


Настройка внешнего вида текста

  • fontSize — размер шрифта.
  • fontFamily — шрифт, например "Arial" или "Courier New".
  • fillColor — цвет текста.
  • justification — выравнивание: left, center, right.
var text = new PointText({
    point: [100, 100],
    content: "Текст в Paper.js",
    fontSize: 20,
    fillColor: 'blue',
    justification: 'center'
});

Выравнивание особенно важно при размещении текста внутри сложных форм, чтобы строки выглядели аккуратно и симметрично.


Оптимизация производительности

Для больших текстовых блоков:

  1. Минимизировать создание скрытых PointText объектов.
  2. Кэшировать размеры слов через measureText или аналогичные методы.
  3. Использовать группы (Group) для управления всеми строками текста.
var group = new Group();
group.addChild(lineText); // добавление всех строк в группу

Группы позволяют легко перемещать, масштабировать или анимировать весь текстовый блок.


Анимация текста внутри области

Используя Paper.js, можно анимировать текстовые строки внутри заданной области. Например, постепенное появление слов:

lineText.opacity = 0;
lineText.onFr ame = function(event) {
    this.opacity += 0.05;
    if (this.opacity >= 1) {
        this.onFr ame = null;
    }
};

Такой подход совместим с динамическим переносом текста и позволяет создавать эффект “печатающегося” текста.


Эти методы создают гибкую и мощную систему AreaText, позволяющую интегрировать текст в любые графические формы Paper.js, с полной поддержкой переноса, выравнивания и анимации.