Skip to content

Viewer-postMessage-API ​

Verwenden Sie die Viewer-PostMessage-API, wenn eine übergeordnete HTML-Seite den Voluma-Viewer in ein iframe einbettet und die Seitenoberfläche mit dem Viewer-Status koordinieren muss. Der elternteil kann einen marker innerhalb des betrachters fokussieren, und der betrachter kann den elternteil benachrichtigen, wenn er bereit ist, wenn sich der markerfokus ändert oder wenn eine markeraktion eine benutzerdefinierte nachricht sendet.

Einrichtung ​

Embed the custom viewer URL from Custom Viewer (Embed), then open Projekteinstellungen and set Allowed origins unter Viewer API. Dieses Feld auf Projektebene wird gespeichert als settings.embed.allowedParentOrigins und muss den genauen Ursprung der Elternseite enthalten.

Geben Sie Origins als kommagetrennte vollständige URLs ein, zum Beispiel https://www.example.com, https://partner.example.com. Lokale Entwicklungsherkunft wie http://127.0.0.1:5172 kann beim Testen hinzugefügt werden.

html
<iframe
  id="voluma-viewer"
  src="https://voluma.ai/embed/client/project/scene"
  width="100%"
  height="640"
  allowfullscreen
></iframe>

Alle Runtime-Checks verwenden genaue Ursprünge. Parent-to-Viewer-Befehle von anderen Ursprüngen werden abgelehnt, und Viewer-to-Eltern-Nachrichten werden mit exakter targetOrigin Werte. Nicht verwenden * als Zielursprung im Stammcode der Produktion.

Elternschaft zum Betrachter ​

Der unterstützte Parent-to-Viewer-Befehl ist voluma.viewer.focusMarker.

FeldTypErforderlichBeschreibung
typestringJaMuss sein voluma.viewer.focusMarker.
versionnumberYesMuss sein 1.
requestIdstringJaParent-generated ID verwendet, um die Bestätigung oder Fehler entsprechen.
markerIdZeichenfolge oder ZahlJaMarker ID zum Fokussieren
js
const iframe = document.querySelector("#voluma-viewer");
const viewerOrigin = new URL(iframe.src).origin;
let requestCounter = 0;

function focusMarker(markerId) {
  iframe.contentWindow?.postMessage(
    {
      type: "voluma.viewer.focusMarker",
      version: 1,
      requestId: `marker-${Date.now()}-${++requestCounter}`,
      markerId
    },
    viewerOrigin
  );
}

Viewer to Parent ​

Der Viewer sendet typisierte Protokollereignisse zum Lebenszyklus der Einbettung und zur Rückmeldung auf Befehle.

EreignistypPayloadWann es gesendet wird
voluma.viewer.ready{ type, version }Der Embed Viewer ist geladen und bereit, Befehle zu empfangen.
voluma.viewer.markerFocused{ type, version, markerId, requestId? }Ein Marker erhält den Fokus. requestId ist enthalten, wenn das Ereignis einen Befehl bestätigt.
voluma.viewer.error{ type, version, code, message, requestId? }Ein Befehl ist ungültig, nicht erlaubt, nicht unterstützt oder konnte nicht ausgeführt werden.

Bekannte Fehlercodes sind INVALID_MESSAGE, UNAUTHORIZED_ORIGIN, MARKER_NOT_FOUND, VIEWER_NOT_READY, UNSUPPORTED_VERSION, UNSUPPORTED_COMMAND, und INTERNAL_ERROR.

js
window.addEventListener("message", (event) => {
  if (event.origin !== viewerOrigin) return;
  if (!event.data || typeof event.data !== "object") return;

  if (event.data.type === "voluma.viewer.ready") {
    console.log("Viewer ready");
  }

  if (event.data.type === "voluma.viewer.markerFocused") {
    console.log("Focused marker", event.data.markerId, event.data.requestId);
  }

  if (event.data.type === "voluma.viewer.error") {
    console.warn("Viewer command failed", event.data.code, event.data.message);
  }
});

Markierungs-Aktionsmeldungen ​

Marker können auch benutzerdefinierte Nachrichten an die übergeordnete Seite senden. In Studio konfigurieren Sie eine Markierungsaktion mit dem Aktionstyp postMessage, einem Nachrichtentyp und einer optionalen Nutzdatenvorlage.

Der Betrachter sendet Marker-Aktionsnachrichten mit dieser Form:

js
{
  source: "volumaviewer",
  type: "marker-action",
  payload: {
    id: 7,
    parent_id: 0,
    type: "sphere",
    title: "Marker title"
  },
  timestamp: 1710000000000
}

Payload Templates können verwendet werden {id}, {parent_id}, {type}, und {title}. Wenn die gerenderte Nutzlast JSON gültig ist, erhält der Elternteil analysiertes JSON. Wenn nicht, erhält der Elternteil den gerenderten String.

js
window.addEventListener("message", (event) => {
  if (event.origin !== viewerOrigin) return;
  const data = event.data;
  if (!data || typeof data !== "object") return;

  if (data.source === "volumaviewer" && data.type === "marker-action") {
    console.log("Marker action payload", data.payload);
  }
});

Muster der Mutterseite ​

Behalten Sie für die Seitenoberfläche, die das iframe steuert, den Viewer-Ursprung an einer Stelle, validieren Sie jede eingehende Nachricht und generieren Sie eindeutige Request-IDs für Befehle. Die Veerse Toren-Demo verwendet dieses Muster, um Viewer-Marker von externen Callout-Buttons zu fokussieren und reagiert dann auf eine benutzerdefinierte Marker-Nachricht, indem sie Seiteninhalte unter dem iframe anzeigt.

js
const iframe = document.querySelector(".embedCode iframe");
const viewerOrigin = new URL(iframe.src).origin;
let latestRequestId = 0;

window.addEventListener("message", (event) => {
  if (event.origin !== viewerOrigin) return;
  const data = event.data;
  if (!data || typeof data !== "object") return;

  if (data.source === "volumaviewer" && data.payload?.action === "geschiedenis") {
    document.querySelector(".history-section")?.classList.add("is-visible");
  }
});

document.querySelectorAll("[data-marker-id]").forEach((button) => {
  button.addEventListener("click", () => {
    iframe.contentWindow?.postMessage(
      {
        type: "voluma.viewer.focusMarker",
        version: 1,
        requestId: `parent-${Date.now()}-${++latestRequestId}`,
        markerId: button.dataset.markerId
      },
      viewerOrigin
    );
  });
});

URL Fallback ​

Wenn das iframe nicht bereit ist, zu einer anderen Szene navigiert wurde oder zurückgesetzt werden muss, bevor ein Marker fokussiert wird, aktualisieren Sie die iframe-URL mit dem Marker-Abfrageparameter, anstatt einen Befehl zu senden:

js
function buildMarkerUrl(originalIframeUrl, markerId) {
  const url = new URL(originalIframeUrl, window.location.href);
  url.searchParams.set("m", markerId);
  return url.toString();
}

iframe.src = buildMarkerUrl(iframe.dataset.iframe || iframe.src, markerId);

Verwenden Sie dieses Fallback für vollständige iframe-Reloads. Verwendung voluma.viewer.focusMarker Wenn der aktuelle iframe geladen ist und in der gleichen szene bleiben soll.