@_lowi/substrate
v0.0.1
Published
A Jared Tarbell's Substate implementation
Readme
Substrate
A modern browser implementation of Jared Tarbell's Substrate algorithm using HTML5 Canvas and Svelte 5.
About
Lines likes crystals grow on a computational substrate. A simple perpendicular growth rule creates intricate city-like structures. — Jared Tarbell
Features
- Canvas-based rendering - High-performance drawing using HTML5 Canvas API
- Obstacle detection - Automatically detects and avoids HTML elements with
.obstacleclass.
Installation
npm install @_lowi/substrateOr with pnpm:
pnpm add @_lowi/substrateUsage
Basic Setup
The simplest way to use Substrate is with the built-in Svelte component:
<script>
import { GlCanvas } from '@_lowi/substrate';
</script>
<div style="width: 100%; height: 100vh;">
<GlCanvas />
</div>Advanced Usage
For more control, you can use the Substrate class directly:
import { Substrate } from '@_lowi/substrate';
import { Polygon, Segment, Vector, point } from '@flatten-js/core';
// Setup canvas
const canvas = document.getElementById('myCanvas') as HTMLCanvasElement;
const dimensions = new Vector(800, 600);
// Define bounds
const topEdge = new Segment(point(0, 0), point(dimensions.x, 0));
const rightEdge = new Segment(point(dimensions.x, 0), point(dimensions.x, dimensions.y));
const bottomEdge = new Segment(point(dimensions.x, dimensions.y), point(0, dimensions.y));
const leftEdge = new Segment(point(0, dimensions.y), point(0, 0));
const bounds = new Polygon([topEdge, rightEdge, bottomEdge, leftEdge]);
// Create substrate instance
const substrate = new Substrate(dimensions, bounds, canvas);
// Animation loop
const loop = async () => {
await substrate.loop();
requestAnimationFrame(loop);
};
// Control playback
substrate.play(); // Start animation
substrate.pause(); // Pause animation
substrate.step(); // Advance one step
substrate.clear(); // Clear canvas
substrate.reset(); // Reset to initial state
loop();Using Obstacles
Add HTML elements with the .obstacle class to create no-grow zones:
<div id="canvas">
<GlCanvas />
</div>
<div id="content" class="obstacle">
<h1>This area will block crack growth</h1>
</div>API
Exports
The library exports the following from @_lowi/substrate:
// Main exports
import {
Substrate, // Main substrate class
GlCanvas, // Svelte component
// Types
type Obstacle,
type Obstacles,
type Intersection,
type BoundaryStartingPoint,
type CrackStartingPoint,
type CrackOptions,
// Color utilities
Pallete, // Color palette enum
pallete, // Color palette function
// Advanced classes
Crack,
RootCrack,
ChildCrack,
Gradient,
Squiggle
} from '@_lowi/substrate';Substrate Class
Constructor
new Substrate(dimensions: Vector, bounds: Polygon, htmlCanvas: HTMLCanvasElement)dimensions- Canvas dimensions as a Vectorbounds- Polygon defining the drawable areahtmlCanvas- HTML canvas element for rendering
Methods
play(): void- Start continuous animationpause(): void- Pause animationstep(): void- Advance one generation stepclear(): void- Clear the canvasreset(): void- Reset to initial state with new crack patternloop(): Promise<void>- Execute one iteration of the growth algorithm
Components
GlCanvas
A ready-to-use Svelte component that handles canvas setup and rendering:
<GlCanvas />How It Works
The Substrate algorithm follows these principles:
- Initialization: Start with a random crack on the canvas
- Growth: Each crack extends perpendicular to nearby obstacles or boundaries
- Intersection Detection: Cracks stop growing when they hit another crack or boundary
- New Cracks: When a crack completes, a new crack spawns at a random point
- Rendering: Gradients fill the regions between cracks, creating organic patterns
Development
Prerequisites
- Node.js 18+
- pnpm (recommended) or npm
Setup
# Clone the repository
git clone https://gitlab.com/lowi/substrate.git
cd substrate
# Install dependencies
pnpm install
# Start dev server
pnpm dev
# Build library
pnpm build
# Check types
pnpm checkCredits
- Original Algorithm: Jared Tarbell
- Implementation: Stephan Lohwasser (@lowi)
License
MIT License - see LICENSE for details
