Iframe Preview Slice

Rabbit Studio Animator

The editor now speaks to a real preview iframe on the same app. The current proof is narrow on purpose: boot preview, exchange bridge envelopes, request a live target snapshot, and keep the naming contract explicit for every nested animation-ready element.

What is live
Live preview is now realThe editor boots a real iframe target and can now point either at the built-in preview runtime or at an external local workspace preview.
Target discovery stays explicitThe preview reports only named data-anim nodes, so target identity stays stable even when DOM structure changes.
Bridge remains versionedEditor and preview exchange typed envelopes before selection or draft playback gets deeper.

Immediate next build-out

  • Turn the draft loop into a real preview-backed motion authoring surface, not only a message proof.
  • Use reusable motion recipes and richer controls before the first staging contour is cut.
  • Move the shell toward a timeline-first workbench instead of a narrow inspector.
Preview

Live iframe handshake

Rabbit Marketing Site now drives the preview through connector-owned route data. Current preview route: /landing.

Bridge state: bootingSession connected: noTargets discovered: 0Hovered: noneSelected: noneDraft playback: idleLast cleared page: nonePreview origin: https://animator.dev.breachrabbit.ru
Naming Base

Animation-ready UI rule

  • Every nested animation-ready element gets its own explicit name, not just the outer section.
  • Names stay hierarchical and readable, for example preview-landing-proof-card-performance-value.
  • Avoid vague or numeric-only IDs when a semantic name can identify the UI part directly.
  • The editor targets IDs, not inferred selectors or vague DOM positions.

Draft inspector

Draft authoring now moves beyond a single hardcoded reveal. Recipes and richer motion controls still stay JSON-first, but the preview runtime now replays a real start-to-end draft instead of only setting a final pose.

Live bridge traffic

The editor records the latest envelope traffic from the real iframe preview.

[]

Preview-backed session state

Draft playback now rides the same bridge session. The active playback snapshot stays editor-owned while the iframe applies the draft to real targets.

{
  "editorReady": false,
  "previewReady": false,
  "queuedMessages": [],
  "activePlayback": null,
  "activeStylePatches": [],
  "lastClearedPageId": null
}

JSON-first animation baseline

The preview loop is live, but animation data still stays portable and editor-owned.

{
  "version": 1,
  "projectId": "rabbit-marketing-site",
  "pageId": "landing",
  "targets": [
    {
      "id": "hero-title",
      "label": "Hero title",
      "kind": "element",
      "route": "/",
      "componentPath": "app/page.tsx",
      "selector": "[data-anim='hero-title']",
      "reference": {
        "strategy": "data-anim",
        "attribute": "data-anim",
        "value": "hero-title"
      }
    },
    {
      "id": "hero-cards",
      "label": "Hero cards",
      "kind": "group",
      "route": "/",
      "selector": "[data-anim='hero-cards']",
      "reference": {
        "strategy": "data-anim",
        "attribute": "data-anim",
        "value": "hero-cards"
      }
    }
  ],
  "animations": [
    {
      "id": "hero-title-fade-up",
      "targetId": "hero-title",
      "mode": "fromTo",
      "props": {
        "opacity": 0,
        "y": 32
      },
      "toProps": {
        "opacity": 1,
        "y": 0
      },
      "duration": 0.65,
      "ease": "power2.out",
      "trigger": {
        "type": "load"
      },
      "enabled": true
    }
  ],
  "timelines": [],
  "presetsUsed": [
    "fade-up"
  ],
  "settings": {
    "previewBaseUrl": "https://animator.dev.breachrabbit.ru/",
    "previewRoute": "/landing"
  }
}