The module writes keyframes.
It runs once in the editor and outputs ordinary SVGator keys. Zero runtime, so it works in every export: SVG, CSS, Lottie, video, GIF.
2,356 round-capped strokes. A spring-cloth solver moves them, light is nothing but stroke colour, and it runs in a browser tab with no WebGL, no canvas and no libraries.
SVGator owns the timeline. A module owns the physics inside one layer. You keyframe its parameters like any other property, and it renders as a pure function of the playhead, so scrubbing, looping and export keep working.
Labels, timeline ticks, orbit rings and the module layer's own scale and fade are SVGator keyframes, built through the SVGator MCP and exported with the stock JS player.
Inside it, halo@1 draws 1,500 strokes. Its mode track, idle to supernova, is a list of keyframes on the same timeline.
The keyframe event hands the module the playhead in milliseconds, seekTo scrubs. Nothing in SVGator was patched.
The module is deterministic. Drag the scrubber backwards and every stroke lands exactly where it was, so loops, previews and video renders stay exact.
It runs once in the editor and outputs ordinary SVGator keys. Zero runtime, so it works in every export: SVG, CSS, Lottie, video, GIF.
For motion no keyframe list can hold: cloth, fluids, flocking, thousands of particles. It runs next to SVGator's player and follows its clock.
Three physics presets on two AI icons. A spring solver ran offline, its curves were fitted into SVGator bezier keys and pushed through the SVGator MCP. What ships is a plain SVGator export, every loop seamless. In the editor this would be one click.
A module shows up as a layer with its own parameters. Anything marked keyframable gets a track on the timeline. Click a keyframe on the mode track to see the layer change.
// halo.module.js: everything an editor needs from a module export default { name: 'halo', version: 1, params: { strokes: { type: 'int', default: 1500, min: 200, max: 4000 }, seed: { type: 'int', default: 7 }, mode: { type: 'enum', keyframes: true, values: ['idle', 'water', 'silk', 'nova'] }, }, mount(layer, p) { return Halo.mount(layer, p) }, // draws only in its layer render(h, ms, p) { h.seek(ms / 1000, p.mode) }, // pure function of time bake(h, ms) { return h.keyframes(ms) }, // optional: Path 01 };
// the glue running on this page today, // on SVGator's public Player API const player = svg.svgatorPlayer; const halo = HaloModule.mount(slot, { seed: 7 }); player.on('keyframe', ms => halo.seek(ms / 1000)); scrub.oninput = () => player.seekTo(+scrub.value); // slot = the empty layer drawn in SVGator, // found in the export by its marker
Keyframes are perfect for design intent and painful for physics. Modules keep the first and hand the second to code, without leaving SVGator.
Physics, generative and data presets published as modules. Creators ship them once, everyone keyframes them.
Modules are deterministic, so preview, scrubbing, loop seams and video renders stay exact. Bake keeps Lottie and CSS exports working.
A module declares its parameters, draws only inside its own layer and never touches the rest of the document.
The live path on this page uses only the shipped Player API. The bake path uses the SVGator MCP. The rest is an editor panel.
Prototype. SVGator does not support modules today. Everything on this page runs on SVGator's existing export, Player API and MCP.
One sphere, six product states. Typing sends tiny ripples, thinking folds the surface, speaking pulses from the front, a good answer goes supernova and a failed one collapses into a black hole before it reforms.
A path segment with no length and a round cap paints a perfect dot. Give it length and the same dot becomes a motion streak. Width is depth, colour is light.
Latitude rows on a unit sphere, each point tied to its 6 nearest neighbours. Rows read like woven fabric the moment they bend.
Silk bands, ripple packets on great circles, warped ridged noise, Kepler-like orbits for the accretion disk. Each mode only sets a target shape.
Every point springs to its target (k 30) and to its neighbours like cloth (k 55), with damping 3.6. Two substeps per frame, so modes blend and nothing ever pops.
Normals come from the gradient of the height field. Diffuse, rim and a tight specular are folded into one stroke colour per dot.
Dots are bucketed by colour and width into about 200 paths. One d string per path per frame keeps thousands of strokes at 60 fps.
The engine is one dependency-free script. Mount it on any empty SVG, then drive it from your product state.
<svg id="halo"></svg> <script src="halo.js"></script> <script> const halo = Halo.mount('#halo', { strokes: 1500 }); halo.set('thinking'); // idle · listening · thinking · speaking · success · error halo.touch(0.2, -0.3); // ripple at a point on the face </script>