Hundreds 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
Preset

Installation

pnpm dlx shadcn@latest add https://kagadmodyaa.vercel.app/r/stream-lines.json

Needs 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/effects
import { 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

  • Silk
  • Tide
  • Ink
  • Spectrum
  • Ember

Props

NameTypeDefaultDescription
preset'Silk' | 'Tide' | 'Ink' | 'Spectrum' | 'Ember'none (the defaults below)A named theme. Any prop you pass as well overrides the preset’s value.
linesnumber80How many lines cross the stage height in the calm part of the current. Range 40 to 420.
lineWidthnumber0.8Width in CSS pixels; below one pixel a line stays crisp and just gets fainter. Range 0.3 to 3 px.
depthFadenumber0.55How much the far threads fade into haze and the picture dims with distance. Range 0 to 1.
currentnumber0.50 draws every line radially into the focus, 1 is a steady current across the stage. Range 0 to 1.
convergencenumber0.75How strongly the focus pulls: the share of the current it swallows; the rest bends around it. Range 0 to 1.
swirlnumber0.5How far the lines turn as they approach the focus. Range -2 to 2.
anglenumber00 flows to the right, 90 upwards, -90 downwards. Range -180 to 180 °.
curvaturenumber0.55How much the lines wave and bunch as they travel. Range 0 to 1.
speednumber1How fast the current and its pulses travel. 0 freezes the stage. Range 0 to 2.5.
pulsenumber0.6Light pulses travelling along the lines; 0 draws steady lines. Range 0 to 1.
focalXnumber0.68Horizontal position of the focus, 0 (left) to 1 (right). Range 0 to 1.
focalYnumber0.5Vertical position of the focus, 0 (bottom) to 1 (top). Range 0 to 1.
glownumber0.8Light gathered at the focus. Range 0 to 1.5.
pointerPullnumber0.7How far the pointer bends the lines toward it, like a second focus. 0 ignores the pointer. Range 0 to 1.
colorFromstring'#fff3d6'Colour of the lines on one side of the picture, and of the glow. A hex colour.
colorTostring'#f1b560'Colour of the lines on the other side. A hex colour.
backgroundstring'#09080b'Page colour; a light colour switches to dark ink on paper. A hex colour.
spectrumnumber0A rainbow across the lines, on top of the two colours. Range 0 to 1.
grainnumber0.3Film grain. Range 0 to 1.
classNamestring—Extra class on the root element. The effect fills its parent: give the parent a height.
styleCSSProperties—Inline style on the root element.

Files

What the command adds to your project, and where.

  • components/effects/stream-lines/stream-lines.tsx

    The component.

  • components/effects/stream-lines/lines.tsx

    The component.

  • components/effects/stream-lines/showcase.tsx

    The component.

  • components/effects/stream-lines/poster.tsx

    The component.

  • components/effects/stream-lines/look.ts

    The component.

  • components/effects/stream-lines/shaders.ts

    The fragment shader, as a string. Edit it to change the picture.

  • lib/effect-runtime.ts

    Shared 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.

See all effects