@caddis/cli 0.0.0 → 0.1.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/LICENSE +21 -0
- package/README.md +150 -1
- package/bundles/antigravity-plugin/agents/code-reviewer.md +47 -0
- package/bundles/antigravity-plugin/agents/preflight.md +53 -0
- package/bundles/antigravity-plugin/guard_agy.py +338 -0
- package/bundles/antigravity-plugin/hooks.json +36 -0
- package/bundles/antigravity-plugin/mcp_config.json +8 -0
- package/bundles/antigravity-plugin/mcp_ping_server.py +55 -0
- package/bundles/antigravity-plugin/plugin.json +5 -0
- package/bundles/antigravity-plugin/session_end_agy.py +57 -0
- package/bundles/antigravity-plugin/skills/_registry.md +115 -0
- package/bundles/antigravity-plugin/skills/add-rules/SKILL.md +45 -0
- package/bundles/antigravity-plugin/skills/api-design/SKILL.md +249 -0
- package/bundles/antigravity-plugin/skills/backend-development/SKILL.md +305 -0
- package/bundles/antigravity-plugin/skills/best-practices/SKILL.md +500 -0
- package/bundles/antigravity-plugin/skills/best-practices/agents/best-practices-referencer.md +263 -0
- package/bundles/antigravity-plugin/skills/best-practices/agents/codebase-context-builder.md +326 -0
- package/bundles/antigravity-plugin/skills/best-practices/agents/task-intent-analyzer.md +245 -0
- package/bundles/antigravity-plugin/skills/best-practices/references/anti-patterns.md +571 -0
- package/bundles/antigravity-plugin/skills/best-practices/references/before-after-examples.md +1114 -0
- package/bundles/antigravity-plugin/skills/best-practices/references/best-practices-guide.md +513 -0
- package/bundles/antigravity-plugin/skills/best-practices/references/common-workflows.md +692 -0
- package/bundles/antigravity-plugin/skills/best-practices/references/prompt-patterns.md +547 -0
- package/bundles/antigravity-plugin/skills/brainstorming/SKILL.md +57 -0
- package/bundles/antigravity-plugin/skills/ci-cd-pipeline/SKILL.md +315 -0
- package/bundles/antigravity-plugin/skills/code-documentation/SKILL.md +271 -0
- package/bundles/antigravity-plugin/skills/code-review/SKILL.md +122 -0
- package/bundles/antigravity-plugin/skills/codebase-audit/SKILL.md +204 -0
- package/bundles/antigravity-plugin/skills/context-curator/SKILL.md +157 -0
- package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +40 -0
- package/bundles/antigravity-plugin/skills/css-architecture/SKILL.md +305 -0
- package/bundles/antigravity-plugin/skills/css-architecture/references/RESPONSIVE-DESIGN.md +604 -0
- package/bundles/antigravity-plugin/skills/database-design/SKILL.md +177 -0
- package/bundles/antigravity-plugin/skills/db-diagram/SKILL.md +148 -0
- package/bundles/antigravity-plugin/skills/db-diagram/scripts/sql_to_graph.py +1212 -0
- package/bundles/antigravity-plugin/skills/digress/SKILL.md +61 -0
- package/bundles/antigravity-plugin/skills/draw-io/SKILL.md +162 -0
- package/bundles/antigravity-plugin/skills/draw-io/references/aws-icons.md +677 -0
- package/bundles/antigravity-plugin/skills/draw-io/references/layout-guidelines.md +142 -0
- package/bundles/antigravity-plugin/skills/draw-io/references/troubleshooting.md +118 -0
- package/bundles/antigravity-plugin/skills/draw-io/references/workflows.md +103 -0
- package/bundles/antigravity-plugin/skills/draw-io/scripts/convert-drawio-to-png.sh +25 -0
- package/bundles/antigravity-plugin/skills/draw-io/scripts/find_aws_icon.py +79 -0
- package/bundles/antigravity-plugin/skills/error-handling/SKILL.md +260 -0
- package/bundles/antigravity-plugin/skills/excalidraw-db/SKILL.md +38 -0
- package/bundles/antigravity-plugin/skills/fastapi-dev/SKILL.md +300 -0
- package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +198 -0
- package/bundles/antigravity-plugin/skills/frontend-design/SKILL.md +193 -0
- package/bundles/antigravity-plugin/skills/frontend-design/references/my-tech-stack.md +127 -0
- package/bundles/antigravity-plugin/skills/gh-cli/SKILL.md +195 -0
- package/bundles/antigravity-plugin/skills/git-commit/SKILL.md +285 -0
- package/bundles/antigravity-plugin/skills/golden-plan/SKILL.md +577 -0
- package/bundles/antigravity-plugin/skills/handoff/SKILL.md +100 -0
- package/bundles/antigravity-plugin/skills/implement/SKILL.md +114 -0
- package/bundles/antigravity-plugin/skills/javascript-typescript/SKILL.md +142 -0
- package/bundles/antigravity-plugin/skills/kb/SKILL.md +60 -0
- package/bundles/antigravity-plugin/skills/mermaid-db/SKILL.md +33 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/SKILL.md +236 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/ENHANCEMENTS.md +264 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/MERMAID-SUMMARY.md +137 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/advanced-features.md +556 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/architecture-diagrams.md +192 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/c4-diagrams.md +410 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/class-diagrams.md +361 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/erd-diagrams.md +510 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/flowcharts.md +450 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/sequence-diagrams.md +394 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/troubleshooting.md +335 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/workflows.md +418 -0
- package/bundles/antigravity-plugin/skills/migrate-dir/SKILL.md +68 -0
- package/bundles/antigravity-plugin/skills/mockup/SKILL.md +242 -0
- package/bundles/antigravity-plugin/skills/particle-art/SKILL.md +243 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/canvas-utils.ts +171 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/dot-field.template.tsx +203 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/flow-field.template.tsx +263 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/node-shape.template.tsx +261 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/shape-sampler.ts +281 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/stipple-morph.template.tsx +167 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/stipple.template.tsx +175 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/trail-ghost.template.tsx +266 -0
- package/bundles/antigravity-plugin/skills/particle-art/references/usage-examples.md +320 -0
- package/bundles/antigravity-plugin/skills/playwright/API_REFERENCE.md +653 -0
- package/bundles/antigravity-plugin/skills/playwright/SKILL.md +454 -0
- package/bundles/antigravity-plugin/skills/playwright/lib/helpers.js +441 -0
- package/bundles/antigravity-plugin/skills/playwright/package.json +26 -0
- package/bundles/antigravity-plugin/skills/playwright/run.js +228 -0
- package/bundles/antigravity-plugin/skills/prd/SKILL.md +107 -0
- package/bundles/antigravity-plugin/skills/preflight/SKILL.md +435 -0
- package/bundles/antigravity-plugin/skills/python/SKILL.md +388 -0
- package/bundles/antigravity-plugin/skills/react-best-practices/SKILL.md +269 -0
- package/bundles/antigravity-plugin/skills/react-dev/README.md +404 -0
- package/bundles/antigravity-plugin/skills/react-dev/SKILL.md +459 -0
- package/bundles/antigravity-plugin/skills/react-dev/examples/generic-components.md +579 -0
- package/bundles/antigravity-plugin/skills/react-dev/examples/server-components.md +579 -0
- package/bundles/antigravity-plugin/skills/react-dev/references/event-handlers.md +574 -0
- package/bundles/antigravity-plugin/skills/react-dev/references/hooks.md +456 -0
- package/bundles/antigravity-plugin/skills/react-dev/references/react-19-patterns.md +638 -0
- package/bundles/antigravity-plugin/skills/react-dev/references/react-router.md +1002 -0
- package/bundles/antigravity-plugin/skills/react-dev/references/tanstack-router.md +587 -0
- package/bundles/antigravity-plugin/skills/refactoring/SKILL.md +486 -0
- package/bundles/antigravity-plugin/skills/resume/SKILL.md +36 -0
- package/bundles/antigravity-plugin/skills/security-review/SKILL.md +196 -0
- package/bundles/antigravity-plugin/skills/setup-project-ai/SKILL.md +61 -0
- package/bundles/antigravity-plugin/skills/ship/SKILL.md +107 -0
- package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +103 -0
- package/bundles/antigravity-plugin/skills/ship-pr/SKILL.md +102 -0
- package/bundles/antigravity-plugin/skills/skill-creator/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin/skills/skill-creator/SKILL.md +491 -0
- package/bundles/antigravity-plugin/skills/skill-creator/agents/analyzer.md +274 -0
- package/bundles/antigravity-plugin/skills/skill-creator/agents/comparator.md +202 -0
- package/bundles/antigravity-plugin/skills/skill-creator/agents/grader.md +223 -0
- package/bundles/antigravity-plugin/skills/skill-creator/assets/eval_review.html +146 -0
- package/bundles/antigravity-plugin/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/bundles/antigravity-plugin/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/bundles/antigravity-plugin/skills/skill-creator/references/schemas.md +430 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/__init__.py +0 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/generate_report.py +326 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/improve_description.py +247 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/package_skill.py +136 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/run_eval.py +310 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/run_loop.py +328 -0
- package/bundles/antigravity-plugin/skills/skill-creator/scripts/utils.py +47 -0
- package/bundles/antigravity-plugin/skills/sql/SKILL.md +321 -0
- package/bundles/antigravity-plugin/skills/tdd/SKILL.md +37 -0
- package/bundles/antigravity-plugin/skills/tdd-workflow/SKILL.md +188 -0
- package/bundles/antigravity-plugin/skills/technical-writing/SKILL.md +286 -0
- package/bundles/antigravity-plugin/skills/test-strategy/SKILL.md +155 -0
- package/bundles/antigravity-plugin/skills/ui-brief/SKILL.md +84 -0
- package/bundles/antigravity-plugin/skills/ui-review/SKILL.md +176 -0
- package/bundles/antigravity-plugin/skills/ui-review/references/framework-fixes.md +471 -0
- package/bundles/antigravity-plugin/skills/ui-review/references/visual-checklist.md +236 -0
- package/bundles/antigravity-plugin/skills/usage-review/SKILL.md +77 -0
- package/bundles/antigravity-plugin/skills/use-model/SKILL.md +64 -0
- package/bundles/antigravity-plugin/skills/using-git-worktrees/SKILL.md +217 -0
- package/bundles/antigravity-plugin/skills/version/SKILL.md +18 -0
- package/bundles/antigravity-plugin/skills/warm-editorial-ui/DESIGN_TOKENS.md +487 -0
- package/bundles/antigravity-plugin/skills/warm-editorial-ui/IMPLEMENTATION_GUIDE.md +177 -0
- package/bundles/antigravity-plugin/skills/warm-editorial-ui/SKILL.md +732 -0
- package/bundles/antigravity-plugin/skills/webapp-testing/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin/skills/webapp-testing/SKILL.md +97 -0
- package/bundles/antigravity-plugin/skills/webapp-testing/examples/console_logging.py +35 -0
- package/bundles/antigravity-plugin/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/bundles/antigravity-plugin/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/bundles/antigravity-plugin/skills/webapp-testing/scripts/with_server.py +106 -0
- package/bundles/antigravity-plugin/skills/windows-deployment/SKILL.md +880 -0
- package/bundles/antigravity-plugin/skills/writing-plans/SKILL.md +384 -0
- package/bundles/antigravity-plugin/statusline-command-agy.sh +91 -0
- package/bundles/antigravity-plugin/warm_start_agy.py +149 -0
- package/bundles/manifest.json +6 -0
- package/dist/cli.js +5363 -0
- package/package.json +61 -4
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Particle Art — Usage Examples
|
|
2
|
+
|
|
3
|
+
Real configurations with descriptions of what they produce. Use these as a reference before
|
|
4
|
+
delivering a component to verify your output looks right.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Example 1 — Lowercase "j" brand mark (NodeJ.tsx)
|
|
9
|
+
|
|
10
|
+
**Shape:** Single letter "j"
|
|
11
|
+
**Style:** spring-nodes
|
|
12
|
+
**Size:** 300px
|
|
13
|
+
**Colors:** CSS vars (dark: teal mint, light: dark teal)
|
|
14
|
+
**Interaction:** repel
|
|
15
|
+
|
|
16
|
+
### What it produces
|
|
17
|
+
- 13 stem nodes stacked vertically, centered horizontally
|
|
18
|
+
- 9 hook nodes curving left and back up via cubic bezier
|
|
19
|
+
- 1 tittle node at the top with a slow pulsing ring
|
|
20
|
+
- 16 ambient halo nodes floating in an elliptical orbit around the letter
|
|
21
|
+
- On mouse hover: nodes scatter outward, spring back smoothly when cursor leaves
|
|
22
|
+
- The letter shape is always visible even during mouse scatter — spring force is strong enough
|
|
23
|
+
|
|
24
|
+
### Physics values used
|
|
25
|
+
```ts
|
|
26
|
+
const LINK = 72;
|
|
27
|
+
const FRICTION = 0.88; // strong damping for letter nodes
|
|
28
|
+
const AMBIENT_FRICTION = 0.985;
|
|
29
|
+
const REPEL_R = 85;
|
|
30
|
+
const REPEL_F = 0.5;
|
|
31
|
+
const DRIFT = 0.06;
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Bezier hook definition
|
|
35
|
+
```ts
|
|
36
|
+
const P0 = [cx, stemBot];
|
|
37
|
+
const P1 = [cx, stemBot + size * 0.115]; // control: extend down
|
|
38
|
+
const P2 = [cx - size * 0.115, stemBot + size * 0.145]; // control: curve left
|
|
39
|
+
const P3 = [cx - size * 0.155, stemBot + size * 0.040]; // end: curl back up
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Example 2 — Abstract neural node cloud (NodeCluster.tsx)
|
|
45
|
+
|
|
46
|
+
**Shape:** abstract (no fixed targets)
|
|
47
|
+
**Style:** spring-nodes (ambient only)
|
|
48
|
+
**Size:** 360px
|
|
49
|
+
**Colors:** CSS vars
|
|
50
|
+
**Interaction:** repel
|
|
51
|
+
|
|
52
|
+
### What it produces
|
|
53
|
+
- 32 free-floating nodes with mild random drift
|
|
54
|
+
- Dense connection web — links form and break as nodes wander
|
|
55
|
+
- Mouse sends nodes scattering; they slowly drift back
|
|
56
|
+
- No fixed shape — pure kinetic energy
|
|
57
|
+
|
|
58
|
+
### Physics values used
|
|
59
|
+
```ts
|
|
60
|
+
const N = 32;
|
|
61
|
+
const LINK = 82;
|
|
62
|
+
const MAX_SPEED = 1.5;
|
|
63
|
+
const FRICTION = 0.984;
|
|
64
|
+
const REPEL_R = 90;
|
|
65
|
+
const REPEL_F = 0.55;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Example 3 — Stipple halftone dot portrait (StippleGlyph.tsx)
|
|
71
|
+
|
|
72
|
+
**Shape:** Gaussian density grid
|
|
73
|
+
**Style:** stipple
|
|
74
|
+
**Size:** determined by COLS × ROWS (not a fixed px size)
|
|
75
|
+
**Colors:** CSS vars
|
|
76
|
+
**Interaction:** none (scan wave + breathing)
|
|
77
|
+
|
|
78
|
+
### What it produces
|
|
79
|
+
- 26 × 20 = 520 Unicode character spans (●, •, ·)
|
|
80
|
+
- Gaussian falloff: dense ● at centre, dispersing · at edges
|
|
81
|
+
- Scan wave sweeps outward every 8 seconds (480 frames @ 60fps)
|
|
82
|
+
- Each dot has an independent breathing oscillation (opacity 0.04–0.14 amplitude)
|
|
83
|
+
- ✦ glyph floats above the grid, pulsing gently
|
|
84
|
+
|
|
85
|
+
### GRID construction
|
|
86
|
+
```ts
|
|
87
|
+
const base = Math.exp(-(dist * dist) / (2 * 0.28 * 0.28));
|
|
88
|
+
const jitter = srand(xi * 53, yi * 97) * 0.12 - 0.06;
|
|
89
|
+
v = clamp(base + jitter, 0, 1);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Example 4 — Gaussian dot field with sparks (DotField.tsx)
|
|
95
|
+
|
|
96
|
+
**Shape:** abstract Gaussian cloud
|
|
97
|
+
**Style:** dot-field
|
|
98
|
+
**Size:** 260px
|
|
99
|
+
**Colors:** CSS vars (inner → --accent-strong, outer → --accent-soft)
|
|
100
|
+
**Interaction:** repel + spring-back
|
|
101
|
+
|
|
102
|
+
### What it produces
|
|
103
|
+
- 120 canvas dots, Box-Muller distributed around centre (σ = 0.28)
|
|
104
|
+
- Inner dots bright (accent-strong), outer dots dim (accent-soft), linearly blended
|
|
105
|
+
- Sparks: 1.2% chance per frame to spawn a tiny bright dot near centre that drifts outward and fades
|
|
106
|
+
- Max 8 concurrent sparks
|
|
107
|
+
- Mouse pushes nearest dots away; they spring back at 8% per frame (gradual, elastic feel)
|
|
108
|
+
- ✦ as an HTML span centered over canvas (stays crisp, scales independently)
|
|
109
|
+
|
|
110
|
+
### Colour blend
|
|
111
|
+
```ts
|
|
112
|
+
const t = Math.min(1, d.distRatio * 1.6);
|
|
113
|
+
const r = sr + (lr - sr) * t; // interpolate R
|
|
114
|
+
const g = sg + (lg - sg) * t; // interpolate G
|
|
115
|
+
const b = sb + (lb - sb) * t; // interpolate B
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Example 5 — "JS" initials (using shape-sampler sampleText)
|
|
121
|
+
|
|
122
|
+
**Shape:** text "JS"
|
|
123
|
+
**Style:** spring-nodes
|
|
124
|
+
**Size:** 380px
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
// In buildTargets():
|
|
128
|
+
const pts = sampleText("JS", size, { nodeCount: 40, font: "bold 160px sans-serif" });
|
|
129
|
+
return pts.map(([tx, ty]) => ({
|
|
130
|
+
tx, ty, spring: 0.030, r: 2.0, alpha: 0.88, isDot: false
|
|
131
|
+
}));
|
|
132
|
+
// Add ambient: ambientCount={10}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Physics:** use Short word row from SKILL.md table (spring 0.030, friction 0.90)
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Example 6 — Constellation preset
|
|
140
|
+
|
|
141
|
+
**Shape:** constellation
|
|
142
|
+
**Style:** spring-nodes
|
|
143
|
+
**Size:** 340px
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { sampleConstellation } from "./shape-sampler";
|
|
147
|
+
|
|
148
|
+
function buildTargets(size: number) {
|
|
149
|
+
return sampleConstellation(size, 32).map(([tx, ty]) => ({
|
|
150
|
+
tx, ty, spring: 0.012, r: 1.8, alpha: 0.75, isDot: false
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
// ambientCount={6}, LINK=90, FRICTION=0.94
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Produces a loose ring of 20 outer nodes + 12 inner cluster nodes.
|
|
157
|
+
Nodes drift slowly (low spring 0.012), giving a star-field feel.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Example 7 — Stipple Morph (StippleMorph.tsx)
|
|
164
|
+
|
|
165
|
+
**Shape:** Halftone cloud → letter "j" on hover
|
|
166
|
+
**Style:** stipple-morph
|
|
167
|
+
**Size:** determined by COLS × ROWS
|
|
168
|
+
**Colors:** CSS vars (--accent-strong)
|
|
169
|
+
**Interaction:** mousemove → cloud resolves into letter; mouseleave → drifts back
|
|
170
|
+
|
|
171
|
+
### What it produces
|
|
172
|
+
- 24 × 18 = 432 Unicode dot spans, each with an independently computed opacity
|
|
173
|
+
- Idle: Gaussian cloud + breathing oscillation + scan wave sweep every 8 seconds
|
|
174
|
+
- Hover: dots rearrange opacity to match a letter sampled from an off-screen canvas (Grid B)
|
|
175
|
+
- Morph lerps at 0.045/frame — smooth 1-second transition
|
|
176
|
+
- Grid B oversamples at 8× (192 × 144 px) and averages per cell, then boosts contrast ×2.2
|
|
177
|
+
- Breathing amplitude fades to 15% at full morph so the letter reads clearly
|
|
178
|
+
|
|
179
|
+
### Tunable constants
|
|
180
|
+
```ts
|
|
181
|
+
const COLS = 24, ROWS = 18; // increase for denser dot field
|
|
182
|
+
const SCAN_PERIOD = 480; // frames between scan sweeps
|
|
183
|
+
const MORPH_SPEED = 0.045; // lerp rate per frame; 0.03 = slower, dreamier
|
|
184
|
+
|
|
185
|
+
function buildLetterGrid(text: string) {
|
|
186
|
+
const S = 8; // oversample factor; 6–10 works well
|
|
187
|
+
// font sizing auto-fits one character; for multi-char reduce to COLS*S*0.35
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Import and usage
|
|
192
|
+
```tsx
|
|
193
|
+
import { StippleMorphArt } from "@/components/art/StippleMorph";
|
|
194
|
+
|
|
195
|
+
<StippleMorphArt text="j" /> // single character
|
|
196
|
+
<StippleMorphArt text="JS" /> // initials (auto-sizes font)
|
|
197
|
+
<StippleMorphArt text="AI" className="mt-4" />
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Example 8 — Trail Ghost (TrailGhost.tsx)
|
|
203
|
+
|
|
204
|
+
**Shape:** Scattered cloud → letter "j" on hover
|
|
205
|
+
**Style:** trail-ghost
|
|
206
|
+
**Size:** 280px
|
|
207
|
+
**Colors:** CSS vars
|
|
208
|
+
**Interaction:** mousemove → nodes fly to letter leaving glowing smears; mouseleave → drift apart
|
|
209
|
+
|
|
210
|
+
### What it produces
|
|
211
|
+
- 23 letter nodes (same "j" bezier as NodeJ) starting scattered around centre
|
|
212
|
+
- 10 ambient atmosphere nodes drifting in a loose orbit
|
|
213
|
+
- Each node records a trail of up to 50 positions per frame; each position fades at 0.91× per frame
|
|
214
|
+
- Canvas uses `fillStyle = "rgba(0,0,0,0.10)"` instead of `clearRect` — old frames decay naturally, creating ghosted smears
|
|
215
|
+
- On hover: spring force engages, nodes race toward targets trailing bright streaks
|
|
216
|
+
- Tittle node has extra pulsing glow ring when morph > 0.15
|
|
217
|
+
|
|
218
|
+
### Key technique — canvas persistence ghost
|
|
219
|
+
```ts
|
|
220
|
+
// Instead of: ctx.clearRect(0, 0, size, size)
|
|
221
|
+
ctx.fillStyle = "rgba(0,0,0,0.10)"; // 10% fill each frame → 10-frame decay
|
|
222
|
+
ctx.fillRect(0, 0, size, size);
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Tunable constants
|
|
226
|
+
```ts
|
|
227
|
+
const TRAIL_DECAY = 0.91; // per-frame alpha multiplier: 0.80 = shorter, 0.96 = longer
|
|
228
|
+
const TRAIL_MAX = 50; // trail history length per node; increase for longer tails
|
|
229
|
+
const MORPH_SPEED = 0.05; // faster snap than other components
|
|
230
|
+
const IDLE_FRICTION = 0.984;
|
|
231
|
+
const ACTIVE_FRICTION = 0.88;
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Import and usage
|
|
235
|
+
```tsx
|
|
236
|
+
import { TrailGhostArt } from "@/components/art/TrailGhost";
|
|
237
|
+
|
|
238
|
+
<TrailGhostArt size={280} />
|
|
239
|
+
<TrailGhostArt size={360} /> // larger for hero sections
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Example 9 — Flow Field (FlowField.tsx)
|
|
245
|
+
|
|
246
|
+
**Shape:** Noise-driven particle streams → letter "j" on hover
|
|
247
|
+
**Style:** flow-field
|
|
248
|
+
**Size:** 280px
|
|
249
|
+
**Colors:** CSS vars
|
|
250
|
+
**Interaction:** mousemove → flow currents bend toward letter targets; mouseleave → particles disperse back into streams
|
|
251
|
+
|
|
252
|
+
### What it produces
|
|
253
|
+
- 23 letter particles + 22 ambient flow-only particles (45 total)
|
|
254
|
+
- Idle: all particles follow 2-octave value-noise angle field — organic river/smoke behaviour
|
|
255
|
+
- Hover: spring forces toward letter targets compete with flow field; morph controls the blend
|
|
256
|
+
- At m=0: pure noise, particles wander freely
|
|
257
|
+
- At m=1: 75% spring + 25% noise — letter forms with a residual alive quality
|
|
258
|
+
- Particles drawn as velocity-aligned streaks (tail length ∝ speed) — shows flow direction
|
|
259
|
+
- Edge wrapping (particle exits right → re-enters left) disabled during morph to let letter hold shape
|
|
260
|
+
- Ambient particles never spring; they perpetually flow
|
|
261
|
+
|
|
262
|
+
### 2D value noise implementation
|
|
263
|
+
```ts
|
|
264
|
+
function vnoise(x: number, y: number): number {
|
|
265
|
+
// Smoothstep bilinear interpolation of sin-hashed corner values
|
|
266
|
+
const ix = Math.floor(x), iy = Math.floor(y);
|
|
267
|
+
const fx = x - ix, fy = y - iy;
|
|
268
|
+
const ux = fx*fx*(3-2*fx), uy = fy*fy*(3-2*fy);
|
|
269
|
+
const h = (a: number, b: number) => (Math.abs(Math.sin(a*127.1 + b*311.7)*43758.5453)) % 1;
|
|
270
|
+
const aa=h(ix,iy), ba=h(ix+1,iy), ab=h(ix,iy+1), bb=h(ix+1,iy+1);
|
|
271
|
+
return aa + (ba-aa)*ux + (ab-aa)*uy + (aa-ba-ab+bb)*ux*uy;
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Tunable constants
|
|
276
|
+
```ts
|
|
277
|
+
const FLOW_FORCE = 0.06; // noise field push: raise for wilder currents
|
|
278
|
+
const FRICTION = 0.965; // less damping than spring → particles glide
|
|
279
|
+
const MORPH_SPEED = 0.048; // slightly slower than TrailGhost for dreamier assembly
|
|
280
|
+
const LINK = 80; // connection line threshold; lines strengthen as letter forms
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Import and usage
|
|
284
|
+
```tsx
|
|
285
|
+
import { FlowFieldArt } from "@/components/art/FlowField";
|
|
286
|
+
|
|
287
|
+
<FlowFieldArt size={280} />
|
|
288
|
+
<FlowFieldArt size={400} /> // larger = more visible noise patterns
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Placement Pattern (Next.js App Router hero section)
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
// page.tsx (server component — no "use client")
|
|
297
|
+
import { MyArt } from "@/components/art/MyArt";
|
|
298
|
+
|
|
299
|
+
export default function Page() {
|
|
300
|
+
return (
|
|
301
|
+
<div className="flex flex-col lg:flex-row lg:items-center lg:gap-16">
|
|
302
|
+
{/* Text content */}
|
|
303
|
+
<div className="flex-1 min-w-0">
|
|
304
|
+
<h1>...</h1>
|
|
305
|
+
</div>
|
|
306
|
+
|
|
307
|
+
{/* Art — desktop only, fades in after text */}
|
|
308
|
+
<div
|
|
309
|
+
className="hidden lg:flex shrink-0 items-center justify-center animate-fade-up"
|
|
310
|
+
style={{ animationDelay: "0.35s" }}
|
|
311
|
+
>
|
|
312
|
+
<MyArt size={360} />
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The `hidden lg:flex` keeps the canvas off mobile where layout space is tight.
|
|
320
|
+
The `animate-fade-up` + delay staggers the art in after the headline text.
|