Синхронизировать поле выбора HTML с повернутым элементом SVG (смещение вращения и неправильные границы)Javascript

Форум по Javascript
Ответить
Anonymous
 Синхронизировать поле выбора HTML с повернутым элементом SVG (смещение вращения и неправильные границы)

Сообщение Anonymous »

Я создаю простой редактор SVG (перемещение, изменение размера или поворот с помощью пользовательского центра поворота).

Элемент SVG преобразуется с помощью преобразований SVG, но поле выбора НЕ SVG — это наложение HTML , расположенное поверх SVG.
После поворота элемента SVG:
  • Поле выбора HTML не изменяется правильно следовать за повернутым элементом SVG.
    • Ограничительная рамка смещена.
    • Ручки отображаются в неправильных положениях.
    • Ошибки увеличиваются при повороте на 90 / 180 °.
  • Поворот не выполняется. мышь работает правильно
    • Угол мыши смещается при перетаскивании
    • Кажется, что центр вращения перемещается во время вращения
Перевод работает правильно. Масштабирование работает частично.
Логика поворота (элемент SVG)

Код: Выделить всё

const mouse = pt.matrixTransform(svg.getScreenCTM().inverse());

const wp = pivotPoint.matrixTransform(
selectedElement.getCTM()
);

const currentAngle = Math.atan2(
mouse.y - wp.y,
mouse.x - wp.x
);

const delta = currentAngle - startAngle;

const m = startMatrix
.translate(pivot.x, pivot.y)
.rotate(delta * 180 / Math.PI)
.translate(-pivot.x, -pivot.y);

selectedElement.transform.baseVal.initialize(
svg.createSVGTransformFromMatrix(m)
);
Обновление поля выбора HTML

Код: Выделить всё

const bbox = selectedElement.getBBox();
const ctm = selectedElement.getCTM();

const p1 = svg.createSVGPoint();
p1.x = bbox.x;
p1.y = bbox.y;

const p2 = svg.createSVGPoint();
p2.x = bbox.x + bbox.width;
p2.y = bbox.y + bbox.height;

const t1 = p1.matrixTransform(ctm);
const t2 = p2.matrixTransform(ctm);

const m = selectedElement.transform.baseVal.consolidate()?.matrix;
const angle = m ? Math.atan2(m.b, m.a) * 180 / Math.PI : 0;

// HTML div overlay
selectorDiv.style.transform =
`translate(${Math.min(t1.x, t2.x)}px, ${Math.min(t1.y, t2.y)}px)
rotate(${angle}deg)`;

selectorDiv.style.width  = `${Math.abs(t2.x - t1.x)}px`;
selectorDiv.style.height = `${Math.abs(t2.y - t1.y)}px`;
Структура поля выбора HTML Вопросы
  • Достаточно ли getBBox() + getCTM() при синхронизации наложения HTML с повернутым элементом SVG?
  • Почему вращение смещается, когда к элементу SVG уже применены преобразования?
  • Должны ли математические вычисления вращения выполняться в локальном пространстве SVG или в мировом (экранном) пространстве?
  • Существует ли рекомендуемый подход для полей выбора на основе HTML вместо SVG (используется такими редакторами, как Figma / Illustrator)?
Спасибо, что нашли время разобраться в этом.
Любой указатели, исправления или ссылки на общепринятые подходы приветствуются.
Снимок экрана

Подробнее здесь: https://stackoverflow.com/questions/798 ... orrect-bou
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»