{"id":"ripple-pond","version":"1.0.0","title":"Ripple Pond","summary":"Raindrops landing on a still pond from above: thin rings spread, cross and fade while lily pads rock. Loops perfectly.","kind":"background","target":"canvas2d","collections":["backgrounds","hypnotic-loops","satisfying"],"tags":["ripples","pond","water","raindrops","lily pads","calm","meditation","rings","nature","loop"],"loopable":true,"motion":"procedural","durationSeconds":12,"status":"published","media":{"poster":"https://aipixelwizard.com/media/ripple-pond/1.0.0/poster.webp","preview":"https://aipixelwizard.com/media/ripple-pond/1.0.0/preview.mp4","sample":"https://aipixelwizard.com/media/ripple-pond/1.0.0/sample.mp4","sampleBytes":1038042,"sampleNote":"Pre-rendered with the default settings. Customised settings must be exported locally (npm run render)."},"urls":{"page":"https://aipixelwizard.com/visuals/ripple-pond","manifest":"https://aipixelwizard.com/api/v1/visuals/ripple-pond/versions/1.0.0","agentMd":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/agent.md","files":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/","demo":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/index.html"},"description":"Raindrops on a still pond seen from above. Drops land at seeded places at fixed moments of the loop; each sends out a set of thin circular ripples that widen, thin and fade, and where rings from different drops cross they pass through each other cleanly. A soft sky reflection tints the water, and lily pads, some with a flower, sit on the surface and rock slightly when a ripple reaches them. Each drop repeats once per loop, so the loop is exact. Choose the number of drops, the colours (twilight, morning, koi or night), the number of lily pads and the seed.","role":"Background (Canvas 2D): a calm, meditative water scene.","useCases":["A meditation, sleep or wellness backdrop","A calm looping background behind text","A water or rain atmosphere"],"synonyms":["water ripples","rain on a pond","raindrop ripples","pond surface","koi pond","water rings"],"digest":"cb2676a2321fe8fa130b4d69e25cc6e65e6a7487302225ba5e4780183984c844","implementation":{"target":"canvas2d","runtime":"browser","language":"javascript","module":"esm","entry":"src/ripple-pond.js","exports":[{"name":"createRipplePond","signature":"createRipplePond({ drops?, palette?, pads?, seed? }) => { draw(ctx, info, width, height) }","description":"Canvas 2D scene; info.progress (0 to 1 over the loop) sets the place in the loop; it fills the canvas."},{"name":"PALETTES","signature":"PALETTES: { twilight, morning, koi, night }","description":"Water, ripple and lily-pad colours."}],"reusable":["src/ripple-pond.js"],"demo":"demo.js","harness":"index.html"},"dependencies":[{"id":"apw-runtime","version":"1.0.0","scope":"demo","reason":"Demo harness. The reusable source has no dependencies."}],"uses":[],"usedBy":[],"params":[{"key":"drops","label":"Drops per loop","type":"integer","min":3,"max":24,"step":1,"default":9},{"key":"palette","label":"Colours","type":"select","default":"twilight","options":[{"value":"twilight","label":"Twilight"},{"value":"morning","label":"Morning"},{"value":"koi","label":"Koi pond"},{"value":"night","label":"Night"}]},{"key":"pads","label":"Lily pads","type":"integer","min":0,"max":8,"step":1,"default":4},{"key":"seed","label":"Seed","type":"integer","min":1,"max":999,"step":1,"default":5}],"presets":[{"id":"default","label":"Twilight pond","params":{}},{"id":"morning","label":"Morning, light rain","params":{"palette":"morning","drops":6,"pads":6,"seed":11}},{"id":"koi","label":"Koi pond, heavy rain","params":{"palette":"koi","drops":22,"pads":3,"seed":2}},{"id":"night","label":"Night, no pads","params":{"palette":"night","pads":0,"seed":7}}],"output":{"width":1080,"height":1080,"fps":30,"durationSeconds":12,"posterSeconds":3,"alpha":false,"motion":"procedural","loop":{"seamless":true,"cycleSeconds":12,"method":"Each drop's ripples are a function of the time since it landed, wrapping round the loop, and the pads rock in whole cycles, so the last frame meets the first."},"seed":{"param":"seed","behavior":"Seed places the drops and lily pads: same seed, same pond."}},"composition":{"inputs":"Canvas 2D context, info.progress (0 to 1 over the loop), width, height.","outputs":"Fills the whole canvas.","coordinates":"Drops and pads are placed in fractions of the canvas; ripple reach and pad size scale with the smaller side.","lighting":"A soft radial water colour with a faint sheen; pads cast a soft shadow.","timing":"Pure function of info.progress.","compatibleWith":["kinetic-title","gradient-background"],"notes":["Ripples are drawn as thin rings with a wider faint ring behind each, which reads as a glint."]},"reuse":["Sleep video: Twilight pond.","Calm morning: Morning, light rain.","Storm mood: Koi pond, heavy rain."],"integration":{"newProject":"Create it once, then each frame draw your backdrop and call draw(ctx, { progress }, width, height).","existingProject":"Copy src/ripple-pond.js. Call draw on your existing 2D canvas."},"performance":{"notes":"At most about 100 rings per frame; a few milliseconds.","limits":"Many overlapping drops draw more rings."},"limitations":["Ripples do not reflect off the edges or interfere; rings cross without changing.","The water has no depth or refraction."],"license":{"spdx":"MIT","notice":"Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.","thirdParty":[]},"rights":{"approvedForPublicRelease":true},"provenance":"Original code written for AI Pixel Wizard in October 2026, to the catalog quality bar (docs/QUALITY.md).","changelog":[{"version":"1.0.0","date":"2026-10-08","notes":"Initial release."}],"verification":{"testedOn":"2026-10-08","inputs":{"ripple-pond@1.0.0":"cb2676a2321fe8fa130b4d69e25cc6e65e6a7487302225ba5e4780183984c844","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":"Canvas 2D","width":1080,"height":1080,"fps":30,"frames":360,"renderSeconds":61.6,"loopCheck":{"checked":true,"seamless":true,"maxDifference":0,"note":"Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255."},"determinism":{"checked":true,"identical":true},"errors":[],"media":{"poster":"/media/ripple-pond/1.0.0/poster.webp","preview":"/media/ripple-pond/1.0.0/preview.mp4","sample":"/media/ripple-pond/1.0.0/sample.mp4","sampleBytes":1038042}},"files":[{"path":"LICENSE","size":1072,"sha256":"8a5f3a96f07e11522ec4bdd0a583356f99bad1245920f9709cee09b995a45153","contentType":"text/plain; charset=utf-8","url":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/LICENSE"},{"path":"asset.json","size":6302,"sha256":"6184ee051c96d2db4e1d1d235d7f827deb5f84c28a927d176cd90ee7839a6d3f","contentType":"application/json; charset=utf-8","url":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/asset.json"},{"path":"demo.js","size":482,"sha256":"cddd780fff8f72fe0b4833e64ca6ef8c326d8263907f82e259c8780a23b5d9e8","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/demo.js"},{"path":"index.html","size":525,"sha256":"e2aef9b51359609778c7c509c8d5e08ca5505ac0843a7f5d2c1773ef384cc10c","contentType":"text/html; charset=utf-8","url":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/index.html"},{"path":"src/ripple-pond.js","size":5914,"sha256":"9acc63a84aa2166e7242fe11ad08dde727b403dd2174cc0d5f6474209c6f9734","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/ripple-pond/1.0.0/src/ripple-pond.js"}],"warnings":[]}