@sprig-and-prose/sprig-texture
v0.1.0
Published
Procedurally generated, calm background textures
Readme
sprig-texture
Procedurally generated, calm, parasympathetic background textures for use across projects.
Purpose
This library generates seamless, tiling textures designed to:
- Eliminate gradient banding and grid artifacts
- Provide subtle "paper / watercolor surface" material
- Create calm, non-distracting backgrounds
- Be deterministic (same key = same texture)
Important: This library generates neutral material textures. Lighting, vignettes, and mood gradients belong in CSS, not in the texture bitmap.
Usage
import { generateTexture, releaseObjectUrl, nightInk, bloom } from 'sprig-texture';
const { canvas, blob, url } = await generateTexture({
key: 'my-unique-key',
palette: nightInk,
preset: bloom,
});
// Use the URL as a background image
element.style.backgroundImage = `url(${url})`;
element.style.backgroundRepeat = 'repeat';
element.style.backgroundSize = '1024px 1024px';
// Clean up when done (prevents memory leaks)
releaseObjectUrl(url);Determinism
Textures are deterministic: the same key + palette + preset will always produce the same texture. This allows caching and consistent rendering across sessions.
Palettes
- nightInk: Dark blue-gray tones (default)
- parchment: Warm paper tones
Presets
- quiet: Minimal variation, subtle
- bloom: Slightly richer, more variation (default)
Watercolor Stroke CSS
This package includes a reusable CSS module for creating watercolor brush stroke effects, perfect for highlighting keywords, badges, or decorative elements.
Importing the CSS
/* In your CSS file */
@import 'sprig-texture/src/styles/watercolor-stroke.css';Or in JavaScript/TypeScript (if your bundler supports CSS imports):
import 'sprig-texture/src/styles/watercolor-stroke.css';Basic Usage
Apply the .watercolor-stroke class to an element and set CSS variables for color and opacity:
<span class="watercolor-stroke" style="--watercolor-pigment-color: rgba(50, 80, 160, 1); --watercolor-opacity: 0.30;">
COLLECTS
</span>The effect is applied via a ::before pseudo-element, so ensure your element has position: relative:
.my-badge {
position: relative;
display: inline-block;
padding: 0.1rem 0.45rem;
}Using Pre-configured Variants
The CSS includes several pre-configured color variants that you can use via data attributes:
<span class="watercolor-stroke" data-variant="collects">COLLECTS</span>
<span class="watercolor-stroke" data-variant="expands">EXPANDS</span>
<span class="watercolor-stroke" data-variant="optional">OPTIONAL</span>
<span class="watercolor-stroke" data-variant="aggregates">AGGREGATES</span>Customizing Colors
Override the CSS variables to use your own colors:
.custom-stroke {
--watercolor-pigment-color: rgba(120, 60, 200, 1);
--watercolor-opacity: 0.35;
}Adjusting Stroke Position
The stroke position is controlled by four CSS properties on the ::before pseudo-element. To adjust the position, override these values:
.my-element::before {
top: -1.2rem; /* move stroke DOWN = make this LESS negative */
bottom: -0.54rem; /* move stroke UP = make this MORE negative */
left: -0.80rem;
right: -0.80rem;
}How It Works
The watercolor effect is created using:
- Radial gradients for the pigment color distribution
- Clip-path polygon for the wavy brush stroke shape
- Blur filter for soft edges
- Mix-blend-mode: screen for the watercolor blending effect
- Subtle transforms (rotate, skew) for natural variation
Design Principles
- Texture ≠ lighting: The generated bitmap is neutral material; CSS handles mood
- Micro-variation prevents banding: Multi-scale noise (low, mid, high frequency)
- Subtlety over effect: Everything should be "barely there"
- Forgiving defaults:
generateTexture({ key })should look good
Layers
The texture is generated in 5 layers:
- Base fill: Palette-driven base color
- Ultra-low-frequency tone drift: Very large radial washes to prevent flat regions
- Mid-frequency mottling: Soft radial blobs for material variation
- Paper grain / speckles: Soft dots for texture and anti-banding
- Fiber strokes: Thin strokes with vertical bias
All layers tile seamlessly.
API
generateTexture(args)
Generates a texture and returns a Promise resolving to { canvas, blob, url }.
args.key(string, required): Deterministic seed keyargs.size(number, optional, default: 1024): Canvas size (square)args.palette(Palette, optional): Color palette (default:nightInk)args.preset(Preset, optional): Numeric parameters (default:bloom)
releaseObjectUrl(url)
Releases an object URL created by generateTexture(). Call this when you're done using the texture to prevent memory leaks in long-running sessions.
Examples
See examples/demo.html for a working demo with controls.
To run the demo, start a local server:
npm run serveThen open http://localhost:3000/examples/demo.html in your browser.
Alternatively, you can use any static file server:
npx serve .(if you haveserveinstalled)python3 -m http.server 8000(Python 3)- Or any other static file server
