bluedither 1.0.17 → 1.0.19
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/fine-tuner/dev-middleware.js +6 -3
- package/fine-tuner/inject.js +3 -1
- package/package.json +1 -1
- package/theme/generators/react.md +111 -43
|
@@ -18,17 +18,20 @@ import { resolve, dirname } from 'path';
|
|
|
18
18
|
const ENDPOINT = '/__bluedither/commit';
|
|
19
19
|
|
|
20
20
|
function findTokensPath() {
|
|
21
|
-
// Search from cwd
|
|
21
|
+
// Search from cwd — prioritize public/ (Vite serves static from there)
|
|
22
22
|
const cwd = process.cwd();
|
|
23
23
|
const paths = [
|
|
24
|
-
resolve(cwd, 'bluedither', 'tokens.json'),
|
|
25
24
|
resolve(cwd, 'public', 'bluedither', 'tokens.json'),
|
|
25
|
+
resolve(cwd, 'bluedither', 'tokens.json'),
|
|
26
26
|
resolve(cwd, 'theme', 'tokens.json'),
|
|
27
27
|
];
|
|
28
28
|
for (const p of paths) {
|
|
29
29
|
if (existsSync(p)) return p;
|
|
30
30
|
}
|
|
31
|
-
// Default to bluedither/
|
|
31
|
+
// Default to public/bluedither if public/ dir exists (Vite project), else bluedither/
|
|
32
|
+
if (existsSync(resolve(cwd, 'public'))) {
|
|
33
|
+
return resolve(cwd, 'public', 'bluedither', 'tokens.json');
|
|
34
|
+
}
|
|
32
35
|
return resolve(cwd, 'bluedither', 'tokens.json');
|
|
33
36
|
}
|
|
34
37
|
|
package/fine-tuner/inject.js
CHANGED
|
@@ -111,7 +111,9 @@
|
|
|
111
111
|
if (t.shader?.scale != null) params.scale = t.shader.scale;
|
|
112
112
|
if (t.shader?.size != null) params.size = t.shader.size;
|
|
113
113
|
if (t.shader?.rotation != null) params.rotation = t.shader.rotation;
|
|
114
|
-
shader.updateParams
|
|
114
|
+
if (typeof shader.updateParams === 'function') {
|
|
115
|
+
shader.updateParams(params);
|
|
116
|
+
}
|
|
115
117
|
return true;
|
|
116
118
|
};
|
|
117
119
|
|
package/package.json
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
When the target project uses **React** (detected via `react` in package.json dependencies), follow these patterns.
|
|
4
4
|
|
|
5
|
+
## CRITICAL: File Placement Rules
|
|
6
|
+
|
|
7
|
+
**In `src/` (importable source files):**
|
|
8
|
+
- All `.jsx`/`.tsx` component files
|
|
9
|
+
- `bluedither.css` — CSS custom properties + rules
|
|
10
|
+
- `paper-shaders-bundle.js` — copied from `bluedither/shaders/`
|
|
11
|
+
- Any other JS modules that are `import`-ed
|
|
12
|
+
|
|
13
|
+
**In `public/bluedither/` (static assets loaded at runtime):**
|
|
14
|
+
- `bluedither-tuner.js` — tuner panel
|
|
15
|
+
- `bluedither-tuner.css` — tuner styles
|
|
16
|
+
- `bluedither-tuner-inject.js` — tuner loader
|
|
17
|
+
- `tokens.json` — design tokens (read at runtime by tuner)
|
|
18
|
+
- `tokens.defaults.json` — default tokens
|
|
19
|
+
- `dev-middleware.js` — Vite commit endpoint
|
|
20
|
+
|
|
21
|
+
**NEVER import JS files from `public/` — Vite will error.** Shader files MUST be in `src/`.
|
|
22
|
+
|
|
23
|
+
Copy shader files during generation:
|
|
24
|
+
```bash
|
|
25
|
+
cp bluedither/shaders/paper-shaders-bundle.js src/paper-shaders-bundle.js
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Copy tuner assets to public:
|
|
29
|
+
```bash
|
|
30
|
+
mkdir -p public/bluedither
|
|
31
|
+
cp bluedither/bluedither-tuner.js public/bluedither/
|
|
32
|
+
cp bluedither/bluedither-tuner.css public/bluedither/
|
|
33
|
+
cp bluedither/bluedither-tuner-inject.js public/bluedither/
|
|
34
|
+
cp bluedither/tokens.json public/bluedither/
|
|
35
|
+
cp bluedither/tokens.defaults.json public/bluedither/
|
|
36
|
+
cp bluedither/dev-middleware.js public/bluedither/
|
|
37
|
+
```
|
|
38
|
+
|
|
5
39
|
## Detection
|
|
6
40
|
|
|
7
41
|
React is detected when `package.json` contains `react` in `dependencies` or `devDependencies`. Also check for:
|
|
@@ -11,76 +45,110 @@ React is detected when `package.json` contains `react` in `dependencies` or `dev
|
|
|
11
45
|
|
|
12
46
|
## Component Structure
|
|
13
47
|
|
|
14
|
-
Generate
|
|
48
|
+
Generate all component files in `src/`:
|
|
15
49
|
|
|
16
|
-
### `
|
|
17
|
-
Root component wrapping the full layout. Imports and
|
|
50
|
+
### `src/App.jsx` (or modify existing)
|
|
51
|
+
Root component wrapping the full layout. Imports shader, CSS, and loads tuner in dev mode.
|
|
18
52
|
|
|
19
53
|
```jsx
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
54
|
+
import { useEffect, useRef } from 'react';
|
|
55
|
+
import { ShaderMount, ditheringFragmentShader, DitheringShapes, DitheringTypes, getShaderColorFromString } from './paper-shaders-bundle.js';
|
|
22
56
|
import './bluedither.css';
|
|
23
57
|
|
|
24
|
-
|
|
58
|
+
// Content from tokens.json content section
|
|
59
|
+
const CONTENT = { /* ... */ };
|
|
60
|
+
|
|
61
|
+
// Shader params from tokens.json shader + colors sections
|
|
62
|
+
const SHADER_PARAMS = { /* ... */ };
|
|
63
|
+
|
|
64
|
+
function App() {
|
|
65
|
+
const shaderRef = useRef(null);
|
|
66
|
+
|
|
67
|
+
// Initialize shader
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!shaderRef.current) return;
|
|
70
|
+
const mount = new ShaderMount(shaderRef.current, ditheringFragmentShader, {
|
|
71
|
+
u_colorFront: getShaderColorFromString(SHADER_PARAMS.colorFront),
|
|
72
|
+
u_colorBack: getShaderColorFromString(SHADER_PARAMS.colorBack),
|
|
73
|
+
u_shape: DitheringShapes[SHADER_PARAMS.shape] ?? DitheringShapes.warp,
|
|
74
|
+
u_type: DitheringTypes[SHADER_PARAMS.type] ?? DitheringTypes['2x2'],
|
|
75
|
+
u_pxSize: SHADER_PARAMS.size,
|
|
76
|
+
u_scale: SHADER_PARAMS.scale,
|
|
77
|
+
u_rotation: SHADER_PARAMS.rotation,
|
|
78
|
+
u_originX: 0.5, u_originY: 0.5,
|
|
79
|
+
u_worldWidth: 0, u_worldHeight: 0,
|
|
80
|
+
u_fit: 0, u_offsetX: 0, u_offsetY: 0,
|
|
81
|
+
}, { alpha: true, premultipliedAlpha: false }, SHADER_PARAMS.speed, 0, 2);
|
|
82
|
+
|
|
83
|
+
// CRITICAL: expose wrapper with updateParams for the tuner
|
|
84
|
+
window.__BD_SHADER__ = {
|
|
85
|
+
updateParams(params) {
|
|
86
|
+
const uniforms = {};
|
|
87
|
+
if (params.colorFront !== undefined) uniforms.u_colorFront = getShaderColorFromString(params.colorFront);
|
|
88
|
+
if (params.colorBack !== undefined) uniforms.u_colorBack = getShaderColorFromString(params.colorBack);
|
|
89
|
+
if (params.shape !== undefined) uniforms.u_shape = DitheringShapes[params.shape] ?? DitheringShapes.warp;
|
|
90
|
+
if (params.type !== undefined) uniforms.u_type = DitheringTypes[params.type] ?? DitheringTypes['2x2'];
|
|
91
|
+
if (params.size !== undefined) uniforms.u_pxSize = params.size;
|
|
92
|
+
if (params.scale !== undefined) uniforms.u_scale = params.scale;
|
|
93
|
+
if (params.rotation !== undefined) uniforms.u_rotation = parseFloat(params.rotation) || 180;
|
|
94
|
+
if (Object.keys(uniforms).length > 0) mount.setUniforms(uniforms);
|
|
95
|
+
if (params.speed !== undefined) mount.setSpeed(params.speed);
|
|
96
|
+
},
|
|
97
|
+
dispose() { mount.dispose(); },
|
|
98
|
+
};
|
|
99
|
+
return () => { window.__BD_SHADER__.dispose(); window.__BD_SHADER__ = null; };
|
|
100
|
+
}, []);
|
|
101
|
+
|
|
102
|
+
// Load tuner in dev mode only
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (import.meta.env.DEV) {
|
|
105
|
+
const s = document.createElement('script');
|
|
106
|
+
s.src = '/bluedither/bluedither-tuner-inject.js';
|
|
107
|
+
document.body.appendChild(s);
|
|
108
|
+
return () => s.remove();
|
|
109
|
+
}
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
25
112
|
return (
|
|
26
113
|
<div className="bd-root">
|
|
27
|
-
<
|
|
28
|
-
|
|
114
|
+
<div className="bd-hero">
|
|
115
|
+
<div className="bd-hero-inner">
|
|
116
|
+
<div className="bd-shader-layer" ref={shaderRef} />
|
|
117
|
+
{/* hero content */}
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<header className="bd-header">
|
|
121
|
+
{/* header content */}
|
|
122
|
+
</header>
|
|
29
123
|
</div>
|
|
30
124
|
);
|
|
31
125
|
}
|
|
32
126
|
```
|
|
33
127
|
|
|
34
|
-
|
|
35
|
-
Navbar component with logo, nav items, and CTA.
|
|
128
|
+
Note: The shader uses `ShaderMount` directly from `paper-shaders-bundle.js` — do NOT create a separate shader wrapper module. Import `ShaderMount`, `ditheringFragmentShader`, `DitheringShapes`, `DitheringTypes`, and `getShaderColorFromString` directly.
|
|
36
129
|
|
|
37
|
-
|
|
38
|
-
- Use `<nav>` with `<a>` elements for nav items
|
|
39
|
-
- CTA is an `<a>` or `<button>` element
|
|
130
|
+
The `window.__BD_SHADER__` assignment is **required** — the tuner calls `updateParams()` on it for live shader editing. The ShaderMount instance has `setUniforms()` and `setSpeed()` methods. The tuner's `updateParams` maps token names to uniform names (e.g., `colorFront` → `u_colorFront`).
|
|
40
131
|
|
|
41
|
-
### `
|
|
42
|
-
|
|
132
|
+
### `src/bluedither.css`
|
|
133
|
+
All CSS custom properties and `.bd-*` class rules.
|
|
43
134
|
|
|
44
|
-
|
|
45
|
-
```jsx
|
|
46
|
-
import { useEffect, useRef } from 'react';
|
|
47
|
-
|
|
48
|
-
const shaderRef = useRef(null);
|
|
135
|
+
## Vite Config
|
|
49
136
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
window.__BD_SHADER__ = mount;
|
|
55
|
-
return () => { mount.dispose(); window.__BD_SHADER__ = null; };
|
|
56
|
-
});
|
|
57
|
-
}, []);
|
|
137
|
+
The `npx bluedither install` command auto-wires the Vite plugin. If it wasn't auto-wired, add manually:
|
|
138
|
+
```js
|
|
139
|
+
import { bluedither } from './bluedither/dev-middleware.js'
|
|
140
|
+
export default defineConfig({ plugins: [react(), bluedither()] })
|
|
58
141
|
```
|
|
59
142
|
|
|
60
|
-
### `bluedither.css`
|
|
61
|
-
All CSS custom properties and `.bd-*` class rules, identical to the vanilla `<style>` block but as an external file.
|
|
62
|
-
|
|
63
143
|
## TypeScript
|
|
64
144
|
|
|
65
145
|
If TypeScript is detected, use `.tsx` extensions and add minimal type annotations:
|
|
66
|
-
- Props interfaces where components accept props
|
|
67
146
|
- `useRef<HTMLDivElement>(null)` for refs
|
|
68
147
|
|
|
69
148
|
## Next.js
|
|
70
149
|
|
|
71
150
|
If Next.js is detected:
|
|
72
151
|
- Add `"use client"` at the top of components that use `useEffect` or `useRef`
|
|
73
|
-
- The CSS file can be imported directly in the component
|
|
74
|
-
|
|
75
|
-
## File Output
|
|
76
|
-
|
|
77
|
-
| File | Contents |
|
|
78
|
-
|------|----------|
|
|
79
|
-
| `BlueDitherTheme.jsx/tsx` | Root layout component |
|
|
80
|
-
| `BlueDitherHeader.jsx/tsx` | Navbar component |
|
|
81
|
-
| `BlueDitherHero.jsx/tsx` | Hero + shader component |
|
|
82
|
-
| `bluedither.css` | CSS custom properties + rules |
|
|
83
|
-
| `paper-shaders-bundle.js` | Shader library (copied) |
|
|
84
152
|
|
|
85
153
|
## Content Handling
|
|
86
154
|
|