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

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

Пример создания многострочного текста с переносами:

var text = new PointText({
    point: [50, 50],
    content: 'Первая строка\nВторая строка\nТретья строка',
    fillColor: 'black',
    fontFamily: 'Arial',
    fontSize: 24,
    justification: 'left'
});

Ключевой момент: символ \n работает как разделитель строк, а свойство justification отвечает за выравнивание текста: 'left', 'center' или 'right'.

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

Каждая строка может иметь свои индивидуальные стили. Для этого Paper.js предоставляет characterStyle, применяемый через отдельные объекты TextItem. Основные параметры:

  • fillColor – цвет текста
  • fontFamily – шрифт
  • fontSize – размер шрифта
  • fontWeight – толщина шрифта (например, 'bold')
  • justification – выравнивание текста

Пример изменения стиля отдельной строки:

var line1 = new PointText(new Point(50, 50));
line1.content = 'Первая строка';
line1.fillColor = 'red';
line1.fontSize = 30;

var line2 = new PointText(new Point(50, 90));
line2.content = 'Вторая строка';
line2.fillColor = 'blue';
line2.fontSize = 24;

Для более сложного текста с разным стилем в одной визуальной области создается группа Group, в которую добавляются все строки как отдельные объекты PointText.

Автоматический перенос текста

Paper.js не поддерживает автоматический перенос текста по ширине канваса. Необходим ручной расчет длины строки и разбиение текста на массив строк:

function wrapText(content, maxWidth, fontSize, fontFamily) {
    var words = content.split(' ');
    var lines = [];
    var line = '';

    words.forEach(function(word) {
        var testLine = line + (line ? ' ' : '') + word;
        var textItem = new PointText({
            content: testLine,
            fontSize: fontSize,
            fontFamily: fontFamily
        });
        if (textItem.bounds.width > maxWidth) {
            lines.push(line);
            line = word;
        } else {
            line = testLine;
        }
        textItem.remove();
    });
    lines.push(line);
    return lines;
}

var lines = wrapText('Очень длинный текст, который нужно перенести', 200, 18, 'Arial');

lines.forEach(function(line, i) {
    new PointText({
        point: [50, 50 + i * 24],
        content: line,
        fontSize: 18,
        fontFamily: 'Arial'
    });
});

Ключевой приём: создание временного объекта PointText для измерения ширины строки и удаление его после проверки.

Использование Raster для текста

Для статического многострочного текста можно предварительно отрисовать его в Canvas через обычный API и затем создать Raster в Paper.js. Это полезно, если требуется применять сложные фильтры или эффекты, недоступные через PointText.

var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.font = '24px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Первая строка', 0, 24);
ctx.fillText('Вторая строка', 0, 50);

var raster = new Raster(canvas);
raster.position = new Point(100, 100);

Такой подход позволяет комбинировать текст с графическими эффектами Paper.js, такими как маски, градиенты или анимация.

Анимация и взаимодействие с многострочным текстом

PointText и Raster объекты могут быть перемещены, анимированы или трансформированы с помощью стандартных методов Paper.js:

  • position – перемещение текста
  • rotate(angle) – поворот
  • scale(factor) – масштабирование

Пример плавного движения многострочного текста:

var text = new PointText(new Point(50, 50));
text.content = 'Анимация\nмногострочного текста';
text.fillColor = 'green';

function onFrame(event) {
    text.position.y += Math.sin(event.time * 2) * 1.5;
}

Каждая строка в многострочном тексте может управляться отдельно для создания эффектов параллакса, рассеивания или появления по буквам.

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

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

var input = 'Начальный текст';
var textItem = new PointText(new Point(50, 50));
textItem.content = input;

view.onKeyD own = function(event) {
    input += event.character || '';
    var lines = input.split('\n');
    textItem.content = lines.join('\n');
};

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