{
  "schemaVersion": 1,
  "id": "pocket-watch",
  "version": "1.0.0",
  "status": "published",
  "kind": "object",
  "title": "Gold Pocket Watch",
  "summary": "A polished gold pocket watch whose hands show any time, with a ticking, beating or sweeping second hand.",
  "description": "A pocket watch made entirely in code: a lathe-turned gold case with a domed glass crystal, an enamel dial with Roman numerals or applied batons, blued-steel Breguet hands, a knurled crown and a chain. Set the time it starts at and how fast time runs, from real time with a quartz tick to a time-lapse where the hands race round. Pick the case metal and the dial.",
  "role": "Hero object: a 3D pocket watch that shows a chosen time.",
  "collections": [
    "product-reveals",
    "chrome-glass"
  ],
  "tags": [
    "watch",
    "pocket watch",
    "clock",
    "time",
    "gold",
    "metal",
    "luxury",
    "countdown",
    "ticking",
    "3d"
  ],
  "synonyms": [
    "gold watch",
    "ticking clock",
    "timepiece",
    "stopwatch",
    "watch face",
    "clock hands",
    "time passing",
    "deadline clock",
    "vintage watch"
  ],
  "useCases": [
    "A countdown or deadline moment",
    "A time-lapse for 'later that day'",
    "A luxury product shot"
  ],
  "featured": null,
  "publishedAt": "2026-10-05",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/pocket-watch.js",
    "exports": [
      {
        "name": "createPocketWatch",
        "signature": "createPocketWatch({ finish?, dial?, numerals?, chain?, crystal?, anisotropy? }) => { group, setTime(seconds, { motion?, showSeconds? }), dispose() }",
        "description": "The watch as a THREE.Group in watch units (case radius 1, dial facing +Y). setTime takes seconds since midnight."
      },
      {
        "name": "handAngles",
        "signature": "handAngles(seconds, motion = 'tick') => { hour, minute, second }",
        "description": "Clockwise hand angles in radians; motion is 'tick' (quartz step with settle), 'beat' (six steps a second) or 'sweep'."
      },
      {
        "name": "watchSeconds",
        "signature": "watchSeconds(info, { start?, rate? }) => number",
        "description": "Time shown at a frame: start + elapsed video time × rate (1 real time, 60 a minute per second, 3600 an hour per second)."
      },
      {
        "name": "drawDial",
        "signature": "drawDial({ dial?, numerals?, size?, dialRadius? }) => HTMLCanvasElement",
        "description": "The dial artwork on a canvas (Roman numerals are drawn as strokes, so no font is needed)."
      }
    ],
    "reusable": [
      "src/pocket-watch.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Geometry, physical materials, transmission glass and shadows."
    },
    {
      "id": "chrome-material",
      "version": "1.1.0",
      "scope": "demo",
      "reason": "Demo uses the shared studio: environment light, cove, floor and contact shadow."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "finish",
      "label": "Case metal",
      "type": "select",
      "default": "gold",
      "options": [
        {
          "value": "gold",
          "label": "Yellow gold"
        },
        {
          "value": "rose",
          "label": "Rose gold"
        },
        {
          "value": "silver",
          "label": "Silver"
        },
        {
          "value": "black",
          "label": "Gunmetal"
        }
      ]
    },
    {
      "key": "dial",
      "label": "Dial",
      "type": "select",
      "default": "cream",
      "options": [
        {
          "value": "cream",
          "label": "Cream enamel"
        },
        {
          "value": "white",
          "label": "White enamel"
        },
        {
          "value": "black",
          "label": "Black sunburst"
        },
        {
          "value": "blue",
          "label": "Blue sunburst"
        }
      ]
    },
    {
      "key": "numerals",
      "label": "Hour markers",
      "type": "select",
      "default": "roman",
      "options": [
        {
          "value": "roman",
          "label": "Roman numerals"
        },
        {
          "value": "batons",
          "label": "Metal batons"
        }
      ]
    },
    {
      "key": "hour",
      "label": "Start hour",
      "type": "integer",
      "min": 1,
      "max": 12,
      "step": 1,
      "default": 10
    },
    {
      "key": "minute",
      "label": "Start minute",
      "type": "integer",
      "min": 0,
      "max": 59,
      "step": 1,
      "default": 8
    },
    {
      "key": "second",
      "label": "Start second",
      "type": "integer",
      "min": 0,
      "max": 59,
      "step": 1,
      "default": 36
    },
    {
      "key": "motion",
      "label": "Second hand",
      "help": "How the second hand moves in real time.",
      "type": "select",
      "default": "tick",
      "options": [
        {
          "value": "tick",
          "label": "Ticks each second"
        },
        {
          "value": "beat",
          "label": "Mechanical beat"
        },
        {
          "value": "sweep",
          "label": "Smooth sweep"
        }
      ]
    },
    {
      "key": "speed",
      "label": "Time speed",
      "help": "Fast speeds turn the clip into a time-lapse.",
      "type": "select",
      "default": "real",
      "options": [
        {
          "value": "real",
          "label": "Real time"
        },
        {
          "value": "minutes",
          "label": "A minute per second"
        },
        {
          "value": "hours",
          "label": "An hour per second"
        }
      ]
    },
    {
      "key": "chain",
      "label": "Chain",
      "type": "boolean",
      "default": true
    },
    {
      "key": "crystal",
      "label": "Glass crystal",
      "help": "The domed glass over the dial. It adds reflections; turn it off for the clearest dial.",
      "type": "boolean",
      "default": true
    },
    {
      "key": "surface",
      "label": "Velvet colour",
      "type": "color",
      "default": "#3a0c18"
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Classic gold",
      "params": {}
    },
    {
      "id": "midnight",
      "label": "Black dial, gold batons",
      "params": {
        "dial": "black",
        "numerals": "batons",
        "motion": "sweep",
        "surface": "#0e0e12"
      }
    },
    {
      "id": "silver",
      "label": "Silver and white",
      "params": {
        "finish": "silver",
        "dial": "white",
        "motion": "beat",
        "hour": 3,
        "minute": 51,
        "second": 12,
        "surface": "#12204a"
      }
    },
    {
      "id": "time-flies",
      "label": "Time flies (rose gold)",
      "params": {
        "finish": "rose",
        "dial": "blue",
        "numerals": "batons",
        "speed": "hours",
        "hour": 9,
        "minute": 0,
        "second": 0,
        "surface": "#123026"
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 8,
    "posterSeconds": 1.5,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": false,
      "method": "Not a loop: the hands show time passing. The camera sway is periodic, so only the hands jump when a preview restarts."
    },
    "seed": null
  },
  "composition": {
    "inputs": "Seconds since midnight for setTime (watchSeconds turns frame info into it). Needs scene.environment for the metal.",
    "outputs": "A THREE.Group: case, dial, hands, crystal, crown, bow and an optional chain lying on the floor.",
    "coordinates": "Watch units: case radius 1, dial facing +Y, 12 o'clock toward -Z. The back rests on y = -0.16 and the chain lies at that level, so lift the group by 0.16 × its scale to stand it on a floor.",
    "lighting": "Image-based (scene.environment) for the metal; add a shadow-casting directional light for hand shadows on the dial.",
    "timing": "setTime(seconds) is a pure function of the time shown; frames render in any order.",
    "compatibleWith": [
      "chrome-material",
      "orbit-camera",
      "rolling-counter",
      "kinetic-title",
      "armillary-sphere"
    ],
    "notes": [
      "Stand it upright by rotating the group -90° about X (dial toward +Z) and pass chain: false.",
      "The crystal uses transmission, which refracts only opaque objects behind it (the dial and hands are opaque).",
      "The demo lays it on a velvet tray (a sheen material) with a shadow-casting key light; that tray is part of demo.js, not the reusable file."
    ]
  },
  "reuse": [
    "Countdown or deadline scene: set the start time a few seconds before the hour and let it tick, with Rolling Counter or Kinetic Title beside it.",
    "Time-lapse: 'An hour per second' races the hands round for 'later that day' or 'all-nighter' moments.",
    "Luxury product shot: change the case metal and dial for a different brand feel and orbit it with Smooth Orbit Camera."
  ],
  "integration": {
    "newProject": "Create a Three.js scene with an environment map (createStudioEnvironment from Chrome Material), add createPocketWatch().group and call setTime(watchSeconds(info, { start })) every frame.",
    "existingProject": "Copy src/pocket-watch.js. Add watch.group to your scene, scale and place it, and call watch.setTime(seconds) from your frame loop. Your scene needs an environment map for the metal to look like metal."
  },
  "performance": {
    "notes": "About 320 meshes plus one instanced chain; the dial texture (2048 × 2048) is drawn once; the glass crystal costs one extra transmission pass per frame.",
    "limits": "On phones pass crystal: false and drawDial({ size: 1024 }), or skip shadow maps."
  },
  "limitations": [
    "Only the dial side is modelled: there is no movement or caseback to show.",
    "The hands show a 12-hour time; there is no date or day.",
    "At an hour per second the second hand is hidden, because it would strobe."
  ],
  "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": "Adapted from the owner's threejs-sketches/objects-scenes/pocket-watch (MIT), rebuilt for AI Pixel Wizard in October 2026: new lathe-turned case, crystal, font-free dial, Breguet hands and chain, the shared studio, and the frame/time contract.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-05",
      "notes": "Initial release."
    }
  ]
}
