2014-12-05 7 views
11

Ich kombiniere 3D-Inhalte mit Three.js mit HTML- und SVG-Inhalten. Der Three.js CSSLoader kann die Platzierung von HTML- und SVG-Inhalten in der 3D-Welt sehr gut synchronisieren.Wie synchronisiert man das Three.js- und das HTML/SVG-Koordinatensystem (speziell auf der y-Achse)?

Aber die SVG/HTML-Koordinatensysteme sind "Linkshänder", während das Three.js-Koordinatensystem "Rechtshänder" ist. Dies bedeutet im Wesentlichen, dass ihre y-Achsen umgekehrt sind. In SVG/HTML, y/top geht nach oben, wenn Sie den Bildschirm gehen, und Three.js verwendet die mehr standardmäßige mathematische Konvention von y geht nach unten, wie Sie den Bildschirm gehen.

Ich muss ständig von einem zum anderen konvertieren, was ziemlich fehleranfällig ist. Ich weiß, dass ich nicht der Erste bin, der darauf reinkommt (zum Beispiel look here). Hat jemand eine allgemeine Lösung gefunden? Hier ist, was ich versucht:

  1. Tun Sie alles in einem Object3D mit .scale.y = -1. Wie Sie vielleicht vermuten, stellt sich heraus, dass dies eine Katastrophe ist. Es dreht alles um, und versuchen Sie nicht einmal, Ihre Kamera hineinzustellen.

  2. Tun Sie alles in Object3D mit .rotate.x = Math.PI. Dies ist vielversprechender, aber die Achse z stimmt nicht mehr mit dem HTML-Konzept des Z-Index überein. Trotzdem verwende ich das jetzt.

  3. Verwenden Sie in HTML nicht top, verwenden Sie bottom. In SVG, alles innerhalb einer <g transform="scale(1, -1)"> innerhalb einer <g transform="translate(0, imageHeight)"> tun. Ich denke jedoch, dass dies für Entwickler verwirrender wäre, und die imageHeight muss immer auf dem neuesten Stand gehalten werden, was eine weitere Belastung darstellt.

Hat sich jemand etwas besseres einfallen lassen? Vielleicht eine Bibliothek, um damit zu helfen?

+0

Ich denke, die Lösung ist ein Weltkoordinatensystem für Ihre SVG/HTML mit THREE.js Konvention zu erstellen.Also die Mitte des Bildschirms (genannt Viewport) ist 0,0,0. So werden Objekte in SVG/HTML durch viewport.center (0,0,0) + viewport.halfWidth transformiert. – beiller

+0

@Beiller: Ich sehe nicht, wie dies das gekippte y-Achse-Problem löst, worum meine Frage geht. : -/Fehle ich etwas? – mhelvens

+0

Vielleicht bist du, oder vielleicht ist es aus deiner Situation nicht machbar. ZB: Sie haben ein CSS-Sprite bei Weltkoordinaten (2,0,0). Um das Sprite zu zeichnen, würden Sie die folgende Formel verwenden: pos.x + viewportCenter.x + viewportHalfWidth.x - object.halfWidth.x. Das bedeutet, dass (0,0,0) Viewport- und 10x10-Sprite- und 800x600-Dimensionen vorausgesetzt werden. Sie zeichnen x mit 397 Pixel von der linken Seite des Fensters. – beiller

Antwort

1

Ich würde vorschlagen, dass Sie das SVG Global Transform Attribut verwenden, wenn Sie ein Beispiel Ihres Codes veröffentlichen, könnte ich die Antwort bearbeiten und das Beispiel hier, vielleicht ein JSfiddle.

Grundsätzlich müssen Sie die Transformation zu Ihrem SVG hinzufügen, in Ihrem Fall, um die Richtung der y-Achse zu ändern, können Sie eine "Skalierung (1, -1)" tun.

Siehe die W3-Dokumentation mit Beispielen in dem folgenden Link: http://www.w3.org/TR/SVG/coords.html#SVGGlobalTransformAttribute

Die erste gemeinsame Verwendung dieses Attributs:

meisten ProjectedCRS haben die Nordrichtung durch positive Werte der zweiten Achse dargestellt und umgekehrt hat SVG ein y-down-Koordinatensystem . Aus diesem Grund ist es für die Art ProjectedCRS empfehlenswert, das globale Attribut 'svg: transform' mit einer '-Skala (1, -) zu verwenden, um die übliche Darstellung einer Karte mit dem Norden an dessen Spitze zu erhalten. 1) Wert wie im dritten Beispiel unten.

Sie haben dort auch einige Beispiele, ich hoffe, es löst Ihr Problem. :)

+0

Jeder Text wird auf dem Kopf stehen. –

+0

Das ist Sache nr.3 Ich versuchte es (siehe Originalfrage). Es hat eine Reihe von Problemen. Und @RobertLongson hat Recht: Die Dinge wären auf den Kopf gestellt - nicht nur Text, sondern jedes Element, das ich hineinlege. Trotzdem, ich fürchte, das könnte das kleinere Übel sein. Vielleicht, wenn es eine Möglichkeit gibt, dies automatisch zu korrigieren, d. H. Jedes untergeordnete Element lokal zu verkleinern? – mhelvens

+0

Hi, ja, tatsächlich wird alles auf den Kopf gestellt, ich dachte, in deiner Nummer 3 hast du das Globale nicht ausprobiert. Ich habe auch über das Internet geschaut, aber ich habe keine andere Möglichkeit gefunden, das zu tun, was Sie wollen, leider denke ich, dass es für den Moment keine einfache Lösung gibt, tut mir leid und sieht gut aus. – Jacobi

Verwandte Themen