Balloon Zinnia
Twenty-two egg-shaped petals hinge around a small throat and sit on a short S-curved stem. A 512-wide ramp stripes both of them, and one 14 second clock keeps the sway, the breath, the colour flow and the band pulse in step. The pointer turns the head and swells the petals under it. A tap bobs the flower and squashes it. Raw WebGL2, no extra libraries.
npx shadcn@latest add @compronents/balloon-zinniaInstalls from ui.aryank.space. Needs a registry token and a one-time @compronents entry in components.json. The docs walk through both.
| Prop | Type | Default | Description |
|---|---|---|---|
| background | string | "#000000" | Colour behind the flower. The canvas clears transparent so this shows through. |
| colors | { color: string; width: number }[] | 13 stops, green through pink, navy and blue, back to a pale ground | The colour loop the bands run through, in order. Width is that stop's share of the loop. The last colour blends back into the first. Fewer than two stops keeps the base ramp. |
| petals | number | 22 | Petals in the outer ring. Clamped to 6..24. |
| stem | { show: boolean; curve: number; thickness: number } | { show: true, curve: 100, thickness: 100 } | Whether the stem is drawn, how deep its S-bends are, and its thickness. Curve and thickness are percents. 0 curve is a straight stem. |
| petalLength / petalWidth / puff | number | 200 / 100 / 134 | Length from the throat, width across the ring, and how fat the petals are blown. All percents. |
| bands / grain / scale | number | 5 / 0 / 100 | Colour bands across the flower, film grain amplitude, and the flower's size in the frame. Grain 0 is off. Scale is a percent. |
| placement | { x: number; y: number; angle: number; tilt: number } | { x: 0, y: 0, angle: 0, tilt: 0 } | Offset in percent of the frame, then a roll and a tilt in degrees. Positive x is right. |
| entrance | { animate: boolean; delay: number; stagger: number } | { animate: false, delay: 0, stagger: 5 } | Inflates the petals in turn when animate is on. Delay is seconds. Stagger is a 0..10 dial. Off, the flower appears full. |
| response | { reach: number; swell: number; follow: number; bounce: number } | 5 / 5 / 5 / 5 | How far the head leans, how much nearby petals swell, how quickly the head follows the pointer, and how hard a tap bobs it. Each is a 0..10 dial. |
| motion | { sway: number; breathe: number; speed: number; flow: number; pulse: number } | 5 / 5 / 5 / 5 / 5 | Idle sway, petal breath, clock speed, colour flow and band pulse. Each is a 0..10 dial. Speed 0 holds the picture. |
| advanced | AdvancedSettings | lean 48, bandAxis 48, lens 12, cup 25, twist 0, ribs 10, swayYaw 29, breatheAngle 35, nodAngle 0, swayPeriod 14, pulseDepth 36, phase 60, bloomTime 0.9, followEase 0.3 | The silhouette and the timing that the base preset was tuned with. swayPeriod is the loop length in seconds. |
| className / style | string / CSSProperties | — | The root fills its parent. With no height of its own it keeps a 720 / 1280 box. A parent with both axes set, such as the demo's 600px stage, ignores that ratio. |
backgroundcolorColour behind the canvas. The canvas itself clears transparent.
petalssliderPetals in the outer ring, from 6 to 24. The base preset uses 22.
puffsliderHow fat each petal is blown, as a percent. 134 is the base preset.
bandssliderHow many colour bands span the flower. 5 matches the base preset. Each step of 2.5 doubles them.
scalesliderSize of the flower in the frame, as a percent. 100 is the base framing.
grainsliderFilm grain over the flower, one grain per CSS pixel. 0 leaves the background clean.
motiontupleSway, breathe, speed, flow and pulse, each on a 0 to 10 dial. 5 is the base preset. Speed 0 holds the clock.
responsetupleReach, swell, follow and bounce, each on a 0 to 10 dial. Follow turns the head toward the pointer. Bounce is the tap.