git-hash-art 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ # Product: git-hash-art
2
+
3
+ A cross-platform library that generates deterministic abstract art from git commit hashes. Given a hex hash string, it produces a unique image using layered geometric shapes, sacred geometry patterns, and harmonious color schemes. Works in both Node.js and browser environments.
4
+
5
+ Key capabilities:
6
+ - Deterministic output: same hash always produces the same image
7
+ - Configurable canvas size, grid density, layers, shape sizes, and opacity
8
+ - Built-in presets for social media (Instagram, Twitter, LinkedIn), device wallpapers, and print sizes
9
+ - CLI for generating art from the current commit or a specific hash
10
+ - Cross-platform: Node.js (via `@napi-rs/canvas`) and browsers (native Canvas 2D API)
11
+
12
+ ## Public API
13
+
14
+ - Node entry (`git-hash-art`): `generateImageFromHash` (returns PNG Buffer), `saveImageToFile`, `renderHashArt`
15
+ - Browser entry (`git-hash-art/browser`): `renderToCanvas`, `generateImageBlob`, `generateDataURL`, `renderHashArt`
16
+ - Both re-export `PRESETS`, `DEFAULT_CONFIG`, and the `GenerationConfig` type
@@ -0,0 +1,40 @@
1
+ # Project Structure
2
+
3
+ ```
4
+ src/
5
+ index.ts # Node.js entry: generateImageFromHash, saveImageToFile, re-exports renderHashArt
6
+ browser.ts # Browser entry: renderToCanvas, generateImageBlob, generateDataURL, re-exports renderHashArt
7
+ types.ts # Shared GenerationConfig interface and DEFAULT_CONFIG
8
+ __tests__/ # Vitest test files (*.test.ts)
9
+ lib/
10
+ render.ts # Pure rendering logic (environment-agnostic) — renderHashArt()
11
+ utils.ts # Hash-to-seed conversion, deterministic RNG, PatternCombiner
12
+ constants.ts # PRESETS, default shape config, proportions, pattern presets
13
+ canvas/
14
+ colors.ts # Color scheme generation (generateColorScheme, SacredColorScheme class)
15
+ draw.ts # Shape drawing and enhancement (drawShape, enhanceShapeGeneration)
16
+ shapes/
17
+ index.ts # Aggregates and re-exports all shape draw functions
18
+ basic.ts # Circle, square, triangle, hexagon, star
19
+ complex.ts # Platonic solids, fibonacci, golden ratio shapes
20
+ sacred.ts # Flower of life, tree of life, Metatron's cube, Sri Yantra
21
+ utils.ts # Geometry helpers (transforms, degree conversion)
22
+ bin/
23
+ generateExamples.js # Script to generate example images from PRESETS
24
+ examples/ # Generated example PNGs (gitignored)
25
+ ```
26
+
27
+ ## Architecture
28
+
29
+ - `src/lib/render.ts` contains the pure rendering core (`renderHashArt`) that only uses the standard `CanvasRenderingContext2D` API — no Node or browser dependencies
30
+ - `src/index.ts` is the Node entry point — wraps `renderHashArt` with `@napi-rs/canvas` for PNG buffer output and `fs` for file saving
31
+ - `src/browser.ts` is the browser entry point — wraps `renderHashArt` with `HTMLCanvasElement`/`OffscreenCanvas` helpers
32
+ - `@napi-rs/canvas` is an optional peer dependency, only required for Node.js usage
33
+
34
+ ## Conventions
35
+
36
+ - Shape draw functions follow the `DrawFunction` signature: `(ctx: CanvasRenderingContext2D, size: number, config?: any) => void`
37
+ - Shapes are grouped by category (basic, complex, sacred) and merged via the barrel `shapes/index.ts`
38
+ - All randomness is derived deterministically from the git hash via `getRandomFromHash` — never use `Math.random()`
39
+ - Tests live in `src/__tests__/` and use Vitest (`describe`/`it`/`expect`)
40
+ - The `examples/` directory is gitignored; regenerate with `yarn build:examples`
@@ -0,0 +1,24 @@
1
+ # Tech Stack
2
+
3
+ - Language: TypeScript (strict mode, ES2020 target)
4
+ - Runtime: Node.js and browsers
5
+ - Canvas (Node): `@napi-rs/canvas` (optional peer dependency)
6
+ - Canvas (Browser): native Canvas 2D API / OffscreenCanvas
7
+ - Color generation: `color-scheme` (declared in `global.d.ts` since it lacks types)
8
+ - Bundler: Parcel (outputs CJS `dist/main.js`, ESM `dist/module.js`, browser `dist/browser.js`, types `dist/types.d.ts`)
9
+ - Test framework: Vitest
10
+ - Formatter: Prettier
11
+ - Release: release-it
12
+ - Package manager: Yarn
13
+
14
+ ## Common Commands
15
+
16
+ | Command | Purpose |
17
+ |---|---|
18
+ | `yarn build` | Production build (clears `.parcel-cache` first via `prebuild`) |
19
+ | `yarn watch` | Dev build with file watching |
20
+ | `npx vitest --run` | Run tests once |
21
+ | `yarn format` | Format source files with Prettier |
22
+ | `yarn format:check` | Check formatting without writing |
23
+ | `yarn build:examples` | Generate example images via `bin/generateExamples.js` |
24
+ | `yarn test:publish` | Dry-run npm publish |
package/ALGORITHM.md ADDED
@@ -0,0 +1,198 @@
1
+ # Art Generation Algorithm
2
+
3
+ This document describes the deterministic art generation pipeline used by `git-hash-art`. Every step derives its randomness from the input hash via a seeded mulberry32 PRNG, guaranteeing identical output for identical input.
4
+
5
+ ## Pipeline Overview
6
+
7
+ ```
8
+ Hash String
9
+
10
+ ├─► Seed (mulberry32 PRNG)
11
+
12
+ ├─► Color Scheme (analogic + complementary + triadic palettes)
13
+
14
+ └─► Rendering Pipeline
15
+
16
+ 1. Background Layer
17
+ 2. Composition Mode Selection
18
+ 3. Focal Point Generation
19
+ 4. Flow Field Initialization
20
+ 5. Shape Layers (× N layers)
21
+ │ ├─ Position (composition mode + focal bias)
22
+ │ ├─ Shape Selection (layer-weighted)
23
+ │ ├─ Styling (transparency, glow, gradients, color jitter)
24
+ │ └─ Recursive Nesting (~15% of large shapes)
25
+ 6. Flow-Line Pass
26
+ 7. Noise Texture Overlay
27
+ 8. Organic Connecting Curves
28
+ ```
29
+
30
+ ## 1. Deterministic RNG
31
+
32
+ All randomness flows from a single **mulberry32** PRNG seeded by hashing the full input string:
33
+
34
+ ```
35
+ seed = hash(gitHash) → mulberry32 state
36
+ rng() → float in [0, 1)
37
+ ```
38
+
39
+ The old approach extracted 2-char hex pairs from the hash (only ~20 unique values in a 40-char hash). Mulberry32 produces a full 32-bit uniform stream from any seed, eliminating correlation artifacts.
40
+
41
+ ## 2. Color Scheme
42
+
43
+ The `SacredColorScheme` class derives three harmonious palettes from the hash:
44
+
45
+ | Palette | Method | Purpose |
46
+ |---------|--------|---------|
47
+ | Base (analogic) | `color-scheme` lib, hue = seed % 360 | Primary shape colors |
48
+ | Complementary (mono) | hue = seed + 180° | Contrast accents |
49
+ | Triadic | hue = seed + 120° | Additional variety |
50
+
51
+ These are merged and deduplicated into a single 6-8 color palette. Background colors are darkened variants (65% and 55% brightness) of the base scheme.
52
+
53
+ ### Color Utilities
54
+
55
+ - **`hexWithAlpha(hex, alpha)`** — converts hex to `rgba()` for transparency
56
+ - **`jitterColor(hex, rng, amount)`** — applies ±amount RGB jitter per channel for organic variation
57
+ - **Positional blending** — shape fill color is biased by canvas position, creating smooth color flow across the image
58
+
59
+ ## 3. Background
60
+
61
+ A radial gradient fills the canvas from center to corners using two darkened base-scheme colors. This creates depth before any shapes are drawn.
62
+
63
+ ## 4. Composition Modes
64
+
65
+ The hash deterministically selects one of five composition strategies that control how shapes are positioned on the canvas:
66
+
67
+ | Mode | Description |
68
+ |------|-------------|
69
+ | **Radial** | Shapes emanate from the center with distance following a power curve (denser near center) |
70
+ | **Flow-field** | Random positions; shapes are rotated to align with a hash-derived vector field |
71
+ | **Spiral** | Shapes follow a multi-turn spiral path outward from center with slight scatter |
72
+ | **Grid-subdivision** | Canvas is divided into cells; shapes are placed randomly within cells |
73
+ | **Clustered** | 3-5 cluster centers are generated; shapes scatter around the nearest cluster |
74
+
75
+ Each mode produces fundamentally different visual character from the same shape set.
76
+
77
+ ## 5. Focal Points
78
+
79
+ 1-2 focal points are placed on the canvas (kept away from edges). Every shape position is pulled toward the nearest focal point by a strength factor (30-70%), creating areas of visual density and intentional-looking composition rather than uniform scatter.
80
+
81
+ ## 6. Shape Layers
82
+
83
+ The image is built in N layers (default: 4). Each layer has its own characteristics:
84
+
85
+ ### Layer Properties
86
+
87
+ | Property | Behavior |
88
+ |----------|----------|
89
+ | Opacity | Decays gently per layer (0.7 → 0.58 → 0.46 → 0.34), minimum 0.15 |
90
+ | Size scale | Later layers use progressively smaller shapes (×0.85, ×0.70, ×0.55) |
91
+ | Shape weights | Early layers favor basic shapes; later layers favor complex/sacred |
92
+ | Per-shape opacity | Additional random jitter (50-100% of layer opacity) |
93
+
94
+ ### Shape Selection (Layer-Weighted)
95
+
96
+ Shapes are divided into three categories with weights that shift across layers:
97
+
98
+ | Category | Shapes | Early layers | Late layers |
99
+ |----------|--------|-------------|-------------|
100
+ | **Basic** | circle, square, triangle, hexagon, diamond, cube | High weight | Low weight |
101
+ | **Complex** | star, platonic solid, fibonacci spiral, islamic pattern, celtic knot, merkaba, fractal | Medium | Medium-high |
102
+ | **Sacred** | mandala, flower of life, tree of life, Metatron's cube, Sri Yantra, seed of life, vesica piscis, torus, egg of life | Low | High |
103
+
104
+ ### Size Distribution
105
+
106
+ Shape sizes follow a **power distribution** (`Math.pow(rng(), 1.8)`) — producing many small shapes and few large ones, which creates natural visual hierarchy.
107
+
108
+ ### Styling Per Shape
109
+
110
+ Each shape receives:
111
+
112
+ - **Semi-transparent fill** — alpha between 0.2-0.7, creating watercolor-style blending where shapes overlap
113
+ - **Color jitter** — ±8% RGB variation on fills, ±5% on strokes, so no two shapes using the "same" palette color are pixel-identical
114
+ - **Positional color** — fill color is biased by the shape's canvas position, creating smooth color flow
115
+ - **Glow effect** — 45% of sacred shapes and 20% of others get a `shadowBlur` glow (8-28px scaled), with glow color at 60% opacity
116
+ - **Gradient fill** — ~30% of shapes get a radial gradient between two jittered palette colors instead of a flat fill
117
+ - **Variable stroke width** — 0.5-2.5px scaled to canvas size
118
+
119
+ ### Recursive Nesting
120
+
121
+ ~15% of shapes larger than 40% of max size spawn 1-3 inner shapes:
122
+ - Inner shapes are drawn at the parent's position with small random offsets
123
+ - They use more complex/sacred shape types (layer ratio biased +0.3)
124
+ - Sized at 15-40% of the parent
125
+ - More transparent than the parent layer
126
+
127
+ ## 7. Flow-Line Pass
128
+
129
+ 6-16 flowing curves are drawn across the canvas, following the hash-derived vector field:
130
+
131
+ - Each line starts at a random position and takes 30-70 steps
132
+ - At each step, direction is determined by the flow field angle at that position plus slight random wobble
133
+ - Lines stop if they leave the canvas bounds
134
+ - Drawn at very low opacity (6-16%) with thin strokes for subtle movement
135
+
136
+ The flow field is defined by:
137
+ ```
138
+ angle(x, y) = baseAngle + sin(x/w × freq × 2π) × π/2 + cos(y/h × freq × 2π) × π/2
139
+ ```
140
+
141
+ ## 8. Noise Texture Overlay
142
+
143
+ A dedicated noise RNG (seeded separately from the main RNG to avoid affecting shape generation) renders thousands of 1px dots across the canvas:
144
+
145
+ - Density: ~1 dot per 800 square pixels
146
+ - Each dot is either black or white (50/50)
147
+ - Very low opacity (1-4%)
148
+ - Creates subtle film-grain texture that adds organic depth
149
+
150
+ ## 9. Organic Connecting Curves
151
+
152
+ Quadratic bezier curves connect nearby shapes:
153
+
154
+ - Number of curves scales with canvas area (~8 per megapixel)
155
+ - Each curve connects two shapes that were drawn near each other in sequence
156
+ - Control points are offset perpendicular to the connecting line with random bulge
157
+ - Drawn at low opacity (6-16%) with palette colors at 30% alpha
158
+
159
+ ## Shape Implementations
160
+
161
+ ### Basic Shapes
162
+ Standard geometric primitives drawn as canvas paths (beginPath → moveTo/lineTo/arc → closePath). The draw pipeline calls `fill()` and `stroke()` after the path is defined.
163
+
164
+ ### Complex Shapes
165
+ More intricate geometry including:
166
+ - **Platonic solids** — 2D projections with all edges drawn between vertices
167
+ - **Fibonacci spiral** — iterative arc segments following the golden ratio
168
+ - **Islamic pattern** — 8-pointed star grid at intersections
169
+ - **Celtic knot** — bezier over/under weaving pattern
170
+ - **Mandala** — concentric circles with radial lines
171
+ - **Fractal tree** — recursive branching at ±30° with 0.7× length decay
172
+
173
+ ### Sacred Geometry
174
+ Mathematically precise sacred geometry patterns:
175
+ - **Flower of Life** — 7 overlapping circles in hexagonal arrangement
176
+ - **Tree of Life** — 10 Sephirot nodes with connecting paths
177
+ - **Metatron's Cube** — 13 vertices (center + inner/outer hexagons) fully connected
178
+ - **Sri Yantra** — 9 interlocking triangles at two radii
179
+ - **Seed of Life** — 7 circles (same as Flower of Life, different scale)
180
+ - **Vesica Piscis** — two overlapping circles
181
+ - **Torus** — 2D projection of a torus via line segments
182
+ - **Egg of Life** — 7 circles in tight hexagonal packing
183
+
184
+ ## Configuration
185
+
186
+ All parameters are exposed via `GenerationConfig`:
187
+
188
+ | Parameter | Default | Effect |
189
+ |-----------|---------|--------|
190
+ | `width` | 2048 | Canvas width in pixels |
191
+ | `height` | 2048 | Canvas height in pixels |
192
+ | `gridSize` | 5 | Base shape count = gridSize² × 1.5 |
193
+ | `layers` | 4 | Number of rendering layers |
194
+ | `minShapeSize` | 30 | Minimum shape size (scaled to canvas) |
195
+ | `maxShapeSize` | 400 | Maximum shape size (scaled to canvas) |
196
+ | `baseOpacity` | 0.7 | First layer opacity |
197
+ | `opacityReduction` | 0.12 | Opacity decay per layer |
198
+ | `shapesPerLayer` | auto | Override auto-calculated shape count |
package/CHANGELOG.md CHANGED
@@ -4,9 +4,28 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [0.3.0](https://github.com/gfargo/git-hash-art/compare/0.2.0...0.3.0)
8
+
9
+ - feat: evolve art generation with composition modes, flow fields, nesting, and texture [`#9`](https://github.com/gfargo/git-hash-art/pull/9)
10
+ - refactor(browser): simplify export statement [`dc193c9`](https://github.com/gfargo/git-hash-art/commit/dc193c972511c5b0eb9e6a781c423aa005453007)
11
+
12
+ #### [0.2.0](https://github.com/gfargo/git-hash-art/compare/0.1.0...0.2.0)
13
+
14
+ > 19 March 2026
15
+
16
+ - feat: add cross-platform browser support [`#8`](https://github.com/gfargo/git-hash-art/pull/8)
17
+ - feat: add visual effects for richer art generation [`#6`](https://github.com/gfargo/git-hash-art/pull/6)
18
+ - fix: improve art generation quality [`#5`](https://github.com/gfargo/git-hash-art/pull/5)
19
+ - docs: update README to reflect current algorithm and features [`15879c6`](https://github.com/gfargo/git-hash-art/commit/15879c62480a2d418c4ef8dcb479d912a7160345)
20
+ - chore: release v0.2.0 [`6867e06`](https://github.com/gfargo/git-hash-art/commit/6867e067f6dda0f4a4fd444b412772ddecb01555)
21
+ - fix(shapes): handle missing shape type default [`860bfd3`](https://github.com/gfargo/git-hash-art/commit/860bfd36caab97d6ed44dd441ea1a995863b6068)
22
+
7
23
  #### [0.1.0](https://github.com/gfargo/git-hash-art/compare/0.0.4...0.1.0)
8
24
 
25
+ > 18 March 2026
26
+
9
27
  - update shape drawing for platonic solids [`c26decd`](https://github.com/gfargo/git-hash-art/commit/c26decd8df9d7d47615efce37da8fdf554cdfcc4)
28
+ - chore: release v0.1.0 [`f83dce5`](https://github.com/gfargo/git-hash-art/commit/f83dce5de7a03da5432b1bb538643b7fcb9cd29f)
10
29
 
11
30
  #### [0.0.4](https://github.com/gfargo/git-hash-art/compare/0.0.3...0.0.4)
12
31
 
package/README.md CHANGED
@@ -2,15 +2,22 @@
2
2
 
3
3
  Generate beautiful, deterministic abstract art from git commit hashes. Perfect for creating unique visual representations of your project's commits, generating placeholder images, or creating artistic wallpapers.
4
4
 
5
+ Works in both Node.js and browser environments.
6
+
5
7
  ## Features
6
8
 
7
- - Generate consistent, deterministic abstract art from any git hash
8
- - Configurable canvas sizes and output formats
9
- - Built-in presets for common social media and device sizes
10
- - Harmonious color schemes based on hash values
11
- - Grid-based composition system for balanced layouts
12
- - Multiple shape types and layering effects
13
- - Customizable output settings
9
+ - Deterministic output same hash always produces the same image
10
+ - Hash-derived harmonious color schemes (analogic, complementary, and triadic palettes)
11
+ - 20+ shape types across three categories: basic, complex, and sacred geometry
12
+ - Layered composition with depth early layers use simple shapes, later layers use intricate ones
13
+ - Watercolor-style transparency with semi-transparent fills and color blending
14
+ - Glow effects on sacred geometry shapes for an ethereal quality
15
+ - Radial gradient fills and organic color jitter for a hand-painted feel
16
+ - Organic bezier curves connecting nearby shapes
17
+ - Configurable canvas size, layers, shape sizes, and opacity
18
+ - Built-in presets for social media, device wallpapers, and print sizes
19
+ - CLI for generating art from the current commit or a specific hash
20
+ - Cross-platform: runs in Node.js (via `@napi-rs/canvas`) and browsers (native Canvas API)
14
21
 
15
22
  ## Installation
16
23
 
@@ -18,87 +25,170 @@ Generate beautiful, deterministic abstract art from git commit hashes. Perfect f
18
25
  npm install git-hash-art
19
26
  ```
20
27
 
21
- ## Basic Usage
28
+ For Node.js usage you also need the canvas backend:
29
+
30
+ ```bash
31
+ npm install @napi-rs/canvas
32
+ ```
33
+
34
+ Browser usage requires no additional dependencies — the library uses the native Canvas 2D API.
35
+
36
+ ## Node.js Usage
22
37
 
23
38
  ```javascript
24
- import { generateImageFromHash } from 'git-hash-art';
39
+ import { generateImageFromHash, saveImageToFile } from 'git-hash-art';
25
40
 
26
- // Generate art from a git hash with default settings
41
+ // Generate a PNG buffer from a git hash
27
42
  const gitHash = '46192e59d42f741c761cbea79462a8b3815dd905';
28
- generateImageFromHash(gitHash);
43
+ const imageBuffer = generateImageFromHash(gitHash);
44
+
45
+ // Save to disk
46
+ saveImageToFile(imageBuffer, './output', gitHash, 'my-art', 2048, 2048);
29
47
  ```
30
48
 
31
- ## Advanced Usage
49
+ ### Advanced Node.js Usage
32
50
 
33
51
  ```javascript
34
- // Custom configuration
52
+ import { generateImageFromHash } from 'git-hash-art';
53
+
35
54
  const config = {
36
55
  width: 1920,
37
56
  height: 1080,
38
57
  gridSize: 6,
39
- layers: 7,
40
- shapesPerLayer: 30,
58
+ layers: 5,
59
+ shapesPerLayer: 40,
41
60
  minShapeSize: 20,
42
- maxShapeSize: 180,
43
- baseOpacity: 0.6,
44
- opacityReduction: 0.1
61
+ maxShapeSize: 300,
62
+ baseOpacity: 0.7,
63
+ opacityReduction: 0.12
45
64
  };
46
65
 
47
- generateImageFromHash(gitHash, config);
66
+ const imageBuffer = generateImageFromHash(gitHash, config);
48
67
  ```
49
68
 
50
- ## Configuration Options
69
+ ## Browser Usage
51
70
 
52
- | Option | Type | Default | Description |
53
- |--------|------|---------|-------------|
54
- | `width` | number | 1024 | Canvas width in pixels |
55
- | `height` | number | 1024 | Canvas height in pixels |
56
- | `gridSize` | number | 4 | Number of grid cells (gridSize x gridSize) |
57
- | `layers` | number | 5 | Number of layers to generate |
58
- | `shapesPerLayer` | number | - | Base number of shapes per layer (defaults to grid cells * 1.5) |
59
- | `minShapeSize` | number | 20 | Minimum shape size |
60
- | `maxShapeSize` | number | 180 | Maximum shape size |
61
- | `baseOpacity` | number | 0.6 | Starting opacity for first layer |
62
- | `opacityReduction` | number | 0.1 | How much to reduce opacity per layer |
71
+ ```javascript
72
+ import { renderToCanvas, generateDataURL, generateImageBlob } from 'git-hash-art/browser';
73
+ ```
63
74
 
64
- ## Preset Sizes
75
+ ### Render onto an existing canvas element
65
76
 
66
- The package includes several preset configurations for common use cases:
77
+ ```javascript
78
+ import { renderToCanvas } from 'git-hash-art/browser';
79
+
80
+ const canvas = document.getElementById('art-canvas');
81
+ canvas.width = 1024;
82
+ canvas.height = 1024;
83
+
84
+ renderToCanvas(canvas, '46192e59d42f741c761cbea79462a8b3815dd905');
85
+ ```
86
+
87
+ ### Generate a data URL (for `<img>` tags)
67
88
 
68
89
  ```javascript
69
- import { PRESETS } from 'git-hash-art-generator';
90
+ import { generateDataURL } from 'git-hash-art/browser';
70
91
 
71
- // Generate an Instagram-sized image
72
- generateImageFromHash(gitHash, PRESETS['instagram'].config);
92
+ const dataUrl = generateDataURL('46192e59d42f741c761cbea79462a8b3815dd905', {
93
+ width: 512,
94
+ height: 512,
95
+ });
73
96
 
74
- // Generate a mobile wallpaper
75
- generateImageFromHash(gitHash, PRESETS['phone-wallpaper'].config);
97
+ document.getElementById('preview').src = dataUrl;
76
98
  ```
77
99
 
78
- Available presets include:
79
- - Standard (1024x1024)
80
- - Banner (1920x480)
81
- - Ultrawide (3440x1440)
82
- - Instagram (1080x1080)
83
- - Instagram Story (1080x1920)
84
- - Twitter Header (1500x500)
85
- - LinkedIn Banner (1584x396)
86
- - Phone Wallpaper (1170x2532)
87
- - Tablet Wallpaper (2048x2732)
88
- - Print sizes (A4/A3 at 300 DPI)
100
+ ### Generate a Blob (for downloads or uploads)
89
101
 
90
- ## CLI Usage
102
+ ```javascript
103
+ import { generateImageBlob } from 'git-hash-art/browser';
104
+
105
+ const blob = await generateImageBlob('46192e59d42f741c761cbea79462a8b3815dd905', {
106
+ width: 1080,
107
+ height: 1080,
108
+ });
109
+
110
+ // Trigger a download
111
+ const url = URL.createObjectURL(blob);
112
+ const a = document.createElement('a');
113
+ a.href = url;
114
+ a.download = 'hash-art.png';
115
+ a.click();
116
+ ```
117
+
118
+ ## Core Renderer (Environment-Agnostic)
119
+
120
+ If you need full control, both entry points re-export `renderHashArt` which
121
+ accepts any standard `CanvasRenderingContext2D` — useful for custom canvas
122
+ setups, Web Workers with `OffscreenCanvas`, or server-side rendering
123
+ frameworks.
124
+
125
+ ```javascript
126
+ import { renderHashArt } from 'git-hash-art'; // or 'git-hash-art/browser'
127
+
128
+ const ctx = myCanvas.getContext('2d');
129
+ renderHashArt(ctx, '46192e59d42f741c761cbea79462a8b3815dd905', {
130
+ width: myCanvas.width,
131
+ height: myCanvas.height,
132
+ });
133
+ ```
134
+
135
+ ## Configuration Options
136
+
137
+ | Option | Type | Default | Description |
138
+ | ----------------- | ------ | ------- | ---------------------------------------------------- |
139
+ | `width` | number | 2048 | Canvas width in pixels |
140
+ | `height` | number | 2048 | Canvas height in pixels |
141
+ | `gridSize` | number | 5 | Controls base shape count per layer (gridSize² × 1.5)|
142
+ | `layers` | number | 4 | Number of layers to generate |
143
+ | `shapesPerLayer` | number | auto | Base shapes per layer (defaults to gridSize² × 1.5) |
144
+ | `minShapeSize` | number | 30 | Minimum shape size in pixels (scaled to canvas) |
145
+ | `maxShapeSize` | number | 400 | Maximum shape size in pixels (scaled to canvas) |
146
+ | `baseOpacity` | number | 0.7 | Starting opacity for the first layer |
147
+ | `opacityReduction`| number | 0.12 | Opacity reduction per layer |
148
+
149
+ ## Shape Categories
91
150
 
92
- The package includes a command-line interface:
151
+ Shapes are selected with layer-aware weighting — early layers favor simple shapes for background texture, later layers favor intricate ones for foreground detail.
152
+
153
+ **Basic** — circle, square, triangle, hexagon, star, diamond, cube, heart
154
+
155
+ **Complex** — platonic solids, fibonacci spiral, islamic pattern, celtic knot, merkaba, mandala, fractal
156
+
157
+ **Sacred Geometry** — flower of life, tree of life, Metatron's cube, Sri Yantra, seed of life, vesica piscis, torus, egg of life
158
+
159
+ ## Preset Sizes
160
+
161
+ ```javascript
162
+ import { PRESETS } from 'git-hash-art';
163
+
164
+ // Use a preset's hash and config
165
+ const preset = PRESETS['instagram-square'];
166
+ const imageBuffer = generateImageFromHash(preset.hash, preset);
167
+ ```
168
+
169
+ Available presets:
170
+
171
+ - Standard (1024×1024)
172
+ - Banner (1920×480)
173
+ - Ultrawide (3440×1440)
174
+ - Instagram Square (1080×1080)
175
+ - Instagram Story (1080×1920)
176
+ - Twitter Header (1500×500)
177
+ - LinkedIn Banner (1584×396)
178
+ - Phone Wallpaper (1170×2532)
179
+ - Tablet Wallpaper (2048×2732)
180
+ - Minimal, Complex (special configurations)
181
+
182
+ ## CLI Usage
93
183
 
94
184
  ```bash
95
- # Generate with default settings
185
+ # Generate from the current commit
96
186
  npx git-hash-art current
97
187
 
98
- # Generate from specific hash
188
+ # Generate from a specific hash
99
189
  npx git-hash-art generate <hash>
100
190
 
101
- # Generate with custom size
191
+ # Custom size
102
192
  npx git-hash-art generate <hash> --width 1920 --height 1080
103
193
  ```
104
194
 
@@ -115,7 +205,7 @@ jobs:
115
205
  steps:
116
206
  - uses: actions/checkout@v2
117
207
  - uses: actions/setup-node@v2
118
- - run: npm install git-hash-art-generator
208
+ - run: npm install git-hash-art @napi-rs/canvas
119
209
  - run: npx git-hash-art current --output artwork/
120
210
  ```
121
211
 
@@ -124,15 +214,33 @@ jobs:
124
214
  ```bash
125
215
  #!/bin/sh
126
216
  # .git/hooks/post-commit
127
-
128
217
  hash=$(git rev-parse HEAD)
129
218
  npx git-hash-art generate $hash --output .git/artwork/
130
219
  ```
131
220
 
221
+ ### React Component
222
+
223
+ ```jsx
224
+ import { useEffect, useRef } from 'react';
225
+ import { renderToCanvas } from 'git-hash-art/browser';
226
+
227
+ function CommitArt({ hash, width = 256, height = 256 }) {
228
+ const canvasRef = useRef(null);
229
+
230
+ useEffect(() => {
231
+ if (canvasRef.current) {
232
+ renderToCanvas(canvasRef.current, hash, { width, height });
233
+ }
234
+ }, [hash, width, height]);
235
+
236
+ return <canvas ref={canvasRef} width={width} height={height} />;
237
+ }
238
+ ```
239
+
132
240
  ## Contributing
133
241
 
134
242
  Contributions are welcome! Please see our [Contributing Guidelines](CONTRIBUTING.md) for more details.
135
243
 
136
244
  ## License
137
245
 
138
- MIT License - see [LICENSE](LICENSE) for details.
246
+ MIT License - see [LICENSE](LICENSE) for details.