# Kinetic Mobile — `kinetic-mobile@1.0.0`

A Calder-style hanging mobile of brass arms and lacquered shapes, swaying and creeping round forever. Loops perfectly.

A hanging mobile in the manner of Alexander Calder: a tree of slender brass arms, each carrying two things on fine strings — a lacquered shape, or another arm that carries two more. Every arm turns about its own string at its own pace, swaying and creeping round, and every shape spins slowly, so the whole sculpture keeps finding new arrangements. Choose how many levels of arms (4, 8 or 16 shapes), the colours (primary, pastel, sunset or mono), how far the arms sway, how many whole turns they creep round per loop, the seed, the backdrop colour and whether the camera sways.

- Kind: object; status: published; digest sha256:24ccb373de0646a7181595a0a60a7da972f4d3386787fe08059a384bd16bc86b
- Role: Object (3D, three.js): a calm, designer-feel kinetic sculpture for home, art and design content.
- Implementation: three; entry `src/kinetic-mobile.js`
- Files: https://aipixelwizard.com/registry/kinetic-mobile/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/kinetic-mobile.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/kinetic-mobile/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/kinetic-mobile/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer, geometry and shader materials.; `chrome-material@1.1.0` (demo) — Studio environment light, backdrop and contact shadow.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createMobile({ levels?, palette?, sway?, spin?, seed? }) => { group, setProgress(progress), dispose() }` — The mobile hung from y = 8, about 6 wide and 6 tall; needs an environment map.
- `PALETTES: { primary, pastel, sunset, mono }` — Lacquer colours for the shapes.

## Parameters
- `levels` (integer 2–4, default 3) — Levels: Levels of arms: 2 gives 4 shapes, 3 gives 8, 4 gives 16.
- `palette` (select one of primary | pastel | sunset | mono, default "primary") — Colours
- `sway` (number 0–1.6, default 1) — Sway
- `spin` (integer 0–2, default 1) — Creep turns: Whole turns the arms creep round per loop.
- `seed` (integer 1–999, default 11) — Seed
- `background` (color, default "#c9ccd4") — Backdrop
- `orbit` (boolean, default true) — Camera sway

## Composition
- Inputs: Time within the loop; the levels, colours, sway, creep, seed, backdrop and camera sway.
- Outputs: A full frame rendered in 3D with a studio environment.
- Coordinates: The mobile hangs from a hook at y ≈ 9.5 on a thread to the root arm at y ≈ 6.7; the root arm is 3.4 wide and each level is 0.58 times the one above; the camera looks at y = 4.8.
- Lighting: A warm key light with a shadow map, a shadow-catching floor and the studio environment.
- Timing: setProgress(progress) sets every arm's turn and every shape's spin; frames render in any order.
- Works with: chrome-material, orbit-camera, kinetic-title, number-reveal
- Arms are nested groups, so each arm's motion carries everything it holds.

## Output and loop
- 1080×1080, 30 fps, 20 s, procedural
- Seamless loop: yes — Every arm creeps round a whole number of turns per loop and sways in a sine of whole cycles of the loop, every shape turns a whole number of times and the camera sway is a sine of the loop, so the last frame meets the first.
- Verified 2026-10-06 in Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0 (WebGL 2 via SwiftShader (software)); deterministic: yes; loop check: Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255.

## Use it
New project: Create a WebGLRenderer with a studio environment and a shadow-casting light, add createMobile().group and call mobile.setProgress(progress) each frame.

Existing project: Copy src/kinetic-mobile.js; add the group to your scene with an environment map.

Reuse ideas:
- Gallery: Primary, three levels.
- Nursery: Pastel.
- Evening: Sunset, dark.

## Limitations
- Arms do not physically balance: the motion is a formula, so heavy shapes do not tilt their arms.
- Shapes hang at fixed heights below their arms.

## License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.

Provenance: Adapted from the owner's threejs-sketches/objects-scenes/kinetic-mobile (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original studio object: a seeded recursive tree of brass arms and lacquered shapes with whole-turn creep, whole-cycle sway and spinning shapes on an exact loop.

