JavaScript редактор текста для SVG

от автора

Рис 1. Текстовый редактор SVG с поддержкой выделения, копирования, вставки. Работает на пк и мобильных.
Рис 1. Текстовый редактор SVG с поддержкой выделения, копирования, вставки. Работает на пк и мобильных.

Demo | GitHub

<< предыдущая статья

Статья про редактор текста как на рисунке. Исходный код прилагается.

Многострочный текст в SVG

В SVG нет символа переноса строки. Для многострочного текста в SVG используется <tspan>.

Рис 2. Многострочный текст, третья строка пустая
Рис 2. Многострочный текст, третья строка пустая
<text x="0" y="0">     <tspan x="0" y="0">Line 1</tspan>     <tspan x="0" y="20px">Line 2</tspan>     <!-- Line 3 is empty     <tspan x="0" y="40px"></tspan> -->     <tspan x="0" y="60px">Line 4</tspan> </text>

Листинг 1. Многострочный текст в SVG. Третья строка пустая. Высота строки 20px.

Положение элементов <tspan> задается относительно верхнего края <text>. Значение атрибута ‘y’ надо рассчитывать.

Расчетов атрибута ‘y’ можно избежать. Листинг 2 дает тот же результат. Используется атрибут ‘dy’ с фиксированным значением. ‘dy’ указывает положение относительно предыдущего элемента.

<text x="0" y="0">     <tspan x="0" dy="0">Line 1</tspan>     <tspan x="0" dy="20px">Line 2</tspan>     <tspan x="0" dy="20px" visibility="hidden">.</tspan>     <tspan x="0" dy="20px">Line 4</tspan> </text>

Листинг 2. Многострочный текст в SVG. Третья строка пустая. Высота строки 20px. Отступ задается относительно предыдущего элемента.

Формируем многострочную разметку на JavaScript

Функция ниже делает разметку с фиксированным атрибутом ‘dy’. Разметка получается как в листинге 2.

/**  * create multiline tspan markup  * @param {string} str  * @param {number} lineHeight  * @returns {string}  */ function svgStrToTspan(str, lineHeight) {     return str.split('\n').map((t, i) => {         return `<tspan             x="0"             dy="${i === 0 ? '0' : `${lineHeight}px`}"             ${t.length === 0 ? 'visibility="hidden"' : ''}>                   ${t.length === 0                     ? '.'                     : escapeHtml(t).replaceAll(' ', '&nbsp;')}               </tspan>`;     }).join(''); }

Листинг 3. Функция делает многострочную разметку

На рисунке 1 при добавлении строки текст смещается вверх. Таким образом текст всегда по центру круга. Листинге 4 показывает как это реализовано:

/**  * @param {SVGTextElement} textEl target text element  * @param {string} str  * @param {{lineHeight:number, verticalMiddle?:number}} param  * @returns {void}  */ export function svgTextDraw(textEl, str, param) {     textEl.innerHTML = svgStrToTspan(str, param.lineHeight);     if (param.verticalMiddle != null) {         textEl.y.baseVal[0].value =             param.verticalMiddle - textEl.getBBox().height / 2;     } }

Листинг 4. Функция вставляет текст в SVG. При указании verticalMiddle текст центрируется по вертикали.

Редактор текста

Редактор должен поддерживать все стандартные возможности:

  • навигацию по тексту, выделение, вставку, копирование;

  • автозамену, проверку правописания;

  • работать на пк и мобильных.

Для стандартных возможностей есть стандартная <textarea>.

Алгоритм работы редактора:

  • Прозрачная <textarea> располагается над текстом.
    Шрифт <textarea> тоже прозрачный;

  • При вводе вызывается svgTextDraw из листинга 4;

  • Размеры и положение <textarea> пересчитываются.

Алгоритм реализован в функции textareaCreate. Код функции в отдельном файле на GitHub.

Редактор можно сделать для любого элемента <text>:

const textEditor = textareaCreate(     // {SVGTextElement}     textEl,     // text params     { lineHeight: 20, verticalMiddle: 10 },     // init value     'init text',     // onchange     val => {...},     // onblur     val => {...}); … // delete textarea textEditor.remove();

Листинг 5. Создание редактора текста для <text>

Другие статьи про dgrm.net

Как поддержать проект

  • Начните использовать редактор блок схем Dgrm.net.
    Расскажите что думаете. Любым способом: комментарии, личные сообщения, на GitHub.
    Все читаю, веду список предложений.

  • Расскажите знакомым.

  • Ставьте звездочки на GitHub.


ссылка на оригинал статьи https://habr.com/ru/post/662335/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *