{"id":"split-flap","version":"1.0.1","title":"Split-Flap Display","summary":"Your message on an airport departure board, every letter flipping into place, then changing to a second message.","kind":"text","target":"three","collections":["kinetic-text","satisfying"],"tags":["split flap","departure board","flip board","solari","airport","train station","retro","mechanical","title","reveal"],"loopable":false,"motion":"procedural","durationSeconds":9,"status":"published","media":{"poster":"https://aipixelwizard.com/media/split-flap/1.0.1/poster.webp","preview":"https://aipixelwizard.com/media/split-flap/1.0.1/preview.mp4","sample":"https://aipixelwizard.com/media/split-flap/1.0.1/sample.mp4","sampleBytes":729055,"sampleNote":"Pre-rendered with the default settings. Customised settings must be exported locally (npm run render)."},"urls":{"page":"https://aipixelwizard.com/visuals/split-flap","manifest":"https://aipixelwizard.com/api/v1/visuals/split-flap/versions/1.0.1","agentMd":"https://aipixelwizard.com/registry/split-flap/1.0.1/agent.md","files":"https://aipixelwizard.com/registry/split-flap/1.0.1/","demo":"https://aipixelwizard.com/registry/split-flap/1.0.1/index.html"},"description":"A split-flap board like the ones in old stations and airports. Each little module flips through its letters, the flaps falling and slapping down, until your words settle in a ripple from left to right; then the board flips on to a second message. Type up to three lines for each message, pick the flap and letter colours, the flip speed, and a straight-on or angled view.","role":"Title or sign (Three.js 3D): a split-flap board that spells and changes your message.","useCases":["A title reveal for travel, trip and holiday videos","Announcements: \"Now boarding\", \"Coming soon\", a launch date","A score or countdown that flips when it changes"],"synonyms":["flip clock text","solari board","departures board","flap display","airport sign","station board","split flap text","flip letters"],"digest":"5f6cbd920a6b681292e4389a364db35b357c99a01401087a8d28e27d8fa11166","implementation":{"target":"three","runtime":"browser","language":"javascript","module":"esm","entry":"src/split-flap.js","exports":[{"name":"createSplitFlapBoard","signature":"createSplitFlapBoard({ messages, times?, rows?, columns?, align?, flipRate?, ripple?, jitter?, flapColor?, textColor?, housingColor?, fontFamily?, seed?, anisotropy? }) => { group, width, height, rows, columns, settledAt, update(time), dispose() }","description":"The board as a THREE.Group centred at the origin, facing +z; update(time in seconds) every frame."},{"name":"splitLines","signature":"splitLines(text) => string[]","description":"'NOW BOARDING|GATE 12' → ['NOW BOARDING', 'GATE 12']."},{"name":"toDrum","signature":"toDrum(text) => string[]","description":"Text as the characters the drum has (capitals, accents dropped, the rest blank)."},{"name":"DRUM","signature":"DRUM: string","description":"The characters on every module, in flipping order."}],"reusable":["src/split-flap.js"],"demo":"demo.js","harness":"index.html"},"dependencies":[{"id":"three","version":"0.185.1","scope":"source","reason":"Renderer, geometry and materials."},{"id":"chrome-material","version":"1.1.0","scope":"demo","reason":"Studio environment light for the demo."},{"id":"apw-runtime","version":"1.0.0","scope":"demo","reason":"Demo harness."}],"uses":[],"usedBy":[],"params":[{"key":"text1","label":"First message","help":"Use | to start a new line (up to 3 lines).","type":"text","default":"NOW|BOARDING|GATE 12","maxLength":80,"sensitive":true},{"key":"text2","label":"Then","help":"A second message to flip to. Leave empty to keep the first.","type":"text","default":"FINAL|CALL|LISBON","maxLength":80,"sensitive":true},{"key":"changeAt","label":"Change at (seconds)","type":"number","min":2,"max":8,"step":0.1,"default":4.6},{"key":"flapColor","label":"Flap colour","type":"color","default":"#1d1d21"},{"key":"textColor","label":"Letter colour","type":"color","default":"#f2eee4"},{"key":"speed","label":"Flips per second","type":"number","min":8,"max":30,"step":1,"default":18},{"key":"ripple","label":"Ripple","help":"Delay from one column to the next, in seconds.","type":"number","min":0,"max":0.12,"step":0.005,"default":0.035},{"key":"columns","label":"Columns","help":"0 fits the longest line.","type":"integer","min":0,"max":24,"step":1,"default":0},{"key":"align","label":"Alignment","type":"select","default":"center","options":[{"value":"center","label":"Centred"},{"value":"left","label":"Left"}]},{"key":"camera","label":"View","type":"select","default":"angled","options":[{"value":"angled","label":"Angled, drifting"},{"value":"front","label":"Straight on"}]},{"key":"seed","label":"Variation","help":"Changes when each module starts.","type":"integer","min":1,"max":9999,"step":1,"default":1}],"presets":[{"id":"default","label":"Now boarding","params":{}},{"id":"airport","label":"Airport yellow","params":{"text1":"DEPARTURES|LISBON  08:45|TOKYO   09:10","text2":"DEPARTURES|LISBON  DELAYED|TOKYO   BOARDING","flapColor":"#141414","textColor":"#ffc93c","align":"left","columns":17}},{"id":"station","label":"Station, white flaps","params":{"text1":"PLATFORM 7|14:32","text2":"PLATFORM 7|ON TIME","flapColor":"#f1f0ec","textColor":"#15161a","camera":"front"}},{"id":"score","label":"Scoreboard","params":{"text1":"HOME  0|AWAY  0","text2":"HOME  1|AWAY  0","flapColor":"#13321f","textColor":"#f4f1e6","changeAt":3.5,"align":"left"}}],"output":{"width":1080,"height":1080,"fps":30,"durationSeconds":9,"posterSeconds":3.6,"alpha":false,"motion":"procedural","loop":{"seamless":false,"method":"Starts blank, spells the first message, then flips to the second and holds."},"seed":{"param":"seed","behavior":"Seed sets the small random delay of each module: same seed, same ripple."}},"composition":{"inputs":"Messages (lines of text) and when each starts. Time in seconds for each frame.","outputs":"A THREE.Group: the board with its housing, centred at the origin and facing +z.","coordinates":"World units: each module is 0.62 wide and 1 tall, 0.7 apart; width and height report the whole board.","lighting":"Standard materials: light it like any scene (one shadow-casting light shows the falling flaps best). The demo adds the studio environment from Chrome Material.","timing":"update(time) is a pure function of time. settledAt tells you when every module has stopped.","compatibleWith":["chrome-material","orbit-camera","stop-motion-feel"],"notes":["Messages are treated as private: not stored in shared packs unless you choose to include them.","Letters are drawn with the system's bold sans-serif (Helvetica or Arial where present); pass fontFamily and load the font first for identical renders.","Each module flips forward through the drum (blank, A–Z, 0–9, punctuation), so letters further along take longer, as on a real board."]},"reuse":["Trip video opener: your destination and date as the first message, \"NOW BOARDING\" as the second.","Score update: two messages that differ by one digit; only that module flips.","In a 3D scene: add board.group to a wall in your own scene and light it with a spotlight."],"integration":{"newProject":"Create a scene with a light, add createSplitFlapBoard({ messages }).group, and call board.update(frame / fps) before each render.","existingProject":"Copy src/split-flap.js. Add the group to your scene, scale or rotate it as you like, and call update(time) every frame."},"performance":{"notes":"One shared texture and a few hundred small meshes; only the flaps that are moving change each frame. Smooth at 1080p on laptop GPUs.","limits":"Best up to about 4 rows of 24 columns. Software WebGL (no GPU) renders slowly with shadows on."},"limitations":["Capital letters, digits and common punctuation only (as on a real board); other characters show as blanks.","No sound: add the clatter in your editor."],"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"}]},"rights":{"approvedForPublicRelease":true},"provenance":"Adapted from the owner's threejs-sketches/mechanical-kinetic/flip-clock (MIT), rebuilt for AI Pixel Wizard in October 2026 as a full split-flap board for your own messages: a character drum per module, gravity-eased flaps with a settling bounce, a left-to-right ripple, a second message, and the frame/time contract.","changelog":[{"version":"1.0.1","date":"2026-10-08","notes":"Instanced meshes are no longer culled using their first-frame bounds, so nothing can vanish when parts move far from where the first frame left them. No visual change."},{"version":"1.0.0","date":"2026-10-05","notes":"Initial release."}],"verification":{"testedOn":"2026-10-08","inputs":{"split-flap@1.0.1":"5f6cbd920a6b681292e4389a364db35b357c99a01401087a8d28e27d8fa11166","three@0.185.1":"664ca387e5fab46ff2daaa6895e1d015426850891af5ea5082cbbcc3985b068c","chrome-material@1.1.0":"ecb41776bfc1ee88997604f916a5ffe833f971d7edcc97c855697a5792d6f1dd","apw-runtime@1.0.0":"5be859cdac74823ba0bcc32c6daf06688a871104d24db5d4ceaffffd84d7c40d"},"environment":"Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0","renderer":"WebGL 2 via SwiftShader (software)","width":1080,"height":1080,"fps":30,"frames":270,"renderSeconds":321.3,"loopCheck":{"checked":false,"seamless":null,"maxDifference":null,"note":"Asset does not claim a seamless loop."},"determinism":{"checked":true,"identical":true},"errors":[],"media":{"poster":"/media/split-flap/1.0.1/poster.webp","preview":"/media/split-flap/1.0.1/preview.mp4","sample":"/media/split-flap/1.0.1/sample.mp4","sampleBytes":729055}},"files":[{"path":"LICENSE","size":1072,"sha256":"8a5f3a96f07e11522ec4bdd0a583356f99bad1245920f9709cee09b995a45153","contentType":"text/plain; charset=utf-8","url":"https://aipixelwizard.com/registry/split-flap/1.0.1/LICENSE"},{"path":"asset.json","size":10163,"sha256":"a3c74fba9c2b2863360a039674161132f9f2b35499c041f6c18435c42f21ade1","contentType":"application/json; charset=utf-8","url":"https://aipixelwizard.com/registry/split-flap/1.0.1/asset.json"},{"path":"demo.js","size":3947,"sha256":"9bf02f4e228ca419b6e40b65047b7f6e38a32b486c3c8444ca845b1c81f038f6","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/split-flap/1.0.1/demo.js"},{"path":"index.html","size":524,"sha256":"429260e642ee7c1172ec8852a12ab7f56a171353996d31e1d1ca0c4ce0b2e03e","contentType":"text/html; charset=utf-8","url":"https://aipixelwizard.com/registry/split-flap/1.0.1/index.html"},{"path":"src/split-flap.js","size":14000,"sha256":"dae97aab6049f55e80abecea74099fbadc4af8b078b06f6ec751c09425db3414","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/split-flap/1.0.1/src/split-flap.js"}],"warnings":[]}