Stream Lines
NewFreeHundreds of fine luminous threads flowing like a current and converging on a focal point, bending around it like field lines, with light pulses travelling along them.
- shader
- webgl
- lines
- flow
- background
- hero
Installation
pnpm dlx shadcn@latest add https://kagadmodyaa.vercel.app/r/stream-lines.jsonNeeds a React + Tailwind project set up with shadcn. Copies the effect into your project, along with lib/effect-runtime.ts, the small WebGL layer it runs on. No other dependencies.
Or from npm
pnpm add @kagadmodyaa/effectsimport { StreamLines } from '@kagadmodyaa/effects/stream-lines'One package with every free effect, one import path each. No Tailwind or shadcn needed, and no stylesheet to import: the few layout rules an effect needs come with it. The npm package and the command above ship the same source.
Usage
Use it like any other component. Choose a theme with preset; any prop you pass as well overrides the preset.
import { StreamLines } from '@/components/effects/stream-lines/stream-lines'
export function Hero() {
return (
<section className="relative h-[640px] overflow-hidden">
{/* fills its parent; the left of the stage is the calm upstream part of the current, good for a headline */}
<StreamLines preset="Silk" focalX={0.7} className="absolute inset-0" />
<div className="relative z-10 mx-auto max-w-xl px-6 pt-28 text-center text-white">
<h1 className="text-5xl font-semibold tracking-tight">Everything, drawn to one point.</h1>
</div>
</section>
)
}
// Presets: Silk, Tide, Ink (the light one: dark ink on paper, use dark text), Spectrum, Ember.
// The stage above is <StreamLinesShowcase />, also exported, with a headline and a "Send a pulse" button
// that calls ref.current.pulse() to send a bright front along every line.<StreamLines preset="Tide" lines={80} />Presets
SilkTideInkSpectrumEmber
Props
| Name | Type | Default | Description |
|---|---|---|---|
| preset | 'Silk' | 'Tide' | 'Ink' | 'Spectrum' | 'Ember' | none (the defaults below) | A named theme. Any prop you pass as well overrides the preset’s value. |
| lines | number | 80 | How many lines cross the stage height in the calm part of the current. Range 40 to 420. |
| lineWidth | number | 0.8 | Width in CSS pixels; below one pixel a line stays crisp and just gets fainter. Range 0.3 to 3 px. |
| depthFade | number | 0.55 | How much the far threads fade into haze and the picture dims with distance. Range 0 to 1. |
| current | number | 0.5 | 0 draws every line radially into the focus, 1 is a steady current across the stage. Range 0 to 1. |
| convergence | number | 0.75 | How strongly the focus pulls: the share of the current it swallows; the rest bends around it. Range 0 to 1. |
| swirl | number | 0.5 | How far the lines turn as they approach the focus. Range -2 to 2. |
| angle | number | 0 | 0 flows to the right, 90 upwards, -90 downwards. Range -180 to 180 °. |
| curvature | number | 0.55 | How much the lines wave and bunch as they travel. Range 0 to 1. |
| speed | number | 1 | How fast the current and its pulses travel. 0 freezes the stage. Range 0 to 2.5. |
| pulse | number | 0.6 | Light pulses travelling along the lines; 0 draws steady lines. Range 0 to 1. |
| focalX | number | 0.68 | Horizontal position of the focus, 0 (left) to 1 (right). Range 0 to 1. |
| focalY | number | 0.5 | Vertical position of the focus, 0 (bottom) to 1 (top). Range 0 to 1. |
| glow | number | 0.8 | Light gathered at the focus. Range 0 to 1.5. |
| pointerPull | number | 0.7 | How far the pointer bends the lines toward it, like a second focus. 0 ignores the pointer. Range 0 to 1. |
| colorFrom | string | '#fff3d6' | Colour of the lines on one side of the picture, and of the glow. A hex colour. |
| colorTo | string | '#f1b560' | Colour of the lines on the other side. A hex colour. |
| background | string | '#09080b' | Page colour; a light colour switches to dark ink on paper. A hex colour. |
| spectrum | number | 0 | A rainbow across the lines, on top of the two colours. Range 0 to 1. |
| grain | number | 0.3 | Film grain. Range 0 to 1. |
| className | string | — | Extra class on the root element. The effect fills its parent: give the parent a height. |
| style | CSSProperties | — | Inline style on the root element. |
Files
What the command adds to your project, and where.
components/effects/stream-lines/stream-lines.tsxThe component.
components/effects/stream-lines/lines.tsxThe component.
components/effects/stream-lines/showcase.tsxThe component.
components/effects/stream-lines/poster.tsxThe component.
components/effects/stream-lines/look.tsThe component.
components/effects/stream-lines/shaders.tsThe fragment shader, as a string. Edit it to change the picture.
lib/effect-runtime.tsShared by every shader effect: resizing, pausing, reduced motion, context loss and the no-WebGL fallback. Installed once.
Behaviour
- The lines are contours of a flow: a calm current, a focus that swallows part of it (the rest bends around it like field lines) and an optional swirl. Light pulses travel along the lines toward the focus; set pulse amount to 0 for steady lines, flow speed to 0 to freeze everything.
- Move the pointer over the page and it acts as a second, softer focus: the lines bend and gather toward it and the focus leans a little. Click anywhere on the stage (or press the button) to send a brighter pulse along every line into the focus. Set pointer pull to 0 to ignore the pointer.
- Three depth layers share the flow: near threads are thicker, brighter and a little softer, far ones are thinner and fade into haze, and they shift slightly against each other as the pointer moves. Depth fade sets how strong that is.
- Lines are drawn analytically, so they are crisp at any resolution and never shimmer: as lines get closer together than a pixel they melt into a smooth glow instead of moire. Dark looks use light on a dark page; Ink is dark graphite on warm paper for light pages.
- It fills its parent and pauses off screen and in a background tab, lowers its resolution automatically if frames run slow, and draws one composed still frame under prefers-reduced-motion. Without WebGL, and before the first frame, you see a poster of curved lines converging on a glow, in the same colours.