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.
@@ -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
- └─ Bloom (neon/cosmic only)
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. **Light direction:** Non-glowing shapes get a subtle shadow offset along the consistent light angle
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 4 passes:
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. **Delicate stroke:** Thin outline (60% of normal width) at 25% opacity
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 sinusoidal vector field defined by `flowAngle(x, y)`. The archetype's `flowLineMultiplier` controls count (0× = none, up to 4× = heavy).
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