A Svelte package for visualizing graph pathfinding algorithms with interactive maze generation and solving.
npm install @hayro_o7/labyrinthA Svelte package for visualizing graph pathfinding algorithms with interactive maze generation and solving.
- 🎯 Algorithm Visualization: Step-by-step visualization of Dijkstra's and A* pathfinding algorithms
- 🌀 Maze Generation: Generates perfect mazes using Recursive Backtracking algorithm
- 🎨 Interactive Component: Fully customizable Svelte component with play/pause controls
- 📊 Graph-based: Uses proper graph data structures for efficient pathfinding
- 🔧 TypeScript: Fully typed for excellent developer experience
- âš¡ Configurable: Adjustable maze size, cell size, and animation speed
``bash`
npm install labyrinth
`svelte
`
`svelte
{algorithm}
cellSize={30}
animationSpeed={50}
autoPlay={false}
showGrid={true}
colors={customColors}
onControls={(controls) => (labyrinthControls = controls)}
/>
`
Generates a perfect maze (exactly one path between any two points) using the Recursive Backtracking algorithm.
Parameters:
- width: Number of cells horizontallyheight
- : Number of cells vertically
Returns: A Graph object representing the maze
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| graph | Graph | required | The maze graph to visualize |algorithm
| | 'dijkstra' \| 'astar' | 'astar' | Pathfinding algorithm to use |cellSize
| | number | 30 | Size of each cell in pixels |wallThickness
| | number | 2 | Thickness of walls in pixels |startNode
| | string | '0,0' | Starting node ID (format: "x,y") |endNode
| | string | '{width-1},{height-1}' | Ending node ID (format: "x,y"), auto-computed from graph size |autoPlay
| | boolean | false | Start animation automatically |animationSpeed
| | number | 50 | Delay between steps in milliseconds |showGrid
| | boolean | true | Show grid lines |legend
| | boolean | true | Toggle the legend panel |stepCount
| | boolean | true | Toggle the step counter |colors
| | ColorScheme | default theme | Custom color scheme (see below) |onControls
| | (controls: LabyrinthControls) => void | undefined | Receive imperative control methods |
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| graph | GeneralGraph | required | The graph to visualize |startNode
| | string | first node | Starting node ID |goalNodes
| | string[] | [] | Array of goal node IDs |nodeRadius
| | number | 20 | Radius of nodes in pixels |autoPlay
| | boolean | false | Start animation automatically |animationSpeed
| | number | 100 | Delay between steps in milliseconds |showMultiGoal
| | boolean | false | Enable multi-goal pathfinding with permutation optimization |showNodeIds
| | boolean | true | Display node IDs inside nodes |colors
| | ColorScheme | default theme | Custom color scheme |onControls
| | (controls: LabyrinthControls) => void | undefined | Receive imperative control methods |
#### Dijkstra's Algorithm
- Explores all nodes systematically
- Guarantees shortest path
- Works well for unweighted graphs
- Time complexity: O((V+E) log V)
#### A* Algorithm
- Uses Manhattan distance heuristic
- More efficient than Dijkstra for pathfinding
- Explores fewer nodes by prioritizing promising paths
- Guarantees shortest path with admissible heuristic
`typescript
// Generate a maze
import { generateLabyrinth } from 'labyrinth';
const graph = generateLabyrinth(20, 20);
// Run algorithms programmatically
import { dijkstra, astar } from 'labyrinth';
const result = dijkstra(graph, '0,0', '19,19');
const result2 = astar(graph, '0,0', '19,19');
`
You can customize all colors used in the visualization by passing a colors object:
`typescript
import type { ColorScheme } from 'labyrinth';
const customColors: ColorScheme = {
start: '#10b981', // Start node color
end: '#dc2626', // End node color
current: '#f59e0b', // Current node being explored
visiting: '#fef3c7', // Nodes in the frontier
visited: '#e5e7eb', // Already visited nodes
path: '#8b5cf6', // Final path color
background: '#ffffff', // Cell background
wall: '#374151', // Wall color
grid: '#e5e7eb', // Grid line color
legend: '#f3f4f6', // Legend background
legendtext: '#1f2937', // Legend text color
buttons: '#0ea5e9', // Button background
buttonshover: '#0284c7', // Button hover background
buttonsdisabled: '#94a3b8', // Disabled button background
buttonstext: '#ffffff' // Button text color
};
`
All color properties are optional - only specify the ones you want to override.
You can access imperative controls (play/pause/reset/step) by providing onControls:
`svelte
$3
`typescript
interface Graph {
nodes: Map;
width: number;
height: number;
}interface GraphNode {
id: string;
x: number;
y: number;
neighbors: string[];
}
interface AlgorithmResult {
path: string[];
steps: PathStep[];
found: boolean;
}
interface PathStep {
nodeId: string;
type: 'visiting' | 'visited' | 'path' | 'current';
distance?: number;
heuristic?: number;
fScore?: number;
}
interface ColorScheme {
start?: string;
end?: string;
current?: string;
visiting?: string;
visited?: string;
path?: string;
background?: string;
wall?: string;
grid?: string;
legend?: string;
legendtext?: string;
buttons?: string;
buttonshover?: string;
buttonsdisabled?: string;
buttonstext?: string;
}
interface LabyrinthControls {
play: () => void;
pause: () => void;
reset: () => void;
stepForward: () => void;
stepBackward: () => void;
}
`Development
`bash
Install dependencies
npm installStart dev server with demo
npm run devBuild the package
npm run packageType check
npm run check
``This guarantees a maze with exactly one path between any two points.
MIT
Contributions are welcome! Please feel free to submit a Pull Request.