Loading scene...
Frontend Integration

Selectors: prefer publicId, then id, then exact name. Duplicate names return a structured error.

Coordinates: API defaults to { coordSystem: "panda", space: "local" }. Use coordSystem: "three" to work in Three.js axes. Local means transform relative to parent.

// Same-page JS API
const viewer = window.EGWebGLViewer;
await viewer.ready;

const nodes = viewer.nodes.list();
const hero = nodes.find((node) => node.kind === "model");

viewer.animation.play({ publicId: hero.publicId }, {
  clip: "Walk",
  loop: true,
  restart: true,
});

viewer.nodes.translate({ publicId: hero.publicId }, { x: 1, y: 0, z: 0 });
viewer.nodes.setTransform(
  { publicId: hero.publicId },
  { rotation: { h: 45, p: 0, r: 0 } },
  { coordSystem: "panda", space: "local" },
);

const supportedScripts = viewer.scripts.listSupported();
console.log("web supported scripts", supportedScripts);

viewer.scripts.attach({ publicId: hero.publicId }, {
  name: "MoverScript",
  params: {
    move_axis: "x",
    move_distance: 3,
    move_speed: 1.5,
  },
});

viewer.events.on("animationFinished", (payload) => {
  console.log("animation finished", payload);
});
// iframe + postMessage
const iframe = document.querySelector("iframe");

iframe.contentWindow.postMessage({
  source: "eg-frontend",
  type: "handshake",
  id: "hello-1",
}, iframe.src ? new URL(iframe.src).origin : "*");

window.addEventListener("message", (event) => {
  if (!event.data || event.data.source !== "eg-webgl") return;
  console.log("viewer message", event.data);
});

iframe.contentWindow.postMessage({
  source: "eg-frontend",
  type: "command",
  id: "cmd-1",
  command: "scripts.attach",
  payload: {
    selector: { publicId: "model:asset-guid:root" },
    script: {
      name: "RotatorScript",
      params: { rotation_speed_y: 45 },
    },
  },
}, iframe.src ? new URL(iframe.src).origin : "*");

Message protocol: commands use { source: "eg-frontend", id, type: "command", command, payload }. Responses/events use { source: "eg-webgl", type, replyTo?, event?, ok?, result?, error? }.

Events: ready, error, animationFinished, stateChanged.

Script note: exported WebGL can read existing script metadata, but browser-side runtime only executes Web-supported script adapters, not arbitrary Python files.

Demo page: after export, open frontend_demo.html to see a working iframe host example.