{
  "schemaVersion": 1,
  "id": "exploded-view",
  "version": "1.0.0",
  "status": "published",
  "kind": "motion",
  "title": "Exploded View",
  "summary": "A camera lens comes apart into its glass elements, aperture blades and rings, each part labelled, then clicks back together. Loops perfectly.",
  "description": "The \"how it works\" shot from this autumn's explainer videos. A real-looking object floats in a studio, then slides apart along its axis: the parts that travel furthest leave first, each one pulls in slightly before it moves and settles when it arrives. A thin leader line and a numbered label grow out to every part, the camera pulls back to show the whole layout, and the parts slide home in reverse with a small settle. In the camera lens the glass has the green and violet sheen of coated optics, the nine aperture blades close as the lens opens up and the focus ring turns. You can switch to a loudspeaker driver, change how far apart the parts go, how quickly they follow each other and how much they snap, turn the labels and title on or off, and pick the backdrop, label and accent colours and the camera angle. The animation code takes any list of parts, so you can explode your own product with it.",
  "role": "Hero motion (Three.js 3D): takes an object apart along its axis with labelled parts, on a seamless loop.",
  "collections": [
    "product-reveals",
    "chrome-glass",
    "satisfying"
  ],
  "tags": [
    "exploded view",
    "exploded",
    "explainer",
    "how it works",
    "camera lens",
    "lens",
    "anatomy",
    "teardown",
    "cutaway",
    "labels",
    "callouts",
    "diagram",
    "product",
    "speaker",
    "glass",
    "3d",
    "loop"
  ],
  "synonyms": [
    "exploded diagram",
    "exploded view animation",
    "product teardown",
    "parts breakdown",
    "how a camera lens works",
    "lens anatomy",
    "technical illustration",
    "assembly animation",
    "disassemble and reassemble",
    "labelled parts",
    "callout labels",
    "inside a product",
    "deconstructed product"
  ],
  "useCases": [
    "An explainer that shows what is inside a product, part by part",
    "A launch or crowdfunding video that sells the engineering",
    "A camera, photography or audio channel intro or end card",
    "A looping background for a talk or a product page"
  ],
  "featured": null,
  "publishedAt": "2026-10-10",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/exploded-view.js",
    "exports": [
      {
        "name": "createExplodedView",
        "signature": "createExplodedView({ parts, axis?, spread?, duration?, stagger?, overshoot? }) => { group, parts, amount, update(time), labelLayout(camera, width, height, rows?), dispose() }",
        "description": "Moves any list of parts ({ object, offset, name?, radius?, spin?, onProgress? }) apart along one axis and back on a seamless loop of duration seconds, with anticipation, overshoot and settle. amount is 0 when closed and 1 when fully open."
      },
      {
        "name": "createCameraLens",
        "signature": "createCameraLens({ accent?, engraving? }) => { parts, length, radius, dispose() }",
        "description": "A fast prime lens built in code (axis +Y, 1 unit = 1 cm): filter ring, coated front element, rubber focus ring, cemented doublet, nine-blade aperture, focus group, barrel with an accent ring, rear element and chrome bayonet mount."
      },
      {
        "name": "createSpeakerDriver",
        "signature": "createSpeakerDriver({ accent? }) => { parts, length, radius, dispose() }",
        "description": "A loudspeaker driver built in code: dust cap, surround, cone, voice coil, spider, cast basket, magnet and back plate."
      },
      {
        "name": "createLabelOverlay",
        "signature": "createLabelOverlay(width, height) => { canvas, ctx, draw(layout, { ink?, accent?, title?, fontFamily?, scale? }), render(renderer), dispose() }",
        "description": "Leader lines, numbered labels and a title drawn on a 2D canvas and composited over the WebGL frame, pixel for pixel. Labels in a row push each other apart so they never overlap."
      },
      {
        "name": "revolve",
        "signature": "revolve(profile, segments?) => THREE.BufferGeometry",
        "description": "A lathe that keeps hard edges hard and curves smooth, with material groups per edge (used for every round part)."
      }
    ],
    "reusable": [
      "src/exploded-view.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Renderer, geometry and physical materials (transmissive, coated glass)."
    },
    {
      "id": "chrome-material",
      "version": "1.1.0",
      "scope": "demo",
      "reason": "Studio environment light, backdrop, floor and contact shadow."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "subject",
      "label": "Object",
      "type": "select",
      "default": "lens",
      "options": [
        {
          "value": "lens",
          "label": "Camera lens"
        },
        {
          "value": "speaker",
          "label": "Loudspeaker driver"
        }
      ]
    },
    {
      "key": "spread",
      "label": "How far apart",
      "help": "How far the parts travel from their places. 1 is the normal layout.",
      "type": "number",
      "min": 0.6,
      "max": 1.4,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "stagger",
      "label": "Part delay",
      "help": "Seconds between one part starting to move and the next.",
      "type": "number",
      "min": 0,
      "max": 0.14,
      "step": 0.01,
      "default": 0.07
    },
    {
      "key": "snap",
      "label": "Snap",
      "help": "How much each part pulls in before it moves and settles when it lands. 0 is perfectly smooth.",
      "type": "number",
      "min": 0,
      "max": 2,
      "step": 0.1,
      "default": 1
    },
    {
      "key": "labels",
      "label": "Part labels",
      "type": "boolean",
      "default": true
    },
    {
      "key": "title",
      "label": "Title",
      "help": "A small heading at the top left. Leave empty for none.",
      "type": "text",
      "default": "Anatomy of a lens",
      "maxLength": 40,
      "sensitive": true
    },
    {
      "key": "angle",
      "label": "Camera",
      "type": "select",
      "default": "hero",
      "options": [
        {
          "value": "hero",
          "label": "Three-quarter"
        },
        {
          "value": "side",
          "label": "Side on (diagram)"
        },
        {
          "value": "above",
          "label": "From above"
        }
      ]
    },
    {
      "key": "orbit",
      "label": "Camera drift",
      "type": "boolean",
      "default": true
    },
    {
      "key": "background",
      "label": "Backdrop",
      "type": "color",
      "default": "#17191e"
    },
    {
      "key": "ink",
      "label": "Label colour",
      "type": "color",
      "default": "#eef0f4"
    },
    {
      "key": "accent",
      "label": "Accent colour",
      "help": "The ring on the lens (or the speaker's frame), the label dots and the title rule.",
      "type": "color",
      "default": "#e8412c"
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Lens in the dark studio",
      "params": {}
    },
    {
      "id": "blueprint",
      "label": "Blueprint diagram",
      "params": {
        "angle": "side",
        "background": "#123257",
        "ink": "#e3eeff",
        "accent": "#ffd166",
        "title": "Lens elements, exploded"
      }
    },
    {
      "id": "white",
      "label": "White product shot, no labels",
      "params": {
        "labels": false,
        "title": "",
        "angle": "above",
        "background": "#e6e3de",
        "ink": "#1b1d22",
        "accent": "#d9381e",
        "snap": 1.4
      }
    },
    {
      "id": "speaker",
      "label": "Speaker teardown",
      "params": {
        "subject": "speaker",
        "background": "#211b17",
        "ink": "#f4ece2",
        "accent": "#f2a93b",
        "title": "Inside a woofer",
        "stagger": 0.09
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 8,
    "posterSeconds": 4,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 8,
      "method": "One loop is closed → apart → hold → closed: every part's travel, spin and the aperture are functions of the loop phase that return exactly to zero (the settle ends at rest before the loop ends), and the camera drift is a sine of the loop, so the last frame meets the first."
    },
    "seed": null
  },
  "composition": {
    "inputs": "Time in seconds; a list of parts (any THREE.Object3D) with how far each travels along the axis.",
    "outputs": "A THREE.Group holding the parts, posed for the time; label positions in screen pixels; a 2D overlay drawn over the frame.",
    "coordinates": "Parts travel along the group's local axis (default +Y). The lens and speaker are 1 unit = 1 cm, axis +Y, front towards +Y, centred on the origin.",
    "lighting": "Physical materials: needs scene.environment for the glass coating, the chrome mount and the anodised metal; any key and rim light helps the edges.",
    "timing": "update(time) is a pure function of time; frames render in any order.",
    "compatibleWith": [
      "chrome-material",
      "kinetic-title",
      "orbit-camera",
      "lens-flare"
    ],
    "notes": [
      "The title is treated as private: it is not stored in shared packs unless you choose to include it.",
      "Labels use the system's Helvetica Neue, Helvetica or Arial in bold small caps with wide tracking; pass fontFamily to draw() for your own typeface.",
      "Glass uses transmission, so it refracts the opaque parts and the studio behind it."
    ]
  },
  "reuse": [
    "Explode your own product: give createExplodedView your meshes, how far each should travel and a name, and keep the label overlay.",
    "Camera or photography channel: the default with the title set to your channel, then cut to Kinetic Title Reveal for the name.",
    "Audio product: Speaker teardown on your brand colour, with labels off and Camera drift on as a loop behind a voice-over.",
    "Clean product page loop: White product shot, no labels, on your page background."
  ],
  "integration": {
    "newProject": "Set scene.environment (createStudioEnvironment from Chrome Material works), build createCameraLens() or your own parts, pass them to createExplodedView, add view.group to the scene and call view.update(seconds) every frame. For labels: renderer.render(scene, camera), then overlay.draw(view.labelLayout(camera, width, height)) and overlay.render(renderer).",
    "existingProject": "Copy src/exploded-view.js. Wrap the parts of your model in createExplodedView with an offset each (positive = forwards along the axis); place and rotate view.group like any object. Use labelLayout and createLabelOverlay only if you want callouts."
  },
  "performance": {
    "notes": "About sixty meshes made once; each frame moves them and redraws one 2D label canvas. Transmissive glass costs an extra render pass. Smooth at 1080p on laptop GPUs.",
    "limits": "Software WebGL (no GPU) renders slowly, about a second a frame at 1080p."
  },
  "limitations": [
    "Parts move along one straight axis only; objects whose parts come apart sideways (a phone, a shoe) need their own offsets in several directions.",
    "Part names are fixed in the two built-in objects; change them in the code or pass your own parts.",
    "Labels are drawn flat over the picture, so a part can never hide its label."
  ],
  "license": {
    "spdx": "MIT",
    "notice": "Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.",
    "thirdParty": [
      {
        "name": "three.js",
        "version": "0.185.1",
        "license": "MIT",
        "url": "https://github.com/mrdoob/three.js"
      }
    ]
  },
  "provenance": "Original code written for AI Pixel Wizard on 2026-10-06 by an automated agent (the daily trend routine), inspired by the exploded-view and cutaway explainers made with Claude Opus 5.5 in late September and early October 2026, among them an exploded camera lens lab by @RyanSael and a turbofan cutaway by @techartist_, as listed in the Claude Video index (https://claudevideo.org/videos/interactive-lab-explains-focus-with-an-exploded-camera-lens, https://claudevideo.org/videos/turbofan-jet-engine-opens-into-an-interactive-3d-cutaway). No code, models, images or fonts were copied, and no technique was taken from those videos. The lens and the speaker are modelled in code from general knowledge of how they are built.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-06",
      "notes": "Initial release."
    }
  ]
}
