git-hash-art 0.8.0 → 0.10.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.
- package/ALGORITHM.md +425 -274
- package/CHANGELOG.md +18 -0
- package/bin/cli.js +17 -14
- package/bin/generateVersionComparison.js +353 -0
- package/dist/browser.js +1563 -123
- package/dist/browser.js.map +1 -1
- package/dist/main.js +1563 -123
- package/dist/main.js.map +1 -1
- package/dist/module.js +1563 -123
- package/dist/module.js.map +1 -1
- package/package.json +2 -1
- package/src/lib/archetypes.ts +115 -3
- package/src/lib/canvas/colors.ts +25 -0
- package/src/lib/canvas/draw.ts +348 -1
- package/src/lib/canvas/shapes/affinity.ts +149 -4
- package/src/lib/canvas/shapes/procedural.ts +395 -32
- package/src/lib/render.ts +426 -19
package/ALGORITHM.md
CHANGED
|
@@ -4,49 +4,78 @@ This document describes the deterministic art generation pipeline used by `git-h
|
|
|
4
4
|
|
|
5
5
|
## Pipeline Overview
|
|
6
6
|
|
|
7
|
-
```
|
|
7
|
+
```text
|
|
8
8
|
Hash String
|
|
9
9
|
│
|
|
10
10
|
├─► Seed (mulberry32 PRNG)
|
|
11
11
|
│
|
|
12
|
-
├─► Archetype Selection (1 of
|
|
12
|
+
├─► Archetype Selection (1 of 17 visual personalities, ~15% chance of blending two)
|
|
13
|
+
│
|
|
14
|
+
├─► Color Scheme (palette mode + temperature mode + contrast enforcement)
|
|
15
|
+
│ └─► Color Hierarchy (dominant 60% / secondary 25% / accent 15%)
|
|
16
|
+
│ └─► Per-Layer Palette Evolution (±20° hue drift across layers)
|
|
17
|
+
│
|
|
18
|
+
├─► Shape Palette (affinity-curated primary / supporting / accent shapes)
|
|
13
19
|
│
|
|
14
|
-
├─► Color
|
|
20
|
+
├─► Color Grade Selection (unified tone for post-processing)
|
|
15
21
|
│
|
|
16
22
|
└─► Rendering Pipeline (parameters overridden by archetype)
|
|
17
23
|
│
|
|
18
24
|
0. Archetype Override (gridSize, layers, opacity, sizes, styles)
|
|
25
|
+
0b. Color Hierarchy (dominant/secondary/accent weighting)
|
|
26
|
+
0c. Shape Palette (curated via affinity graph)
|
|
27
|
+
0d. Color Grade (hue + intensity for final tone)
|
|
28
|
+
0e. Light Direction (consistent shadow angle)
|
|
19
29
|
1. Background Layer (7 styles: radial, linear, solid, multi-stop)
|
|
30
|
+
└─ Gradient Mesh Overlay (3-4 radial color control points)
|
|
20
31
|
1a. Background Luminance → contrast enforcement threshold
|
|
21
|
-
1b. Layered Background (
|
|
32
|
+
1b. Layered Background (archetype-coherent shapes + concentric rings)
|
|
33
|
+
1c. Background Pattern Layer (dot grid / diagonal lines / tessellation)
|
|
22
34
|
2. Composition Mode Selection
|
|
23
35
|
2b. Symmetry Mode Selection (none / bilateral / quad)
|
|
24
36
|
3. Focal Points (rule-of-thirds biased) + Void Zones
|
|
37
|
+
3b. Void Zone Decoration (halos, scattered dots, concentric rings)
|
|
25
38
|
4. Flow Field Initialization
|
|
26
|
-
4b. Hero Shape (
|
|
39
|
+
4b. Hero Shape (palette-aware, affinity-styled)
|
|
27
40
|
5. Shape Layers (× N layers, archetype-tuned)
|
|
28
41
|
│ ├─ Blend Mode (per-layer compositing)
|
|
29
|
-
│ ├─ Render Style (
|
|
42
|
+
│ ├─ Render Style (affinity-aware per shape)
|
|
43
|
+
│ ├─ Depth-of-Field (stroke thinning + contrast reduction on far layers)
|
|
44
|
+
│ ├─ Color Palette Evolution (per-layer hue drift via evolveHierarchy)
|
|
45
|
+
│ ├─ Focal Depth Boost (nesting/constellation chance ↑ near focal points)
|
|
30
46
|
│ ├─ Position (composition mode + focal bias + density check)
|
|
31
|
-
│ ├─ Shape Selection (
|
|
47
|
+
│ ├─ Shape Selection (palette-driven with size constraints)
|
|
48
|
+
│ ├─ Hero Avoidance Field (nearby shapes orient toward hero)
|
|
32
49
|
│ ├─ Contrast Enforcement (ensure readability vs background)
|
|
33
50
|
│ ├─ Atmospheric Depth (desaturation on later layers)
|
|
34
51
|
│ ├─ Temperature Contrast (foreground opposite to background)
|
|
35
|
-
│ ├─ Styling (transparency, glow, gradients,
|
|
52
|
+
│ ├─ Styling (transparency, glow, gradients, HSL jitter)
|
|
36
53
|
│ ├─ Organic Edges (~15% watercolor bleed)
|
|
37
|
-
│
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
│ ├─ 5a. Tangent Placement (~25% nudge toward nearest shape edge)
|
|
55
|
+
│ ├─ 5b. Shape Mirroring (~40% of basic shapes get reflected copies)
|
|
56
|
+
│ ├─ 5c. Size Echo (~20% of large shapes spawn trailing copies)
|
|
57
|
+
│ ├─ 5d. Recursive Nesting (~15% of large shapes, palette-aware)
|
|
58
|
+
│ └─ 5e. Shape Constellations (~12% of large shapes, pre-composed groups)
|
|
59
|
+
6. Flow-Line Pass (variable color, pressure, branching)
|
|
60
|
+
6b. Motion/Energy Lines (directional bursts from shapes)
|
|
61
|
+
6c. Layered Transparency / Glazing (~20% of shapes get multi-pass redraws)
|
|
62
|
+
7. Symmetry Mirroring (bilateral-x, bilateral-y, or quad)
|
|
63
|
+
7. Symmetry Mirroring (bilateral-x, bilateral-y, or quad)
|
|
64
|
+
8. Noise Texture Overlay
|
|
65
|
+
9. Vignette (radial edge darkening)
|
|
66
|
+
10. Organic Connecting Curves
|
|
67
|
+
11. Post-Processing
|
|
68
|
+
├─ Color Grading (unified tone overlay)
|
|
69
|
+
├─ Chromatic Aberration (neon/cosmic/ethereal only)
|
|
70
|
+
└─ Bloom (neon/cosmic only)
|
|
71
|
+
12. Signature Mark (deterministic geometric chop mark)
|
|
43
72
|
```
|
|
44
73
|
|
|
45
74
|
## 1. Deterministic RNG
|
|
46
75
|
|
|
47
76
|
All randomness flows from a single **mulberry32** PRNG seeded by hashing the full input string:
|
|
48
77
|
|
|
49
|
-
```
|
|
78
|
+
```text
|
|
50
79
|
seed = hash(gitHash) → mulberry32 state
|
|
51
80
|
rng() → float in [0, 1)
|
|
52
81
|
```
|
|
@@ -55,12 +84,12 @@ The old approach extracted 2-char hex pairs from the hash (only ~20 unique value
|
|
|
55
84
|
|
|
56
85
|
## 2. Archetype System
|
|
57
86
|
|
|
58
|
-
Before any rendering begins, the hash deterministically selects one of
|
|
87
|
+
Before any rendering begins, the hash deterministically selects one of 17 **visual archetypes** — fundamentally different rendering personalities that override key parameters. This is the primary mechanism for visual diversity: two hashes that select different archetypes will look like they came from entirely different generators.
|
|
59
88
|
|
|
60
89
|
Each archetype controls:
|
|
61
90
|
|
|
62
91
|
| Parameter | Effect |
|
|
63
|
-
|
|
92
|
+
| --------- | ------ |
|
|
64
93
|
| `gridSize` | Shape density (2 = sparse, 9 = packed) |
|
|
65
94
|
| `layers` | Rendering depth (2 = flat, 5 = deep) |
|
|
66
95
|
| `baseOpacity` / `opacityReduction` | Transparency character |
|
|
@@ -71,340 +100,462 @@ Each archetype controls:
|
|
|
71
100
|
| `flowLineMultiplier` | Flow line density (0 = none, 4 = heavy) |
|
|
72
101
|
| `heroShape` | Whether to draw a dominant focal shape |
|
|
73
102
|
| `glowMultiplier` | Glow probability scaling (0 = none, 3 = heavy) |
|
|
74
|
-
| `sizePower` | Size distribution curve (0.5 = uniform, 2.
|
|
103
|
+
| `sizePower` | Size distribution curve (0.5 = uniform, 2.8 = many tiny) |
|
|
75
104
|
|
|
76
|
-
### The
|
|
105
|
+
### The 17 Archetypes
|
|
77
106
|
|
|
78
|
-
| Archetype |
|
|
79
|
-
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
107
|
+
| Archetype | Grid | Layers | Background | Palette | Key Styles | Flow | Hero | Character |
|
|
108
|
+
| --------- | ---- | ------ | ---------- | ------- | ---------- | ---- | ---- | --------- |
|
|
109
|
+
| dense-chaotic | 9 | 5 | radial-dark | harmonious | fill-and-stroke, watercolor | 2.5× | no | Packed, layered, energetic |
|
|
110
|
+
| minimal-spacious | 2 | 2 | solid-light | duotone | fill-and-stroke, stroke-only, incomplete | 0.3× | yes | Clean, airy, few large shapes |
|
|
111
|
+
| organic-flow | 4 | 3 | radial-dark | earth | watercolor, fill-only, incomplete | 4× | no | Natural, flowing, muted tones |
|
|
112
|
+
| geometric-precision | 6 | 3 | solid-dark | high-contrast | stroke-only, dashed, double-stroke, hatched | 0× | no | Sharp, structured, no flow lines |
|
|
113
|
+
| ethereal | 7 | 5 | radial-light | pastel-light | watercolor, incomplete | 1.5× | yes | Soft, glowing, dreamlike |
|
|
114
|
+
| bold-graphic | 2 | 2 | linear-diagonal | duotone | fill-and-stroke, double-stroke | 0× | yes | Poster-like, large shapes |
|
|
115
|
+
| neon-glow | 5 | 4 | solid-dark | neon | stroke-only, double-stroke, dashed | 2× | yes | Bright outlines on black, heavy glow |
|
|
116
|
+
| monochrome-ink | 6 | 3 | solid-light | monochrome | hatched, incomplete, stroke-only | 1.5× | no | Pen-and-ink, single hue |
|
|
117
|
+
| cosmic | 8 | 5 | radial-dark | neon | fill-only, watercolor | 3× | yes | Deep space, many tiny shapes, glow |
|
|
118
|
+
| watercolor-wash | 3 | 3 | radial-light | harmonious | watercolor, fill-only, incomplete | 0.5× | no | Soft washes, large shapes, low opacity |
|
|
119
|
+
| op-art | 8 | 2 | solid-light | high-contrast | fill-and-stroke, stroke-only, dashed | 0× | no | Dense, high-contrast, uniform sizes |
|
|
120
|
+
| collage | 4 | 3 | solid-light | duotone | fill-and-stroke, fill-only, double-stroke | 0× | yes | Overlapping, medium-large shapes |
|
|
121
|
+
| classic | 5 | 4 | radial-dark | harmonious | fill-and-stroke, watercolor | 1× | yes | Balanced, the original look |
|
|
122
|
+
| shattered-glass | 8 | 3 | solid-dark | high-contrast | fill-and-stroke, stroke-only, fill-only | 0× | no | Angular fragments, sharp edges, mosaic-like |
|
|
123
|
+
| botanical | 4 | 4 | radial-light | earth | watercolor, fill-only, incomplete | 3× | yes | Organic tendrils, flowing forms, natural tones |
|
|
124
|
+
| stipple-portrait | 9 | 2 | solid-light | monochrome | stipple, fill-only, hatched | 0× | no | Dense dot textures, pointillist, single hue |
|
|
125
|
+
| celestial | 7 | 5 | radial-dark | neon | fill-only, watercolor, stroke-only, incomplete | 2× | yes | Cosmic crescents, sacred geometry, heavy glow |
|
|
90
126
|
|
|
91
|
-
|
|
127
|
+
#### New Archetype Details
|
|
92
128
|
|
|
93
|
-
|
|
129
|
+
**shattered-glass** — Favors angular, fragmented shapes (shardField, voronoiCell, penroseTile, diamond, triangle, ngon). Organic shapes like blobs and clouds are filtered from the palette. High contrast on a dark background with no flow lines creates a mosaic of sharp-edged fragments.
|
|
130
|
+
|
|
131
|
+
**botanical** — Boosts organic shapes (tendril, cloudForm, blob, crescent, rose, inkSplat) for a natural, garden-like feel. Earth palette on a light radial background with heavy flow lines (3×) creates flowing, vine-like compositions.
|
|
94
132
|
|
|
95
|
-
|
|
133
|
+
**stipple-portrait** — Extremely dense (grid 9) with very small shapes (5–120px) and a steep size power curve (2.8) producing many tiny dots. Monochrome palette with stipple and hatched styles creates a pointillist texture. No flow lines or hero shape.
|
|
96
134
|
|
|
97
|
-
|
|
98
|
-
|---------|--------|---------|
|
|
99
|
-
| Base | `color-scheme` lib, hue = seed % 360, hash-driven scheme type | Primary shape colors |
|
|
100
|
-
| Complementary | hue = seed + 180°, contrasting variation | Contrast accents |
|
|
101
|
-
| Triadic | hue = seed + 120° | Additional variety |
|
|
135
|
+
**celestial** — Boosts sacred geometry and cosmic shapes (crescent, geodesicDome, mandala, flowerOfLife, spirograph, fibonacciSpiral). Neon palette on dark background with heavy glow (2.5×) and deep layering (5 layers) creates a starfield-like composition with luminous geometric forms.
|
|
102
136
|
|
|
103
|
-
|
|
137
|
+
### Archetype Blending
|
|
138
|
+
|
|
139
|
+
~15% of hashes trigger **archetype blending**, where two archetypes are interpolated to create a hybrid personality. `blendArchetypes(primary, secondary, ratio)` works as follows:
|
|
140
|
+
|
|
141
|
+
- **Blend ratio:** 25–50% (the secondary archetype never dominates)
|
|
142
|
+
- **Numeric parameters** (`gridSize`, `layers`, `baseOpacity`, `minShapeSize`, etc.) are linearly interpolated between the two archetypes
|
|
143
|
+
- **Style arrays** (`preferredStyles`) are merged — the primary's styles come first, then any unique styles from the secondary
|
|
144
|
+
- **Categorical parameters** (`backgroundStyle`, `paletteMode`) use the primary's value when the blend ratio is below 50%, otherwise the secondary's
|
|
145
|
+
- **Boolean parameters** (`heroShape`) use the primary's value
|
|
146
|
+
|
|
147
|
+
This creates subtle hybrid personalities — e.g., a blend of `neon-glow` and `organic-flow` might produce glowing shapes with heavy flow lines and earth-toned neon outlines.
|
|
148
|
+
|
|
149
|
+
## 3. Color Scheme
|
|
150
|
+
|
|
151
|
+
Color generation uses the `color-scheme` library seeded from the hash, then applies archetype-specific palette modes.
|
|
104
152
|
|
|
105
153
|
### Palette Modes
|
|
106
154
|
|
|
107
|
-
|
|
155
|
+
| Mode | Description |
|
|
156
|
+
| ---- | ----------- |
|
|
157
|
+
| harmonious | Full palette from the scheme — the default |
|
|
158
|
+
| monochrome | Single hue, varying lightness |
|
|
159
|
+
| duotone | Two colors only |
|
|
160
|
+
| neon | High saturation on dark backgrounds |
|
|
161
|
+
| pastel-light | Soft pastels on light backgrounds |
|
|
162
|
+
| earth | Muted warm naturals |
|
|
163
|
+
| high-contrast | Black + white + one accent color |
|
|
164
|
+
|
|
165
|
+
### Color Hierarchy
|
|
166
|
+
|
|
167
|
+
After generating the raw palette, colors are organized into a **hierarchy** with weighted selection:
|
|
168
|
+
|
|
169
|
+
- **Dominant (60%)** — the most-used color, selected as the palette entry closest to the average hue
|
|
170
|
+
- **Secondary (25%)** — the color most distant from the dominant
|
|
171
|
+
- **Accent (15%)** — a remaining color for visual punctuation
|
|
108
172
|
|
|
109
|
-
|
|
110
|
-
|------|--------|-----------|
|
|
111
|
-
| **harmonious** | Full base + complementary + triadic | Rich, balanced (default) |
|
|
112
|
-
| **monochrome** | Single hue, 5 lightness steps | Elegant, focused |
|
|
113
|
-
| **duotone** | Two contrasting hues + tints | Bold, graphic |
|
|
114
|
-
| **neon** | 4 hues at full saturation | Electric, vivid |
|
|
115
|
-
| **pastel-light** | 4 hues at low saturation, high lightness | Soft, dreamy |
|
|
116
|
-
| **earth** | Warm muted naturals (browns, olives, sage) | Organic, grounded |
|
|
117
|
-
| **high-contrast** | Black + white + one accent | Technical, stark |
|
|
173
|
+
`pickHierarchyColor(hierarchy, rng)` rolls against these weights so compositions naturally converge on a dominant tone without being monotonous.
|
|
118
174
|
|
|
119
|
-
|
|
175
|
+
### HSL Jitter
|
|
176
|
+
|
|
177
|
+
Color variation uses **HSL-space jitter** (`jitterColorHSL`) instead of the old RGB approach. This produces perceptually uniform shifts — a ±10° hue rotation and ±8% saturation/lightness shift feels natural, whereas the equivalent RGB jitter could accidentally desaturate or muddy colors.
|
|
178
|
+
|
|
179
|
+
### Positional Color
|
|
180
|
+
|
|
181
|
+
Shapes receive color based on their position relative to the canvas center:
|
|
182
|
+
- **Center (< 35% radius):** biased toward the dominant color
|
|
183
|
+
- **Middle (35–70%):** weighted random from the full hierarchy
|
|
184
|
+
- **Edges (> 70%):** biased toward secondary and accent colors
|
|
185
|
+
|
|
186
|
+
This creates a natural color gradient across the composition without explicit gradient code.
|
|
120
187
|
|
|
121
188
|
### Temperature Contrast
|
|
122
189
|
|
|
123
|
-
The
|
|
190
|
+
The scheme detects whether the background leans warm or cool, then shifts foreground shapes toward the opposite temperature. This ensures shapes always "pop" against their background.
|
|
191
|
+
|
|
192
|
+
### Contrast Enforcement
|
|
193
|
+
|
|
194
|
+
Every shape color is checked against the background luminance. If the contrast ratio is too low, the color is lightened or darkened to ensure visibility.
|
|
195
|
+
|
|
196
|
+
### Color Palette Evolution
|
|
197
|
+
|
|
198
|
+
Colors aren't static across layers — they evolve. `evolveHierarchy(hierarchy, layerFraction)` applies a progressive hue rotation to the entire color hierarchy as rendering moves through layers:
|
|
199
|
+
|
|
200
|
+
- **Total drift:** ±20° across the full layer stack (direction determined by the dominant color's initial hue)
|
|
201
|
+
- **Per-layer rotation:** `layerFraction × 20°` applied via `hueRotate(color, degrees)`, which converts to HSL, shifts the hue, and converts back
|
|
202
|
+
- **Effect:** Early layers lean toward the original palette; later layers drift toward adjacent hues on the color wheel
|
|
203
|
+
|
|
204
|
+
This creates a subtle color journey across the depth of the image — warm reds in the background might shift toward orange-gold in the foreground, giving the composition a sense of temporal progression without breaking palette coherence.
|
|
205
|
+
|
|
206
|
+
## 4. Shape Affinity System
|
|
207
|
+
|
|
208
|
+
Not all shapes look equally good at all sizes or in all combinations. The affinity system replaces naive random shape selection with intentional curation.
|
|
209
|
+
|
|
210
|
+
### Shape Inventory
|
|
211
|
+
|
|
212
|
+
The system includes 40+ shapes across 4 categories:
|
|
213
|
+
|
|
214
|
+
| Category | Shapes |
|
|
215
|
+
| -------- | ------ |
|
|
216
|
+
| Basic (9) | circle, square, triangle, hexagon, star, jacked-star, heart, diamond, cube |
|
|
217
|
+
| Complex (7) | platonicSolid, fibonacciSpiral, islamicPattern, celticKnot, merkaba, mandala, fractal |
|
|
218
|
+
| Sacred (8) | flowerOfLife, treeOfLife, metatronsCube, sriYantra, seedOfLife, vesicaPiscis, torus, eggOfLife |
|
|
219
|
+
| Procedural (18) | blob, ngon, lissajous, superellipse, spirograph, waveRing, rose, shardField, voronoiCell, crescent, tendril, cloudForm, inkSplat, geodesicDome, penroseTile, reuleauxTriangle, dotCluster, crosshatchPatch |
|
|
124
220
|
|
|
125
|
-
|
|
126
|
-
|------|-------------|------------|------------|
|
|
127
|
-
| `warm-bg` | ~40% | Hues shifted toward orange (30°) | Hues shifted toward blue (210°) |
|
|
128
|
-
| `cool-bg` | ~40% | Hues shifted toward blue (210°) | Hues shifted toward orange (30°) |
|
|
129
|
-
| `neutral` | ~20% | No temperature shift | No temperature shift |
|
|
221
|
+
### Quality Tiers
|
|
130
222
|
|
|
131
|
-
|
|
223
|
+
Each shape has a profile with:
|
|
132
224
|
|
|
133
|
-
|
|
225
|
+
| Field | Purpose |
|
|
226
|
+
| ----- | ------- |
|
|
227
|
+
| `tier` (1–3) | Visual quality rating. Tier 1 shapes look good at any size; Tier 3 shapes need specific conditions |
|
|
228
|
+
| `minSizeFraction` / `maxSizeFraction` | Size bounds as fraction of `maxShapeSize` — prevents shapes from being drawn at sizes where they look bad |
|
|
229
|
+
| `affinities` | List of shapes this one composes well with |
|
|
230
|
+
| `category` | basic, complex, sacred, or procedural |
|
|
231
|
+
| `heroCandidate` | Whether the shape works as a dominant focal element |
|
|
232
|
+
| `bestStyles` | Render styles that suit this shape (e.g., sacred geometry looks best as stroke-only) |
|
|
134
233
|
|
|
135
|
-
|
|
234
|
+
### Shape Palette Construction
|
|
136
235
|
|
|
137
|
-
|
|
138
|
-
|-----------|-----------|
|
|
139
|
-
| `soft` | Muted, gentle tones |
|
|
140
|
-
| `hard` | High saturation, vivid |
|
|
141
|
-
| `pastel` | Light, airy |
|
|
142
|
-
| `light` | Bright, open |
|
|
143
|
-
| `pale` | Washed out, ethereal |
|
|
144
|
-
| `default` | Balanced, neutral |
|
|
236
|
+
`buildShapePalette(rng, shapeNames, archetypeName)` builds a curated set:
|
|
145
237
|
|
|
146
|
-
|
|
238
|
+
1. **Seed selection:** Pick a Tier 1 hero-candidate shape as the seed
|
|
239
|
+
2. **Primary (5 shapes):** The seed + its direct affinities (Tier 1–2 only)
|
|
240
|
+
3. **Supporting (6 shapes):** Affinities-of-affinities + same-category Tier 1–2 shapes
|
|
241
|
+
4. **Accents (3 shapes):** Tier 1–2 shapes from *other* categories for contrast
|
|
147
242
|
|
|
148
|
-
|
|
243
|
+
Archetype-specific overrides apply:
|
|
244
|
+
- `geometric-precision` removes organic/procedural shapes from primary
|
|
245
|
+
- `organic-flow` boosts blobs and wave rings
|
|
246
|
+
- `shattered-glass` boosts angular shapes (shardField, voronoiCell, penroseTile), removes blobs/clouds
|
|
247
|
+
- `botanical` boosts organic shapes (tendril, cloudForm, crescent, rose, inkSplat)
|
|
248
|
+
- `stipple-portrait` boosts dot-friendly shapes (dotCluster, circle, crosshatchPatch)
|
|
249
|
+
- `celestial` boosts sacred/cosmic shapes (crescent, geodesicDome, mandala, flowerOfLife)
|
|
149
250
|
|
|
150
|
-
-
|
|
151
|
-
- **`jitterColor(hex, rng, amount)`** — applies ±amount RGB jitter per channel for organic variation
|
|
152
|
-
- **`desaturate(hex, amount)`** — blends toward luminance gray for atmospheric depth
|
|
153
|
-
- **`shiftTemperature(hex, target, amount)`** — shifts hue toward warm (orange) or cool (blue)
|
|
154
|
-
- **Positional blending** — shape fill color is biased by canvas position, creating smooth color flow across the image
|
|
251
|
+
### Palette-Driven Selection
|
|
155
252
|
|
|
156
|
-
|
|
253
|
+
During rendering, `pickShapeFromPalette(palette, rng, sizeFraction)` selects shapes with weighted probability:
|
|
254
|
+
- **Primary: ~60%**, Supporting: ~30%, Accent: ~10%
|
|
255
|
+
- Shapes whose size constraints don't match the current `sizeFraction` are filtered out before selection
|
|
157
256
|
|
|
158
|
-
|
|
257
|
+
### Affinity-Aware Styling
|
|
258
|
+
|
|
259
|
+
`pickStyleForShape(shapeName, layerStyle, rng)` gives each shape a 70% chance of using one of its `bestStyles` instead of the layer's default style. This means sacred geometry naturally renders as stroke-only while blobs naturally render as watercolor.
|
|
260
|
+
|
|
261
|
+
## 5. Background Rendering
|
|
262
|
+
|
|
263
|
+
### Base Background
|
|
264
|
+
|
|
265
|
+
The archetype's `backgroundStyle` selects one of 7 modes:
|
|
159
266
|
|
|
160
267
|
| Style | Description |
|
|
161
|
-
|
|
162
|
-
|
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
268
|
+
| ----- | ----------- |
|
|
269
|
+
| radial-dark | Dark radial gradient from center outward (default) |
|
|
270
|
+
| radial-light | Light center (#f0ece4) fading to the palette background |
|
|
271
|
+
| linear-horizontal | Left-to-right gradient |
|
|
272
|
+
| linear-diagonal | Corner-to-corner gradient with midpoint return |
|
|
273
|
+
| solid-dark | Flat dark fill |
|
|
274
|
+
| solid-light | Flat off-white (#f5f2eb) |
|
|
275
|
+
| multi-stop | 3–4 color gradient using palette colors |
|
|
169
276
|
|
|
170
|
-
|
|
277
|
+
### Gradient Mesh Overlay
|
|
171
278
|
|
|
172
|
-
|
|
279
|
+
After the base background, 3–4 radial color control points are placed at random positions using `soft-light` compositing. Each point uses a hierarchy color at very low opacity (8–14%). This adds subtle color variation and depth to what would otherwise be a flat or simple gradient background.
|
|
173
280
|
|
|
174
|
-
|
|
281
|
+
### Layered Background Shapes
|
|
175
282
|
|
|
176
|
-
-
|
|
177
|
-
- **Concentric rings** — 2-4 rings emanating from center at ~2-5% opacity, adding structure without competing with foreground shapes
|
|
283
|
+
Large, nearly-transparent shapes (3–7) are drawn in `soft-light` mode at 3–8% opacity. The shape type is archetype-coherent: geometric archetypes (`geometric-precision`, `op-art`) use rectangles; all others use circles. Subtle concentric rings radiate from the center at ~2–5% opacity to add structure.
|
|
178
284
|
|
|
179
|
-
|
|
285
|
+
### Background Pattern Layer
|
|
180
286
|
|
|
181
|
-
|
|
287
|
+
~60% of images receive a subtle background pattern drawn in `soft-light` at 2–6% opacity, simulating textured paper:
|
|
182
288
|
|
|
183
|
-
|
|
289
|
+
| Pattern | Description |
|
|
290
|
+
| ------- | ----------- |
|
|
291
|
+
| Dot grid (⅓ chance) | Evenly spaced tiny dots across the canvas |
|
|
292
|
+
| Diagonal lines (⅓ chance) | Parallel diagonal lines at 0.5px width |
|
|
293
|
+
| Hexagonal tessellation (⅓ chance) | Honeycomb grid of tiny hexagons, stroke-only |
|
|
184
294
|
|
|
185
|
-
|
|
186
|
-
|------|-------------|
|
|
187
|
-
| **Radial** | Shapes emanate from the center with distance following a power curve (denser near center) |
|
|
188
|
-
| **Flow-field** | Random positions; shapes are rotated to align with a hash-derived vector field |
|
|
189
|
-
| **Spiral** | Shapes follow a multi-turn spiral path outward from center with slight scatter |
|
|
190
|
-
| **Grid-subdivision** | Canvas is divided into cells; shapes are placed randomly within cells |
|
|
191
|
-
| **Clustered** | 3-5 cluster centers are generated; shapes scatter around the nearest cluster |
|
|
295
|
+
The pattern spacing scales with canvas size (1.5–3% of the shorter dimension). This adds tactile depth without competing with foreground shapes.
|
|
192
296
|
|
|
193
|
-
|
|
297
|
+
### Background Luminance
|
|
194
298
|
|
|
195
|
-
|
|
299
|
+
The average luminance of the two background colors is computed and stored. This value drives contrast enforcement for all foreground shapes — ensuring they remain visible regardless of background brightness.
|
|
196
300
|
|
|
197
|
-
|
|
301
|
+
## 6. Composition & Symmetry
|
|
198
302
|
|
|
199
|
-
|
|
200
|
-
|------|-------------|--------|
|
|
201
|
-
| `bilateral-x` | 10% | Left half mirrored onto right half |
|
|
202
|
-
| `bilateral-y` | 10% | Top half mirrored onto bottom half |
|
|
203
|
-
| `quad` | 5% | Both axes mirrored (4-fold symmetry) |
|
|
204
|
-
| `none` | 75% | No mirroring |
|
|
303
|
+
### Composition Modes
|
|
205
304
|
|
|
206
|
-
|
|
305
|
+
Each image uses one of 5 composition strategies for shape placement:
|
|
207
306
|
|
|
208
|
-
|
|
307
|
+
| Mode | Behavior |
|
|
308
|
+
| ---- | -------- |
|
|
309
|
+
| radial | Shapes cluster around center with power-curve falloff |
|
|
310
|
+
| spiral | Shapes follow a multi-turn spiral from center outward |
|
|
311
|
+
| grid-subdivision | Canvas divided into 3–5 cells; shapes placed within random cells |
|
|
312
|
+
| clustered | 3–5 cluster centers; shapes scatter around the nearest cluster |
|
|
313
|
+
| flow-field | Uniform random placement (rotation driven by flow field) |
|
|
209
314
|
|
|
210
|
-
|
|
315
|
+
### Symmetry
|
|
211
316
|
|
|
212
|
-
|
|
317
|
+
~25% of hashes trigger symmetry mirroring, applied after all shapes and flow lines are drawn:
|
|
318
|
+
- **bilateral-x (10%):** Left half mirrored to right
|
|
319
|
+
- **bilateral-y (10%):** Top half mirrored to bottom
|
|
320
|
+
- **quad (5%):** Both axes mirrored
|
|
213
321
|
|
|
214
|
-
|
|
215
|
-
- Uses sacred/complex shape types (flower of life, fibonacci spiral, merkaba, fractal, etc.)
|
|
216
|
-
- Is sized at 80-130% of the maximum shape size for visual dominance
|
|
217
|
-
- Gets glow effects, gradient fills, and often watercolor rendering
|
|
218
|
-
- Is drawn before the main shape layers so other shapes layer on top of it
|
|
219
|
-
- Creates a clear center of gravity that anchors the entire composition
|
|
322
|
+
Symmetry is applied by drawing the canvas image onto itself with `scale(-1, 1)` or `scale(1, -1)` transforms.
|
|
220
323
|
|
|
221
|
-
|
|
324
|
+
## 7. Focal Points & Void Zones
|
|
222
325
|
|
|
223
|
-
1
|
|
326
|
+
1–2 **focal points** are placed with 70% bias toward rule-of-thirds intersections (the remaining 30% are placed randomly within the central 60% of the canvas). Each focal point has a `strength` (0.3–0.7) that pulls nearby shapes toward it via `applyFocalBias`.
|
|
224
327
|
|
|
225
|
-
|
|
328
|
+
1–2 **void zones** are placed randomly. Shapes landing inside a void zone have an 85% chance of being skipped, creating breathing room in the composition.
|
|
226
329
|
|
|
227
|
-
|
|
330
|
+
### Void Zone Decoration
|
|
228
331
|
|
|
229
|
-
|
|
332
|
+
Void zones aren't left completely empty — they receive subtle decorative elements that acknowledge the negative space:
|
|
230
333
|
|
|
231
|
-
|
|
334
|
+
- **Halo ring:** A thin circular stroke at the void zone's boundary using the accent color at 6–12% opacity
|
|
335
|
+
- **Scattered dots (~50% chance):** 5–12 tiny dots (1–3px) scattered randomly inside the void zone at 4–10% opacity, creating a dust-like texture
|
|
336
|
+
- **Inner concentric ring (~30% chance):** A smaller ring at 40–70% of the void zone radius at 3–8% opacity
|
|
232
337
|
|
|
233
|
-
|
|
338
|
+
These decorations are subtle enough to preserve the breathing room while preventing void zones from feeling like rendering errors.
|
|
234
339
|
|
|
235
|
-
|
|
236
|
-
|----------|----------|
|
|
237
|
-
| Opacity | Decays gently per layer (0.7 → 0.58 → 0.46 → 0.34), minimum 0.15 |
|
|
238
|
-
| Size scale | Later layers use progressively smaller shapes (×0.85, ×0.70, ×0.55) |
|
|
239
|
-
| Shape weights | Early layers favor basic shapes; later layers favor complex/sacred |
|
|
240
|
-
| Per-shape opacity | Additional random jitter (50-100% of layer opacity) |
|
|
241
|
-
| Blend mode | Each layer gets a hash-derived `globalCompositeOperation` (see below) |
|
|
242
|
-
| Render style | Each layer has a dominant render style (60% from archetype preferences, 40% random); 30% of shapes pick their own |
|
|
243
|
-
| Atmospheric depth | Later layers desaturate colors by up to 30%, simulating distance |
|
|
340
|
+
## 8. Hero Shape
|
|
244
341
|
|
|
245
|
-
|
|
342
|
+
When the archetype enables `heroShape` and the RNG roll passes (60% chance), a dominant focal element is drawn at the first focal point:
|
|
246
343
|
|
|
247
|
-
|
|
344
|
+
- Shape is selected from palette hero candidates (Tier 1, `heroCandidate: true`)
|
|
345
|
+
- Size is 80–130% of `adjustedMaxSize`
|
|
346
|
+
- Style is chosen from the shape's `bestStyles` via its affinity profile
|
|
347
|
+
- Fill uses the dominant hierarchy color; stroke uses the accent
|
|
348
|
+
- Glow radius is 12–32px (scaled)
|
|
349
|
+
- The hero's position and size are stored for the **hero avoidance field**
|
|
248
350
|
|
|
249
|
-
|
|
351
|
+
## 9. Shape Layers
|
|
250
352
|
|
|
251
|
-
|
|
353
|
+
The core of the image: `layers` passes (archetype-controlled, typically 2–5), each drawing `gridSize² × 1.5` shapes plus up to 30% random extra.
|
|
252
354
|
|
|
253
|
-
|
|
254
|
-
|-------|-------------|-------------|
|
|
255
|
-
| `fill-and-stroke` | Classic solid fill with outline | ~22% (weighted) |
|
|
256
|
-
| `fill-only` | Soft shapes with no outline | ~11% |
|
|
257
|
-
| `stroke-only` | Wireframe with ghost fill at 30% alpha | ~11% |
|
|
258
|
-
| `double-stroke` | Outer stroke at 2× width + inner stroke in fill color | ~11% |
|
|
259
|
-
| `dashed` | Dashed outline (5% size dash, 3% gap) | ~11% |
|
|
260
|
-
| `watercolor` | 3-4 slightly offset passes at low opacity for bleed effect | ~11% |
|
|
261
|
-
| `hatched` | Cross-hatch texture fill clipped to shape boundary | ~11% |
|
|
262
|
-
| `incomplete` | Only 60-85% of outline drawn via dash patterns | ~11% |
|
|
355
|
+
### Per-Layer Setup
|
|
263
356
|
|
|
264
|
-
|
|
357
|
+
- **Blend mode:** Random compositing mode (`source-over`, `multiply`, `screen`, `overlay`, `soft-light`, etc.)
|
|
358
|
+
- **Render style bias:** 60% chance of using an archetype-preferred style; 40% random
|
|
359
|
+
- **Opacity:** Decreases per layer (`baseOpacity - layer × opacityReduction`, floor 0.15)
|
|
360
|
+
- **Size scale:** Decreases 15% per layer (later layers = smaller shapes)
|
|
361
|
+
- **Atmospheric desaturation:** Later layers are progressively desaturated (up to 30%) to simulate depth
|
|
362
|
+
- **Depth-of-field:** Later layers get thinner strokes (down to 40% of base width) and reduced contrast (up to 20% opacity reduction), simulating camera focus falloff
|
|
265
363
|
|
|
266
|
-
###
|
|
364
|
+
### Focal Depth Boost
|
|
267
365
|
|
|
268
|
-
|
|
366
|
+
Shapes near focal points receive enhanced detail via `focalDetailBoost()`:
|
|
269
367
|
|
|
270
|
-
|
|
368
|
+
- **Nesting chance:** Boosted from the base 15% up to 15–30% for shapes within 25% of canvas size from a focal point
|
|
369
|
+
- **Constellation chance:** Boosted from the base 12% up to 12–22% near focal points
|
|
370
|
+
- **Boost strength:** Proportional to proximity — shapes right at the focal point get the full boost, shapes at the edge of the influence radius get minimal boost
|
|
271
371
|
|
|
272
|
-
|
|
372
|
+
This creates a natural depth-of-detail effect where the areas your eye is drawn to (focal points) contain the most intricate shape compositions.
|
|
273
373
|
|
|
274
|
-
|
|
275
|
-
|----------|--------|-------------|-------------|
|
|
276
|
-
| **Basic** | circle, square, triangle, hexagon, diamond, cube | High weight | Low weight |
|
|
277
|
-
| **Complex** | star, platonic solid, fibonacci spiral, islamic pattern, celtic knot, merkaba, fractal | Medium | Medium-high |
|
|
278
|
-
| **Sacred** | mandala, flower of life, tree of life, Metatron's cube, Sri Yantra, seed of life, vesica piscis, torus, egg of life | Low | High |
|
|
279
|
-
| **Procedural** | blob, ngon, lissajous, superellipse, spirograph, waveRing, rose | Medium (always present) | Medium-high |
|
|
374
|
+
### Per-Shape Pipeline
|
|
280
375
|
|
|
281
|
-
|
|
376
|
+
For each shape in a layer:
|
|
282
377
|
|
|
283
|
-
|
|
378
|
+
1. **Position:** Composition mode generates a candidate position, then `applyFocalBias` pulls it toward the nearest focal point
|
|
379
|
+
2. **Void check:** 85% skip chance if inside a void zone
|
|
380
|
+
3. **Density check:** If local density exceeds 15% of `shapesPerLayer`, 60% skip chance
|
|
381
|
+
4. **Size:** Power-curve distribution controlled by `archetype.sizePower` — higher values produce more small shapes
|
|
382
|
+
5. **Shape selection:** `pickShapeFromPalette` with size-constraint filtering
|
|
383
|
+
6. **Rotation:** Flow-field angle in flow-field mode (±15° jitter); random otherwise
|
|
384
|
+
7. **Hero avoidance:** Shapes within 1.5× the hero's size orient toward it (rotation blended 40% toward the angle-to-hero)
|
|
385
|
+
8. **Color:** Positional color from hierarchy + HSL jitter, with atmospheric desaturation and temperature contrast applied
|
|
386
|
+
9. **Contrast enforcement:** Fill and stroke colors checked against background luminance
|
|
387
|
+
10. **Styling:** Affinity-aware render style, optional glow (sacred shapes 45% base chance × archetype multiplier), optional radial gradient fill (30% chance)
|
|
388
|
+
11. **Organic edges:** 15% of `fill-and-stroke` shapes are promoted to `watercolor` style
|
|
389
|
+
12. **Light direction:** Non-glowing shapes get a subtle shadow offset along the consistent light angle
|
|
284
390
|
|
|
285
|
-
|
|
391
|
+
### 5a. Tangent Placement
|
|
286
392
|
|
|
287
|
-
-
|
|
288
|
-
- **Dark backgrounds** — foreground colors are lightened and saturated
|
|
393
|
+
~25% of shapes are nudged toward the nearest previously-placed shape so their edges "kiss." The algorithm finds the nearest shape, computes the target distance (sum of half-sizes), and repositions the current shape along the angle between them. This creates organic clustering where shapes feel intentionally arranged rather than randomly scattered.
|
|
289
394
|
|
|
290
|
-
|
|
395
|
+
### 5b. Shape Mirroring
|
|
291
396
|
|
|
292
|
-
|
|
397
|
+
Basic shapes (circle, triangle, square, hexagon, star, diamond, crescent, penroseTile, reuleauxTriangle) that are larger than 20% of max size have a ~40% chance of receiving a mirrored reflection. Four mirror axes are available:
|
|
293
398
|
|
|
294
|
-
|
|
399
|
+
| Axis | Probability | Effect |
|
|
400
|
+
| ---- | ----------- | ------ |
|
|
401
|
+
| horizontal | 15% | Reflected below with inverted rotation |
|
|
402
|
+
| vertical | 12% | Reflected to the right with 180° rotation offset |
|
|
403
|
+
| diagonal | 8% | Reflected along 45° axis with 90° rotation offset |
|
|
404
|
+
| radial-4 | 5% | Four copies at 90° intervals around the center |
|
|
295
405
|
|
|
296
|
-
|
|
406
|
+
The mirror copy is drawn at 70% opacity and 95% size (decreasing for radial-4), creating a subtle symmetry effect without perfect duplication.
|
|
297
407
|
|
|
298
|
-
|
|
408
|
+
### 5c. Size Echo
|
|
299
409
|
|
|
300
|
-
|
|
301
|
-
- **Color jitter** — ±8% RGB variation on fills, ±5% on strokes, so no two shapes using the "same" palette color are pixel-identical
|
|
302
|
-
- **Positional color** — fill color is biased by the shape's canvas position, creating smooth color flow
|
|
303
|
-
- **Glow effect** — 45% of sacred shapes and 20% of others get a `shadowBlur` glow (8-28px scaled), with glow color at 60% opacity
|
|
304
|
-
- **Gradient fill** — ~30% of shapes get a radial gradient between two jittered palette colors instead of a flat fill
|
|
305
|
-
- **Variable stroke width** — 0.5-2.5px scaled to canvas size
|
|
410
|
+
~20% of shapes larger than half `adjustedMaxSize` spawn 2–3 trailing copies along a random direction. Each echo is progressively smaller (30% → 22% → 14% of parent size) and more transparent, creating a motion-trail effect.
|
|
306
411
|
|
|
307
|
-
### Recursive Nesting
|
|
412
|
+
### 5d. Recursive Nesting
|
|
308
413
|
|
|
309
|
-
~15% of shapes larger than 40% of
|
|
310
|
-
- Inner shapes are drawn at the parent's position with small random offsets
|
|
311
|
-
- They use more complex/sacred shape types (layer ratio biased +0.3)
|
|
312
|
-
- Sized at 15-40% of the parent
|
|
313
|
-
- More transparent than the parent layer
|
|
414
|
+
~15% of shapes larger than 40% of `adjustedMaxSize` receive 1–3 inner shapes. Inner shapes are selected from the palette via `pickShapeFromPalette` at the nested size fraction, and styled with their own affinity-aware render style.
|
|
314
415
|
|
|
315
|
-
|
|
416
|
+
### 5e. Shape Constellations
|
|
316
417
|
|
|
317
|
-
|
|
418
|
+
~12% of shapes larger than 35% of `adjustedMaxSize` trigger a **constellation** — a pre-composed group of shapes placed as a unit. The entire group is rotated by a random angle for variety. Five constellation types are available:
|
|
318
419
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
-
|
|
322
|
-
|
|
323
|
-
-
|
|
324
|
-
-
|
|
420
|
+
| Constellation | Description |
|
|
421
|
+
| ------------- | ----------- |
|
|
422
|
+
| flanked-triangle | Central triangle with two smaller circles on either side |
|
|
423
|
+
| hexagon-ring | 5–6 hexagons arranged in a ring |
|
|
424
|
+
| spiral-dots | 7–11 circles spiraling outward with decreasing size |
|
|
425
|
+
| diamond-cluster | 4 diamonds in a cardinal arrangement with progressive rotation |
|
|
426
|
+
| crescent-pair | Two crescents facing each other |
|
|
325
427
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
428
|
+
Each member shape uses hierarchy colors with HSL jitter and affinity-aware render styles. Members that fall outside the canvas bounds are skipped.
|
|
429
|
+
|
|
430
|
+
## 10. Render Styles
|
|
431
|
+
|
|
432
|
+
Each shape is drawn using one of 15 render styles:
|
|
433
|
+
|
|
434
|
+
| Style | Description |
|
|
435
|
+
| ----- | ----------- |
|
|
436
|
+
| fill-and-stroke | Standard fill + outline (default) |
|
|
437
|
+
| fill-only | Solid fill, no outline |
|
|
438
|
+
| stroke-only | Ghost fill at 30% opacity + full outline |
|
|
439
|
+
| double-stroke | Fill + thick outer stroke at 50% opacity + thin inner stroke in fill color |
|
|
440
|
+
| dashed | Fill + dashed outline (dash = 5% of size, gap = 3%) |
|
|
441
|
+
| watercolor | Multi-pass: base wash (scaled up 8%), radial-bleed offset washes, edge darkening via inner lighter fill, delicate thin stroke |
|
|
442
|
+
| hatched | 30% opacity fill + clipped cross-hatch lines (parallel + optional perpendicular) + 50% opacity outline |
|
|
443
|
+
| incomplete | 25% opacity fill + long-dash stroke simulating a partially drawn outline (60–85% completeness) |
|
|
444
|
+
| stipple | Ghost fill at 15% + clipped dot grid with jittered positions and variable dot sizes |
|
|
445
|
+
| stencil | Negative-space cutout: fills a bounding rectangle, then erases the shape via destination-out compositing |
|
|
446
|
+
| noise-grain | 25% base tint + clipped procedural noise (random black/white dots at 15–50% opacity, variable sizes) |
|
|
447
|
+
| wood-grain | 20% base tint + clipped parallel wavy lines at a random angle, simulating wood texture |
|
|
448
|
+
| marble-vein | 35% soft base + clipped branching vein lines that drift and fork, simulating marble stone |
|
|
449
|
+
| fabric-weave | 15% ghost base + clipped interlocking horizontal and vertical thread lines at alternating opacities |
|
|
450
|
+
| hand-drawn | Fill + 2–3 wobbly offset stroke passes simulating a hand-drawn sketch |
|
|
451
|
+
|
|
452
|
+
### Texture Fill Details
|
|
453
|
+
|
|
454
|
+
The 4 new texture fills (noise-grain, wood-grain, marble-vein, fabric-weave) all work by:
|
|
455
|
+
1. Drawing a low-opacity base fill to tint the shape
|
|
456
|
+
2. Clipping to the shape boundary via `ctx.clip()`
|
|
457
|
+
3. Drawing the procedural texture pattern within the clipped region
|
|
458
|
+
4. Adding a subtle outline stroke on top
|
|
459
|
+
|
|
460
|
+
**noise-grain** scatters random-sized dots (black or white) across the shape at variable opacity, creating a film-grain or sandpaper texture. Dot spacing scales with shape size.
|
|
461
|
+
|
|
462
|
+
**wood-grain** draws parallel wavy lines at a random angle. The wave frequency (3–8 cycles) and amplitude (1–4% of size) create organic undulation. Line spacing is ~3.5% of shape size.
|
|
463
|
+
|
|
464
|
+
**marble-vein** draws 2–4 main veins that drift randomly downward, with ~20% chance per step of spawning a thinner branch vein. This creates the characteristic forking pattern of natural marble.
|
|
465
|
+
|
|
466
|
+
**fabric-weave** draws horizontal threads at full spacing, then vertical threads at half-spacing offsets, creating an over-under weave pattern. The two thread directions use different opacities (55% vs 45%) and colors (stroke vs fill) for visual distinction.
|
|
467
|
+
|
|
468
|
+
### Hand-Drawn Style
|
|
469
|
+
|
|
470
|
+
The `hand-drawn` style simulates a sketchy, imprecise outline:
|
|
471
|
+
|
|
472
|
+
1. **Base fill:** Standard fill of the shape
|
|
473
|
+
2. **Wobbly strokes (2–3 passes):** Each pass redraws the shape's outline with a small random offset (1–3px) and slightly varied line width, creating the impression of a hand tracing the same line multiple times
|
|
474
|
+
3. **Opacity variation:** Each pass uses 40–70% opacity so the overlapping strokes build up naturally
|
|
475
|
+
|
|
476
|
+
This style works particularly well on organic shapes (circle, triangle, blob) where the wobble feels intentional rather than broken.
|
|
477
|
+
|
|
478
|
+
### Layered Transparency / Glazing
|
|
479
|
+
|
|
480
|
+
~20% of shapes receive **glazing** — 2–3 additional fill-only passes drawn immediately after the main shape:
|
|
481
|
+
|
|
482
|
+
- Each pass is progressively smaller (85% → 72% → 61% of the original size)
|
|
483
|
+
- Each pass is progressively more opaque (adding 5–10% opacity per pass)
|
|
484
|
+
- Only the fill is redrawn (no stroke), creating a pigment-pooling effect where the center of the shape appears richer and more saturated
|
|
485
|
+
|
|
486
|
+
This simulates the traditional oil painting technique of building up translucent layers to create depth and luminosity.
|
|
487
|
+
|
|
488
|
+
### Motion / Energy Lines
|
|
489
|
+
|
|
490
|
+
Short directional line bursts radiate from shapes to suggest movement and energy:
|
|
491
|
+
|
|
492
|
+
- **Trigger:** Always for `dense-chaotic`, `cosmic`, `neon-glow`, and `bold-graphic` archetypes; ~25% random chance for others
|
|
493
|
+
- **Count:** 3–6 lines per shape
|
|
494
|
+
- **Length:** 8–20% of the shape's size
|
|
495
|
+
- **Direction:** Radiating outward from the shape center at evenly-spaced angles with ±15° jitter
|
|
496
|
+
- **Style:** Thin lines (0.5–1.5px) using the shape's stroke color at 15–35% opacity, tapering toward the ends
|
|
497
|
+
|
|
498
|
+
Motion lines are drawn after the main shape layers but before symmetry mirroring, so they participate in any bilateral/quad reflections.
|
|
499
|
+
|
|
500
|
+
### Watercolor Detail
|
|
501
|
+
|
|
502
|
+
The watercolor style simulates wet media through 4 passes:
|
|
503
|
+
1. **Base wash:** Shape drawn at 108% scale, 15% opacity — soft bleed beyond the boundary
|
|
504
|
+
2. **Offset washes:** 4–5 passes with radial displacement (random angle, up to 5% of size) — organic edge irregularity
|
|
505
|
+
3. **Edge darkening:** Shape drawn at 85–93% scale with lightened fill — simulates pigment pooling at boundaries where the inner area dries lighter
|
|
506
|
+
4. **Delicate stroke:** Thin outline (60% of normal width) at 25% opacity
|
|
507
|
+
|
|
508
|
+
## 11. Flow Lines
|
|
509
|
+
|
|
510
|
+
Flow lines follow a sinusoidal vector field defined by `flowAngle(x, y)`. The archetype's `flowLineMultiplier` controls count (0× = none, up to 4× = heavy).
|
|
511
|
+
|
|
512
|
+
Each flow line:
|
|
513
|
+
- Starts at a random position
|
|
514
|
+
- Takes 30–70 steps along the flow field (±0.3 radians jitter per step)
|
|
515
|
+
- **Variable color:** Interpolates between two hierarchy colors along the stroke length
|
|
516
|
+
- **Pressure simulation:** Line width oscillates sinusoidally (frequency 2–6 cycles, amplitude ±40%) to simulate pen pressure
|
|
517
|
+
- **Taper:** Width and opacity decrease toward the end (80% taper over the stroke length)
|
|
518
|
+
- **Branching:** ~12% chance per step (between steps 5 and N-10) to spawn a child stroke at ±0.3–0.8 radians, 40% width, 5–15 steps, 60% parent opacity
|
|
519
|
+
|
|
520
|
+
## 12. Post-Processing
|
|
521
|
+
|
|
522
|
+
After all shapes, flow lines, and symmetry mirroring:
|
|
523
|
+
|
|
524
|
+
### Noise Texture
|
|
525
|
+
|
|
526
|
+
Deterministic noise (separate RNG seeded from hash + salt 777) scatters single-pixel dots across the canvas. Density scales with canvas area (~1 dot per 800px²). Each dot is black or white at 1–4% opacity, adding subtle film grain.
|
|
527
|
+
|
|
528
|
+
### Vignette
|
|
529
|
+
|
|
530
|
+
A radial gradient darkens the edges: transparent at center, ramping to 25–45% black at the corners. This draws the eye inward toward the focal points.
|
|
531
|
+
|
|
532
|
+
### Organic Connecting Curves
|
|
533
|
+
|
|
534
|
+
Quadratic Bézier curves connect random pairs of placed shapes. The control point is offset perpendicular to the line between shapes by up to 40% of their distance, creating organic arcs. Count scales with canvas area (~8 per megapixel). Drawn at 6–16% opacity using hierarchy colors.
|
|
535
|
+
|
|
536
|
+
### Color Grading
|
|
537
|
+
|
|
538
|
+
A `soft-light` overlay in a single hue (random, 40% saturation, 50% lightness) at low intensity (grade intensity × 25% opacity). This unifies the image's color temperature — like applying a photo filter.
|
|
539
|
+
|
|
540
|
+
### Chromatic Aberration
|
|
541
|
+
|
|
542
|
+
Only for `neon-glow`, `cosmic`, and `ethereal` archetypes. The canvas is drawn onto itself with a small horizontal offset (±2px scaled) using `screen` compositing at 3% opacity. This creates a subtle RGB fringing effect at high-contrast edges.
|
|
543
|
+
|
|
544
|
+
### Bloom
|
|
545
|
+
|
|
546
|
+
Only for `neon-glow` and `cosmic` archetypes. The canvas is redrawn with `shadowBlur` at 30px (scaled) and white shadow color, composited via `screen` at 8% opacity. This creates a soft glow around bright areas.
|
|
547
|
+
|
|
548
|
+
## 13. Signature Mark
|
|
549
|
+
|
|
550
|
+
The final rendering step places a small deterministic **chop mark** (inspired by East Asian seal stamps) in the bottom-right corner of the canvas:
|
|
551
|
+
|
|
552
|
+
- **RNG isolation:** Uses a separate RNG seeded with a salt of 42, so the signature is independent of all other rendering decisions
|
|
553
|
+
- **Position:** Bottom-right corner with a small margin (3% of canvas size)
|
|
554
|
+
- **Size:** 1.5–2.5% of the shorter canvas dimension
|
|
555
|
+
- **Structure:**
|
|
556
|
+
1. Outer circle ring (stroke-only) at 12–20% opacity
|
|
557
|
+
2. 2–4 inner lines crossing the circle at unique angles derived from the hash, creating a distinctive geometric pattern
|
|
558
|
+
3. Center dot at slightly higher opacity
|
|
559
|
+
- **Color:** Uses the accent color from the hierarchy at very low opacity so it's visible but never distracting
|
|
330
560
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
A dedicated noise RNG (seeded separately from the main RNG to avoid affecting shape generation) renders thousands of 1px dots across the canvas:
|
|
334
|
-
|
|
335
|
-
- Density: ~1 dot per 800 square pixels
|
|
336
|
-
- Each dot is either black or white (50/50)
|
|
337
|
-
- Very low opacity (1-4%)
|
|
338
|
-
- Creates subtle film-grain texture that adds organic depth
|
|
339
|
-
|
|
340
|
-
## 9b. Vignette
|
|
341
|
-
|
|
342
|
-
A radial gradient overlay darkens the edges of the canvas, drawing the viewer's eye toward the center:
|
|
343
|
-
|
|
344
|
-
- Strength varies by hash: 25-45% maximum edge darkening
|
|
345
|
-
- The vignette begins fading at 60% of the canvas radius from center
|
|
346
|
-
- Applied after noise but before connecting curves, so the curves remain visible at edges
|
|
347
|
-
- Creates a natural "spotlight" effect that makes compositions feel more focused and photographic
|
|
348
|
-
|
|
349
|
-
## 10. Organic Connecting Curves
|
|
350
|
-
|
|
351
|
-
Quadratic bezier curves connect nearby shapes:
|
|
352
|
-
|
|
353
|
-
- Number of curves scales with canvas area (~8 per megapixel)
|
|
354
|
-
- Each curve connects two shapes that were drawn near each other in sequence
|
|
355
|
-
- Control points are offset perpendicular to the connecting line with random bulge
|
|
356
|
-
- Drawn at low opacity (6-16%) with palette colors at 30% alpha
|
|
357
|
-
|
|
358
|
-
## Shape Implementations
|
|
359
|
-
|
|
360
|
-
### Basic Shapes
|
|
361
|
-
Standard geometric primitives drawn as canvas paths (beginPath → moveTo/lineTo/arc → closePath). The draw pipeline calls `fill()` and `stroke()` after the path is defined.
|
|
362
|
-
|
|
363
|
-
### Complex Shapes
|
|
364
|
-
More intricate geometry including:
|
|
365
|
-
- **Platonic solids** — 2D projections with all edges drawn between vertices
|
|
366
|
-
- **Fibonacci spiral** — iterative arc segments following the golden ratio
|
|
367
|
-
- **Islamic pattern** — 8-pointed star grid at intersections
|
|
368
|
-
- **Celtic knot** — bezier over/under weaving pattern
|
|
369
|
-
- **Mandala** — concentric circles with radial lines
|
|
370
|
-
- **Fractal tree** — recursive branching at ±30° with 0.7× length decay
|
|
371
|
-
|
|
372
|
-
### Sacred Geometry
|
|
373
|
-
Mathematically precise sacred geometry patterns:
|
|
374
|
-
- **Flower of Life** — 7 overlapping circles in hexagonal arrangement
|
|
375
|
-
- **Tree of Life** — 10 Sephirot nodes with connecting paths
|
|
376
|
-
- **Metatron's Cube** — 13 vertices (center + inner/outer hexagons) fully connected
|
|
377
|
-
- **Sri Yantra** — 9 interlocking triangles at two radii
|
|
378
|
-
- **Seed of Life** — 7 circles (same as Flower of Life, different scale)
|
|
379
|
-
- **Vesica Piscis** — two overlapping circles
|
|
380
|
-
- **Torus** — 2D projection of a torus via line segments
|
|
381
|
-
- **Egg of Life** — 7 circles in tight hexagonal packing
|
|
382
|
-
|
|
383
|
-
### Procedural Shapes
|
|
384
|
-
Hash-derived shapes whose geometry is generated from the RNG. Every hash produces unique shapes that don't exist in any other generation:
|
|
385
|
-
|
|
386
|
-
| Shape | Algorithm | Hash Controls |
|
|
387
|
-
|-------|-----------|---------------|
|
|
388
|
-
| **Blob** | Smooth closed curve via quadratic bezier through 5-9 control points arranged around a circle | Number of lobes (5-9), radius jitter per lobe (50-100%) |
|
|
389
|
-
| **Ngon** | Irregular polygon with independent vertex displacement | Side count (3-12), vertex jitter amount (10-50%) |
|
|
390
|
-
| **Lissajous** | Parametric curve `x = sin(a*t + φ), y = sin(b*t)` | Frequency ratios a,b (1-5 each), phase offset φ |
|
|
391
|
-
| **Superellipse** | `|x|^n + |y|^n = 1` rendered parametrically | Exponent n: 0.3 (spiky astroid) → 2 (circle) → 5 (rounded rectangle) |
|
|
392
|
-
| **Spirograph** | Hypotrochoid curve `(R-r)cos(t) + d*cos((R-r)t/r)` | Inner radius ratio r (0.2-0.8), pen distance d (0.3-1.0) |
|
|
393
|
-
| **Wave Ring** | Concentric rings with sinusoidal radial displacement | Ring count (2-5), wave frequency (3-14), amplitude (5-20%) |
|
|
394
|
-
| **Rose** | Polar rose curve `r = cos(k*θ)` | Petal parameter k (2-7), producing k or 2k petals |
|
|
395
|
-
|
|
396
|
-
## Configuration
|
|
397
|
-
|
|
398
|
-
All parameters are exposed via `GenerationConfig`:
|
|
399
|
-
|
|
400
|
-
| Parameter | Default | Effect |
|
|
401
|
-
|-----------|---------|--------|
|
|
402
|
-
| `width` | 2048 | Canvas width in pixels |
|
|
403
|
-
| `height` | 2048 | Canvas height in pixels |
|
|
404
|
-
| `gridSize` | 5 | Base shape count = gridSize² × 1.5 |
|
|
405
|
-
| `layers` | 4 | Number of rendering layers |
|
|
406
|
-
| `minShapeSize` | 30 | Minimum shape size (scaled to canvas) |
|
|
407
|
-
| `maxShapeSize` | 400 | Maximum shape size (scaled to canvas) |
|
|
408
|
-
| `baseOpacity` | 0.7 | First layer opacity |
|
|
409
|
-
| `opacityReduction` | 0.12 | Opacity decay per layer |
|
|
410
|
-
| `shapesPerLayer` | auto | Override auto-calculated shape count |
|
|
561
|
+
The signature is unique per hash (different inner line patterns) but always recognizable as a chop mark, giving each generated image a subtle artist's stamp.
|