Как синхронизировать системы координат Three.js и HTML/SVG (особенно w.r.t. ось y)?

Я совмещаю 3D-контент с Three.js с содержимым HTML и SVG. CSS.This.js выполняет довольно хорошую работу, синхронизируя размещение содержимого HTML и SVG в 3D-мире.

Но системы координат SVG/HTML являются "левыми", тогда как система координат Three.js "правша". Это в основном означает, что их оси Y обращены вспять. В SVG/HTML, y/top идет по экрану, а Three.js использует более стандартное математическое соглашение y, спускающегося по экрану.

Мне нужно постоянно конвертировать из одного в другое, что довольно подвержено ошибкам. Я знаю, что я не первый, кто столкнулся с этим (например, смотрите здесь). Кто-нибудь придумал общее решение? Вот что я пробовал:

  • Сделайте все в Object3D с помощью .scale.y = -1. Как вы можете подозревать, это оказывается катастрофой. Он превращает все наизнанку, и даже не пытайтесь поставить свою камеру там.

  • Сделайте все в Object3D с помощью .rotate.x = Math.PI. Это более перспективно, но ось z больше не соответствует концепции HTML z-индекса. Тем не менее, это то, что я сейчас использую.

  • В HTML не используйте top, используйте bottom. В SVG сделайте все внутри <g transform="scale(1, -1)"> внутри <g transform="translate(0, imageHeight)">. Тем не менее, я считаю, что это будет более запутанным для разработчиков, и imageHeight должен постоянно обновляться, что является еще одним бременем.

Кто-нибудь придумал что-то лучше? Возможно, библиотека, чтобы помочь с этим?

Ответ 1

Я бы предложил вам использовать атрибут SVG Global Transform, если вы разместите пример своего кода, я могу отредактировать ответ и разместить здесь пример, возможно, JSfiddle.

В основном вам нужно будет добавить преобразование в ваш SVG, в вашем случае, чтобы изменить направление оси y, вы можете сделать "масштаб (1, -1)".

См. документацию W3 с примерами по следующей ссылке: http://www.w3.org/TR/SVG/coords.html#SVGGlobalTransformAttribute

Первое общее использование этого атрибута:

Большинство ProjectedCRS имеют северное направление, представленное позитивным значения второй оси и наоборот SVG имеет координату y-down система. Поэтому, чтобы следовать обычным способам представления карту с северной вершиной, рекомендуется для такого рода ProjectedCRS использует глобальный атрибут svg: transform с 'scale (1, -1)', как в третьем примере ниже.

У них также есть несколько примеров, я надеюсь, что это решит вашу проблему.:)