git-hash-art 0.10.0 → 0.10.1
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/.github/workflows/deploy-www.yml +47 -0
- package/ALGORITHM.md +108 -8
- package/CHANGELOG.md +10 -0
- package/dist/browser.js +518 -13
- package/dist/browser.js.map +1 -1
- package/dist/main.js +518 -13
- package/dist/main.js.map +1 -1
- package/dist/module.js +518 -13
- package/dist/module.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/archetypes.ts +4 -1
- package/src/lib/canvas/colors.ts +45 -0
- package/src/lib/canvas/draw.ts +84 -5
- package/src/lib/render.ts +255 -10
- package/src/lib/utils.ts +109 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Deploy git-hash-art-www
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
bump-www:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Extract version from release tag
|
|
12
|
+
id: version
|
|
13
|
+
run: |
|
|
14
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
15
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
16
|
+
|
|
17
|
+
- name: Clone git-hash-art-www
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
repository: gfargo/git-hash-art-www
|
|
21
|
+
token: ${{ secrets.WWW_DEPLOY_PAT }}
|
|
22
|
+
path: www
|
|
23
|
+
|
|
24
|
+
- name: Setup Node.js
|
|
25
|
+
uses: actions/setup-node@v4
|
|
26
|
+
with:
|
|
27
|
+
node-version: 20
|
|
28
|
+
|
|
29
|
+
- name: Install pnpm
|
|
30
|
+
uses: pnpm/action-setup@v4
|
|
31
|
+
with:
|
|
32
|
+
run_install: false
|
|
33
|
+
|
|
34
|
+
- name: Update git-hash-art dependency
|
|
35
|
+
working-directory: www
|
|
36
|
+
run: |
|
|
37
|
+
pnpm install git-hash-art@${{ steps.version.outputs.version }}
|
|
38
|
+
|
|
39
|
+
- name: Commit and push
|
|
40
|
+
working-directory: www
|
|
41
|
+
run: |
|
|
42
|
+
git config user.name "github-actions[bot]"
|
|
43
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
44
|
+
git add package.json pnpm-lock.yaml
|
|
45
|
+
git diff --cached --quiet && echo "No changes to commit" && exit 0
|
|
46
|
+
git commit -m "chore: bump git-hash-art to v${{ steps.version.outputs.version }}"
|
|
47
|
+
git push
|
package/ALGORITHM.md
CHANGED
|
@@ -31,11 +31,12 @@ Hash String
|
|
|
31
31
|
1a. Background Luminance → contrast enforcement threshold
|
|
32
32
|
1b. Layered Background (archetype-coherent shapes + concentric rings)
|
|
33
33
|
1c. Background Pattern Layer (dot grid / diagonal lines / tessellation)
|
|
34
|
-
2. Composition Mode Selection
|
|
34
|
+
2. Composition Mode Selection (6 modes including golden-spiral)
|
|
35
35
|
2b. Symmetry Mode Selection (none / bilateral / quad)
|
|
36
36
|
3. Focal Points (rule-of-thirds biased) + Void Zones
|
|
37
37
|
3b. Void Zone Decoration (halos, scattered dots, concentric rings)
|
|
38
|
-
4. Flow Field Initialization
|
|
38
|
+
4. Flow Field Initialization (simplex noise FBM)
|
|
39
|
+
4a. Noise Size Modulation (terrain-like size variation from noise field)
|
|
39
40
|
4b. Hero Shape (palette-aware, affinity-styled)
|
|
40
41
|
5. Shape Layers (× N layers, archetype-tuned)
|
|
41
42
|
│ ├─ Blend Mode (per-layer compositing)
|
|
@@ -50,24 +51,28 @@ Hash String
|
|
|
50
51
|
│ ├─ Atmospheric Depth (desaturation on later layers)
|
|
51
52
|
│ ├─ Temperature Contrast (foreground opposite to background)
|
|
52
53
|
│ ├─ Styling (transparency, glow, gradients, HSL jitter)
|
|
54
|
+
│ ├─ Shadow & Highlight (drop shadow + specular highlight per shape)
|
|
53
55
|
│ ├─ Organic Edges (~15% watercolor bleed)
|
|
56
|
+
│ ├─ Edge Erosion (watercolor + hand-drawn styles get irregular boundary bites)
|
|
54
57
|
│ ├─ 5a. Tangent Placement (~25% nudge toward nearest shape edge)
|
|
55
58
|
│ ├─ 5b. Shape Mirroring (~40% of basic shapes get reflected copies)
|
|
56
59
|
│ ├─ 5c. Size Echo (~20% of large shapes spawn trailing copies)
|
|
57
60
|
│ ├─ 5d. Recursive Nesting (~15% of large shapes, palette-aware)
|
|
58
61
|
│ └─ 5e. Shape Constellations (~12% of large shapes, pre-composed groups)
|
|
62
|
+
5f. Layered Masking / Cutout Portals (~18% of images)
|
|
59
63
|
6. Flow-Line Pass (variable color, pressure, branching)
|
|
60
64
|
6b. Motion/Energy Lines (directional bursts from shapes)
|
|
61
65
|
6c. Layered Transparency / Glazing (~20% of shapes get multi-pass redraws)
|
|
62
66
|
7. Symmetry Mirroring (bilateral-x, bilateral-y, or quad)
|
|
63
|
-
7. Symmetry Mirroring (bilateral-x, bilateral-y, or quad)
|
|
64
67
|
8. Noise Texture Overlay
|
|
65
68
|
9. Vignette (radial edge darkening)
|
|
66
69
|
10. Organic Connecting Curves
|
|
67
70
|
11. Post-Processing
|
|
68
71
|
├─ Color Grading (unified tone overlay)
|
|
69
72
|
├─ Chromatic Aberration (neon/cosmic/ethereal only)
|
|
70
|
-
|
|
73
|
+
├─ Bloom (neon/cosmic only)
|
|
74
|
+
└─ Gradient Map (~35% chance, luminance-mapped two-color overlay)
|
|
75
|
+
11b. Generative Borders (archetype-driven decorative frames)
|
|
71
76
|
12. Signature Mark (deterministic geometric chop mark)
|
|
72
77
|
```
|
|
73
78
|
|
|
@@ -82,6 +87,16 @@ rng() → float in [0, 1)
|
|
|
82
87
|
|
|
83
88
|
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.
|
|
84
89
|
|
|
90
|
+
### Simplex Noise Field
|
|
91
|
+
|
|
92
|
+
In addition to the scalar RNG, the pipeline creates a **2D simplex noise** function seeded from the hash (with a separate salt so it's independent of the main RNG stream). This produces smooth, organic spatial variation across the canvas.
|
|
93
|
+
|
|
94
|
+
The raw simplex noise is layered into **Fractal Brownian Motion (FBM)** with 3 octaves (lacunarity 2.0, gain 0.5), which adds multi-scale detail — large sweeping gradients overlaid with finer turbulence.
|
|
95
|
+
|
|
96
|
+
The noise field drives two systems:
|
|
97
|
+
- **Flow field angles:** `flowAngle(x, y)` samples the FBM at each position, producing organic, non-repeating directional fields. This replaces the old sinusoidal field which produced visible periodic patterns.
|
|
98
|
+
- **Size modulation:** `noiseSizeModulation(x, y)` samples the raw simplex noise to create terrain-like size variation (0.7×–1.3×). Shapes in "high noise" regions are larger; shapes in "low noise" regions are smaller. This creates natural density clusters without explicit clustering logic.
|
|
99
|
+
|
|
85
100
|
## 2. Archetype System
|
|
86
101
|
|
|
87
102
|
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.
|
|
@@ -161,6 +176,17 @@ Color generation uses the `color-scheme` library seeded from the hash, then appl
|
|
|
161
176
|
| pastel-light | Soft pastels on light backgrounds |
|
|
162
177
|
| earth | Muted warm naturals |
|
|
163
178
|
| high-contrast | Black + white + one accent color |
|
|
179
|
+
| split-complementary | Base hue + two colors flanking the complement (±30°) |
|
|
180
|
+
| analogous-accent | Tight cluster of 3 analogous hues + 1 distant accent |
|
|
181
|
+
| limited-palette | Only 3 colors — risograph-print feel |
|
|
182
|
+
|
|
183
|
+
### New Harmony Mode Details
|
|
184
|
+
|
|
185
|
+
**split-complementary** — Instead of a single complement (180° opposite), this mode uses two colors at ±30° from the complement. This creates strong contrast like complementary schemes but with more nuance and less visual tension. The base hue gets a tint variant for 5 total colors.
|
|
186
|
+
|
|
187
|
+
**analogous-accent** — Three hues within a tight 30–70° arc (15–35° step between each) create a harmonious, low-contrast base. A single accent color at 150–210° away provides a pop of contrast. This produces compositions that feel cohesive with one surprising element.
|
|
188
|
+
|
|
189
|
+
**limited-palette** — Only 3 colors total, spaced roughly 120° apart with slight randomization. Mimics the look of risograph or screen-printed art where ink colors are limited. The constraint forces the hierarchy system to work harder, producing bold, graphic compositions.
|
|
164
190
|
|
|
165
191
|
### Color Hierarchy
|
|
166
192
|
|
|
@@ -311,6 +337,13 @@ Each image uses one of 5 composition strategies for shape placement:
|
|
|
311
337
|
| grid-subdivision | Canvas divided into 3–5 cells; shapes placed within random cells |
|
|
312
338
|
| clustered | 3–5 cluster centers; shapes scatter around the nearest cluster |
|
|
313
339
|
| flow-field | Uniform random placement (rotation driven by flow field) |
|
|
340
|
+
| golden-spiral | Shapes placed along a logarithmic golden-angle spiral from center outward |
|
|
341
|
+
|
|
342
|
+
### Golden Spiral Detail
|
|
343
|
+
|
|
344
|
+
The `golden-spiral` mode uses the **golden angle** (~137.5°) to space shapes around the center. Each shape's angular position is `index × goldenAngle` with slight random jitter (±0.3 radians). The radial distance uses a square-root distribution (`√(t) × maxRadius`) which ensures even area coverage — shapes don't bunch up at the center or leave gaps at the edges.
|
|
345
|
+
|
|
346
|
+
This produces the same phyllotactic pattern seen in sunflower seed heads and pinecone spirals. Combined with the size power curve, it creates compositions where large shapes anchor the center and smaller shapes spiral outward in a naturally pleasing arrangement.
|
|
314
347
|
|
|
315
348
|
### Symmetry
|
|
316
349
|
|
|
@@ -386,7 +419,27 @@ For each shape in a layer:
|
|
|
386
419
|
9. **Contrast enforcement:** Fill and stroke colors checked against background luminance
|
|
387
420
|
10. **Styling:** Affinity-aware render style, optional glow (sacred shapes 45% base chance × archetype multiplier), optional radial gradient fill (30% chance)
|
|
388
421
|
11. **Organic edges:** 15% of `fill-and-stroke` shapes are promoted to `watercolor` style
|
|
389
|
-
12. **
|
|
422
|
+
12. **Shadow & highlight:** Each shape receives a directional drop shadow and specular highlight based on the consistent light angle (see below)
|
|
423
|
+
|
|
424
|
+
### Shadow & Highlight System
|
|
425
|
+
|
|
426
|
+
Every shape receives lighting effects based on a single consistent light direction (random angle, fixed for the entire image):
|
|
427
|
+
|
|
428
|
+
**Drop Shadow:**
|
|
429
|
+
- Offset: 3.5% of shape size along the opposite of the light direction
|
|
430
|
+
- Blur radius: 6% of shape size
|
|
431
|
+
- Color: `rgba(0,0,0,0.12)` — subtle enough to add depth without muddying colors
|
|
432
|
+
- Applied via Canvas `shadowOffset` + `shadowBlur` properties before the shape is drawn
|
|
433
|
+
- Shapes with glow effects use the glow instead (no double-shadow)
|
|
434
|
+
|
|
435
|
+
**Specular Highlight:**
|
|
436
|
+
- Position: 15% of shape size along the light direction from center
|
|
437
|
+
- Radius: 35% of shape size
|
|
438
|
+
- Gradient: white at 18% opacity → 5% → 0% (radial falloff)
|
|
439
|
+
- Composited via `soft-light` to interact naturally with the shape's fill color
|
|
440
|
+
- Only applied to shapes larger than 15px (tiny shapes don't benefit)
|
|
441
|
+
|
|
442
|
+
The combination creates a subtle 3D effect where shapes appear to float above the background, with consistent lighting across the entire composition.
|
|
390
443
|
|
|
391
444
|
### 5a. Tangent Placement
|
|
392
445
|
|
|
@@ -427,6 +480,20 @@ The mirror copy is drawn at 70% opacity and 95% size (decreasing for radial-4),
|
|
|
427
480
|
|
|
428
481
|
Each member shape uses hierarchy colors with HSL jitter and affinity-aware render styles. Members that fall outside the canvas bounds are skipped.
|
|
429
482
|
|
|
483
|
+
### 5f. Layered Masking / Cutout Portals
|
|
484
|
+
|
|
485
|
+
~18% of images receive 1–3 **portal cutouts** — shape-sized windows that paint over the foreground layers with a background wash, creating a "peek through" depth effect.
|
|
486
|
+
|
|
487
|
+
The process for each portal:
|
|
488
|
+
|
|
489
|
+
1. **Position:** Biased toward an existing placed shape (with slight random offset), so portals appear in visually active areas rather than empty space
|
|
490
|
+
2. **Shape:** Selected from the shape palette at the portal's size fraction, so the cutout shape is palette-coherent
|
|
491
|
+
3. **Clip and fill:** The shape is used as a clip region, then a radial gradient (derived from the background colors with HSL jitter) is painted over the foreground at 60–95% opacity. This "erases" the foreground shapes within the portal boundary and replaces them with a soft background wash
|
|
492
|
+
4. **Inner texture (~50%):** Tiny scattered dots inside the portal at low opacity add subtle depth to the wash
|
|
493
|
+
5. **Border ring:** A subtle stroke outline at 106% of the portal size (15–35% opacity) frames the window, drawn outside the clip so it sits on top of everything
|
|
494
|
+
|
|
495
|
+
The variable opacity (60–95%) means some portals are translucent peeks while others fully reveal the background, creating varied depth effects without punching actual transparent holes in the canvas.
|
|
496
|
+
|
|
430
497
|
## 10. Render Styles
|
|
431
498
|
|
|
432
499
|
Each shape is drawn using one of 15 render styles:
|
|
@@ -499,15 +566,23 @@ Motion lines are drawn after the main shape layers but before symmetry mirroring
|
|
|
499
566
|
|
|
500
567
|
### Watercolor Detail
|
|
501
568
|
|
|
502
|
-
The watercolor style simulates wet media through
|
|
569
|
+
The watercolor style simulates wet media through 5 passes:
|
|
503
570
|
1. **Base wash:** Shape drawn at 108% scale, 15% opacity — soft bleed beyond the boundary
|
|
504
571
|
2. **Offset washes:** 4–5 passes with radial displacement (random angle, up to 5% of size) — organic edge irregularity
|
|
505
572
|
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. **
|
|
573
|
+
4. **Edge erosion:** 6–14 small circular bites erased along the shape boundary using `destination-out` compositing at 60–90% opacity. Bites are placed at 85–110% of the shape's edge radius with sizes 2–6% of the shape, creating the irregular, feathered edges characteristic of real watercolor on textured paper
|
|
574
|
+
5. **Delicate stroke:** Thin outline (60% of normal width) at 25% opacity
|
|
575
|
+
|
|
576
|
+
### Hand-Drawn Edge Erosion
|
|
577
|
+
|
|
578
|
+
The `hand-drawn` style also receives organic edge erosion after its wobbly stroke passes:
|
|
579
|
+
- 4–10 small circular bites erased along the boundary at 90–110% of the edge radius
|
|
580
|
+
- Bite sizes are slightly smaller than watercolor (1.5–4.5% of shape size) for a rougher, torn-paper feel
|
|
581
|
+
- Combined with the wobbly multi-pass strokes, this creates shapes that look like they were drawn on rough paper with a slightly dry pen
|
|
507
582
|
|
|
508
583
|
## 11. Flow Lines
|
|
509
584
|
|
|
510
|
-
Flow lines follow a
|
|
585
|
+
Flow lines follow a **simplex noise** vector field defined by `flowAngle(x, y)`. The field is generated from a seeded 2D simplex noise function layered with 3-octave Fractal Brownian Motion (FBM) for organic, non-repeating patterns. The archetype's `flowLineMultiplier` controls count (0× = none, up to 4× = heavy).
|
|
511
586
|
|
|
512
587
|
Each flow line:
|
|
513
588
|
- Starts at a random position
|
|
@@ -545,6 +620,31 @@ Only for `neon-glow`, `cosmic`, and `ethereal` archetypes. The canvas is drawn o
|
|
|
545
620
|
|
|
546
621
|
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
622
|
|
|
623
|
+
### Gradient Map
|
|
624
|
+
|
|
625
|
+
~35% of images receive a **gradient map** post-processing pass — a technique borrowed from Photoshop that maps the image's luminance through a two-color gradient:
|
|
626
|
+
|
|
627
|
+
- **Dark color:** The hierarchy's dominant color
|
|
628
|
+
- **Light color:** The hierarchy's accent color
|
|
629
|
+
- **Application:** A linear gradient (top = dark, bottom = light) is painted over the entire canvas using `color` compositing mode at 6–12% opacity
|
|
630
|
+
- **Effect:** Shadows take on the dominant color's hue while highlights shift toward the accent, creating a cohesive tonal relationship across the entire image
|
|
631
|
+
|
|
632
|
+
The `color` blend mode only affects hue and saturation (not luminance), so the gradient map tints the image without changing its brightness structure. At 6–12% opacity, the effect is subtle — it unifies the color temperature without overpowering the original palette.
|
|
633
|
+
|
|
634
|
+
### Generative Borders
|
|
635
|
+
|
|
636
|
+
After all post-processing, archetype-appropriate decorative borders are drawn to frame the composition. The border style is keyed on the archetype name, with a separate RNG (seeded with salt 314) for deterministic border patterns:
|
|
637
|
+
|
|
638
|
+
| Archetype Group | Border Style |
|
|
639
|
+
| --------------- | ------------ |
|
|
640
|
+
| geometric, op-art, shattered-glass | Clean ruled double lines with corner ornaments (small squares with diagonal crosses) |
|
|
641
|
+
| botanical, organic-flow, watercolor-wash | Organic vine tendrils curling inward from edges, with small leaf dots at tendril ends |
|
|
642
|
+
| celestial, cosmic, neon-glow | Subtle arcs along top/bottom edges + scattered 4-point stars in the border region |
|
|
643
|
+
| minimal, monochrome-ink, stipple-portrait | Single thin rule — understated elegance |
|
|
644
|
+
| Others | No border (intentional — not every image needs framing) |
|
|
645
|
+
|
|
646
|
+
Border elements use hierarchy colors at very low opacity (10–25%) so they frame without competing with the main composition. The border padding is 2.5% of the shorter canvas dimension.
|
|
647
|
+
|
|
548
648
|
## 13. Signature Mark
|
|
549
649
|
|
|
550
650
|
The final rendering step places a small deterministic **chop mark** (inspired by East Asian seal stamps) in the bottom-right corner of the canvas:
|
package/CHANGELOG.md
CHANGED
|
@@ -4,10 +4,20 @@ 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.10.1](https://github.com/gfargo/git-hash-art/compare/0.10.0...0.10.1)
|
|
8
|
+
|
|
9
|
+
- feat: shadow/highlight system, generative borders, gradient map, edge erosion [`#19`](https://github.com/gfargo/git-hash-art/pull/19)
|
|
10
|
+
- feat: simplex noise flow fields, color harmony modes, golden spiral composition, layered masking [`#18`](https://github.com/gfargo/git-hash-art/pull/18)
|
|
11
|
+
- fix: portal cutouts use clip-and-fill instead of destination-out [`aecdd14`](https://github.com/gfargo/git-hash-art/commit/aecdd14c0d5ddf52d0394c714d2815679263b961)
|
|
12
|
+
- add GitHub Actions workflow for deployment [`4a6ac42`](https://github.com/gfargo/git-hash-art/commit/4a6ac426d1678f5ff83cbe4c4ddc9ce2a2a0c260)
|
|
13
|
+
|
|
7
14
|
#### [0.10.0](https://github.com/gfargo/git-hash-art/compare/0.9.0...0.10.0)
|
|
8
15
|
|
|
16
|
+
> 19 March 2026
|
|
17
|
+
|
|
9
18
|
- feat: color palette evolution, edge treatment, glazing, motion lines, archetype blending, focal depth, signature mark [`#17`](https://github.com/gfargo/git-hash-art/pull/17)
|
|
10
19
|
- feat: color palette evolution, edge treatment, negative space, glazing, motion lines, archetype blending, focal depth, signature mark [`b496771`](https://github.com/gfargo/git-hash-art/commit/b49677108ae170fef9c1108d40d7db6995efb48c)
|
|
20
|
+
- chore: release v0.10.0 [`38f1d2e`](https://github.com/gfargo/git-hash-art/commit/38f1d2e3b60c921b651be9319e685f77df1ad93b)
|
|
11
21
|
|
|
12
22
|
#### [0.9.0](https://github.com/gfargo/git-hash-art/compare/0.8.0...0.9.0)
|
|
13
23
|
|