@dstackai/sqircle 0.1.0 → 0.1.2
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/README.md +174 -17
- package/dist/SquircleEditor.d.ts +5 -2
- package/dist/codeExport.d.ts +4 -2
- package/dist/index.d.ts +3 -2
- package/dist/palettes.d.ts +1 -0
- package/dist/sqircle.js +1295 -374
- package/dist/sqircle.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types.d.ts +2 -0
- package/docs/README.md +12 -7
- package/docs/design/README.md +2 -1
- package/docs/design/colors.md +23 -33
- package/docs/design/geometry.md +14 -13
- package/docs/design/rendering.md +72 -19
- package/docs/design/single-squircle-states.md +47 -109
- package/docs/examples/README.md +33 -0
- package/docs/react/README.md +106 -62
- package/docs/react/editor.md +162 -0
- package/package.json +3 -2
package/docs/design/README.md
CHANGED
|
@@ -6,13 +6,14 @@ Read these files when changing how a squircle looks. They are visual contracts s
|
|
|
6
6
|
| --- | --- |
|
|
7
7
|
| [geometry.md](./geometry.md) | Superellipse sampling, projection, side-wall visibility, layer offsets, regeneration checklist |
|
|
8
8
|
| [rendering.md](./rendering.md) | Gradients, edge sharpness, draw order, dashed inlay, text path and paint rules |
|
|
9
|
-
| [colors.md](./colors.md) |
|
|
9
|
+
| [colors.md](./colors.md) | Alpha palettes, text contrast colors, edge colors, hover palette rules |
|
|
10
10
|
| [single-squircle-states.md](./single-squircle-states.md) | Reusable one-squircle state recipes for solid, transparent, wireframe, text, dash, and text + dash |
|
|
11
11
|
|
|
12
12
|
## Design Source Of Truth
|
|
13
13
|
|
|
14
14
|
- Geometry is generated from math, not hand-edited point lists.
|
|
15
15
|
- Filled faces use user-space gradients plus tiny in-family edge strokes.
|
|
16
|
+
- Solid faces can use `off`, `fluid`, or `frosted` top-surface effects without moving geometry.
|
|
16
17
|
- Wireframe faces use gradient strokes with matching top and bottom curves.
|
|
17
18
|
- React top-plane text is one live SVG text element in every mode. Static fixtures keep a single compound `GPU` path for their fixed example.
|
|
18
19
|
- Solid/transparent annotations use contrast colors; wireframe annotations use wire gradients.
|
package/docs/design/colors.md
CHANGED
|
@@ -4,15 +4,11 @@ This file is the palette contract for variants, gradients, text labels, and edge
|
|
|
4
4
|
|
|
5
5
|
## Sources Of Truth
|
|
6
6
|
|
|
7
|
-
Colors are defined in
|
|
7
|
+
Colors are defined in `src/squircle/palettes.ts` and consumed by `SquircleScene`. The root HTML files are Vite shells and do not own gradient stops. Keep these synchronized:
|
|
8
8
|
|
|
9
|
-
1.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- `side-13..side-20`
|
|
13
|
-
2. CSS variables in `public/static/styles.css`:
|
|
14
|
-
- Selected-variant selectors for `.hero-card` and `.single-drawer`
|
|
15
|
-
- `.v13..v20` classes for variant cards
|
|
9
|
+
1. `SQUIRCLE_PALETTES`: alpha palettes `13..20`.
|
|
10
|
+
2. Renderer docs in `README.md` and `docs/react/README.md`.
|
|
11
|
+
3. This design file.
|
|
16
12
|
|
|
17
13
|
Do not add or rename a variant in only one place.
|
|
18
14
|
|
|
@@ -45,7 +41,7 @@ The text surface gradient repeats the matching `top-*` stops with label-local co
|
|
|
45
41
|
|
|
46
42
|
## CSS Variable Contract
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
Legacy static snapshots used CSS variables such as `--top-fill` and `--side-fill`. New React work should not edit those snapshots as source of truth. If a legacy static snapshot must be refreshed, keep every selected-variant selector targeting both `.hero-card` and `.single-drawer`:
|
|
49
45
|
|
|
50
46
|
```css
|
|
51
47
|
#variant-15:checked ~ .hero-card,
|
|
@@ -76,41 +72,41 @@ Variant classes may also define fallback ghost colors, but those must remain vis
|
|
|
76
72
|
|
|
77
73
|
## Hover Palettes
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
React examples and generated code can use any palette id as a layer's hover `paletteId`. The base variant keeps its normal palette, and the hover variant receives its own `paletteId`. This means hover color changes use the same documented gradients, label contrast, and wireframe stroke colors as normal rendering.
|
|
80
76
|
|
|
81
|
-
Do not implement hover color with filters, opacity hacks, or untracked ad hoc colors. Hover color is a normal palette swap. `
|
|
77
|
+
Do not implement hover color with filters, opacity hacks, or untracked ad hoc colors. Hover color is a normal palette swap. Hover `paletteId` may be the same id as the base `paletteId`; that is useful when hover should change only material while preserving color. If the resolved hover variant matches the base variant, `SquircleScene` should not render or crossfade a hover copy.
|
|
82
78
|
|
|
83
79
|
## Annotation Auto And Overrides
|
|
84
80
|
|
|
85
|
-
|
|
81
|
+
React layers with `textColor: "contrast"` and `dashColor: "contrast"` use the palette's automatic annotation colors. Solid and transparent top-plane annotations use the palette `labelFill`. This applies to both filled text and solid dashed inlays, so default text + dash states keep one automatic contrast color.
|
|
86
82
|
|
|
87
83
|
- Darker top gradients may use a near-white label. Current example: `15 Alpha` uses `#f7fbff`.
|
|
88
84
|
- Lighter top gradients should use dark in-family annotation colors.
|
|
89
85
|
- Do not add a second outline copy for automatic contrast.
|
|
90
86
|
|
|
91
|
-
Wireframe text labels ignore
|
|
87
|
+
Wireframe text labels ignore fixed label paint and use gradient wire paint:
|
|
92
88
|
|
|
93
89
|
```css
|
|
94
90
|
fill: none !important;
|
|
95
|
-
stroke:
|
|
91
|
+
stroke: url("#...text-wire...");
|
|
96
92
|
stroke-width: var(--label-wire-width);
|
|
97
93
|
```
|
|
98
94
|
|
|
99
|
-
|
|
95
|
+
Wireframe inlays use the top-face gradient.
|
|
100
96
|
|
|
101
|
-
In React, `textStyle: "wireframe"` outlines the same live SVG text element used by filled mode. On solid/transparent material, outline paint comes from `textColor`; `contrast` resolves to
|
|
97
|
+
In React, `textStyle: "wireframe"` outlines the same live SVG text element used by filled mode. On solid/transparent material, outline paint comes from `textColor`; `contrast` resolves to `labelFill`, matching filled text and solid dash. On wireframe material, outline paint comes from label-local `textWire` gradients; do not sample the full-face top ramp there, and do not replace the text with single-stroke lettering.
|
|
102
98
|
|
|
103
|
-
`
|
|
99
|
+
`SquircleVariantConfig` supports explicit annotation overrides:
|
|
104
100
|
|
|
105
101
|
| Field | Values | Paint |
|
|
106
102
|
| --- | --- | --- |
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
103
|
+
| `textColor` | `contrast`, `white`, `black` | Filled or outlined text paint for solid/transparent material; `contrast` appears as `Auto` in the UI |
|
|
104
|
+
| `textStyle` | `solid`, `wireframe` | Filled or outlined text label |
|
|
109
105
|
| `dashColor` | `contrast`, `white`, `black` | Dash stroke for solid/transparent material; `contrast` appears as `Auto` in the UI |
|
|
110
106
|
|
|
111
|
-
Use `Auto` when the annotation should follow the palette. The exported value is `contrast`. Use `white` or `black` only when the user deliberately wants fixed annotation paint.
|
|
107
|
+
Use `Auto` when the annotation should follow the palette. The exported value is `contrast`. Use `white` or `black` only when the user deliberately wants fixed annotation paint. On wireframe material, dash always uses the top gradient; text uses the text surface gradient at full opacity when `textStyle` is `solid` and the text wire gradient when `textStyle` is `wireframe`.
|
|
112
108
|
|
|
113
|
-
Legacy configs with `gpuStyle: "transparent"` normalize to `solid`; there is no third text paint control.
|
|
109
|
+
Deprecated `gpuColor` and `gpuStyle` aliases are accepted only for older snippets. Legacy configs with `gpuStyle: "transparent"` normalize to `solid`; there is no third text paint control.
|
|
114
110
|
|
|
115
111
|
## Edge Colors
|
|
116
112
|
|
|
@@ -136,15 +132,9 @@ This is intentional: light does not interact with a wireframe surface, so top an
|
|
|
136
132
|
|
|
137
133
|
## Adding A Variant
|
|
138
134
|
|
|
139
|
-
When adding a new
|
|
140
|
-
|
|
141
|
-
1. Add
|
|
142
|
-
2.
|
|
143
|
-
3.
|
|
144
|
-
4.
|
|
145
|
-
5. Add a `.v*` class with matching variables.
|
|
146
|
-
6. Add the palette to the constructor `PALETTES` array.
|
|
147
|
-
7. Add a variant card in the drawer.
|
|
148
|
-
8. Add the title span in the hero copy.
|
|
149
|
-
9. Update this palette table.
|
|
150
|
-
10. Render hero, variant drawer, single-state drawer, demo presets, and constructor controls to confirm synchronized colors.
|
|
135
|
+
When adding a new palette:
|
|
136
|
+
|
|
137
|
+
1. Add it to `SQUIRCLE_PALETTES`.
|
|
138
|
+
2. Include top, side, text-wire, label fill, top edge, side edge, and swatch values.
|
|
139
|
+
3. Update the palette table above.
|
|
140
|
+
4. Render the examples and constructor controls.
|
package/docs/design/geometry.md
CHANGED
|
@@ -89,25 +89,26 @@ Rotate the sampled array if needed so the selected front-facing indices are emit
|
|
|
89
89
|
|
|
90
90
|
The complementary back-bottom edge is emitted as `ghost-hidden` and is only shown in wireframe mode.
|
|
91
91
|
|
|
92
|
-
## Generated
|
|
92
|
+
## Generated React Geometry
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
`src/squircle/geometry.ts` returns the geometry consumed by `SquircleScene`:
|
|
95
95
|
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
96
|
+
- `topPoints`: lit top-face polygon.
|
|
97
|
+
- `wallPoints`: one continuous front side-wall polygon.
|
|
98
|
+
- `hiddenPoints`: back/bottom edge used only in wireframe mode.
|
|
99
|
+
- `inlayPoints`: top-plane dashed squircle polygon.
|
|
100
|
+
- `labelTransform`: `matrix(cosA, sinA, -cosA, sinA, cx, cy - h)` for live SVG text.
|
|
101
|
+
- `topBounds` and `sideBounds`: gradient coordinate boxes.
|
|
100
102
|
|
|
101
103
|
## Regeneration Checklist
|
|
102
104
|
|
|
103
|
-
When changing geometry,
|
|
105
|
+
When changing geometry, update the generator and keep these in sync:
|
|
104
106
|
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
- Gradient bboxes documented in [rendering.md](./rendering.md)
|
|
107
|
+
- `DEFAULT_GEOMETRY` in `src/squircle/geometry.ts`.
|
|
108
|
+
- `SquircleScene` gradient definitions in `src/squircle/SquircleScene.tsx`.
|
|
109
|
+
- Example dimensions in `src/pages`.
|
|
110
|
+
- Docs in [rendering.md](./rendering.md) and [single-squircle-states.md](./single-squircle-states.md).
|
|
111
|
+
- Legacy snapshots only if you intentionally refresh `legacy-static/`.
|
|
111
112
|
|
|
112
113
|
For small visual changes:
|
|
113
114
|
|
package/docs/design/rendering.md
CHANGED
|
@@ -18,6 +18,60 @@ React uses `text-surface-*` gradients to remap the top face stops into the label
|
|
|
18
18
|
|
|
19
19
|
Wireframe mode uses the top gradient as the stroke gradient so upper and lower curves match. This intentionally avoids fake lighting on wireframes.
|
|
20
20
|
|
|
21
|
+
## Solid Surface Effects
|
|
22
|
+
|
|
23
|
+
`SquircleVariantConfig.effect` changes only the top-face rendering for `material: "solid"`. It is ignored by `transparent` and `wireframe`.
|
|
24
|
+
|
|
25
|
+
| Effect | Rendering |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `off` | A static top polygon filled by the resolved top gradient. This is the default. |
|
|
28
|
+
| `fluid` | A full-resolution top-face `clipPath` containing an isometrically projected base color field plus blurred moving color blobs. A second lighter blurred layer uses screen blending. No displacement map is used. |
|
|
29
|
+
| `frosted` | The same projected moving-blob field, muted by a deep base, then finished in screen space with a pale veil and a brighter neutral rim. |
|
|
30
|
+
|
|
31
|
+
The moving effects are interval-driven inside `SquircleScene`; they do not query the global DOM and they do not use `requestAnimationFrame`. Motion is enabled only when a visible base or hover variant resolves to a solid `fluid` or `frosted` state.
|
|
32
|
+
|
|
33
|
+
Effect color layers are authored in the flat top-face local coordinate system, not in screen coordinates. Local `(0, 0)` is the center of the raw superellipse, and local `a` is `geometry.config.halfSize`. The whole color field is then wrapped in the same isometric matrix used by labels:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
matrix(cosA, sinA, -cosA, sinA, cx, cy - h)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This means circles are intentionally authored as local circles, then become foreshortened ellipses on the tilted top plane. The top clip path stays in screen space around the generated `topPoints` polygon. For `frosted`, the white veil and bright rim also stay in screen space; only the blob/color field is projected.
|
|
40
|
+
|
|
41
|
+
The SVG structure for effect faces must keep this order:
|
|
42
|
+
|
|
43
|
+
```svg
|
|
44
|
+
<g clip-path="url(#top-clip)">
|
|
45
|
+
<g transform="matrix(cosA,sinA,-cosA,sinA,cx,cy-h)">
|
|
46
|
+
<rect ... />
|
|
47
|
+
<g filter="url(#local-blur)">
|
|
48
|
+
<circle ... />
|
|
49
|
+
</g>
|
|
50
|
+
</g>
|
|
51
|
+
<!-- frost-only veil stays here in screen space -->
|
|
52
|
+
</g>
|
|
53
|
+
<!-- rim and outline stay here in screen space -->
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Effect scale is always derived from `W = 2 * a`, the local top-plane width, not from screen pixels or the projected bbox:
|
|
57
|
+
|
|
58
|
+
- Main blob radius is about `0.45 * W`.
|
|
59
|
+
- Blur is about `0.13 * W`, keeping `blur / radius` near `0.27`.
|
|
60
|
+
- Drift amplitude is about `0.20..0.25 * W`.
|
|
61
|
+
- Blob centers are allowed to sit outside `+-a` so every frame heavily overlaps and overfills the clipped face.
|
|
62
|
+
- The base rectangle covers `+-1.3a`, so the face never shows gaps between blobs.
|
|
63
|
+
|
|
64
|
+
The blur filters use `filterUnits="userSpaceOnUse"` and `primitiveUnits="userSpaceOnUse"` with a local filter region centered around `(0, 0)`. If `halfSize` changes, blob radii, blur, positions, base rect, and motion amplitudes must all scale from `a` or `W` together. Scaling only some of them makes the blobs collapse into visible circles.
|
|
65
|
+
|
|
66
|
+
Effect invariants:
|
|
67
|
+
|
|
68
|
+
- The clip path uses the same generated `topPoints` polygon as the normal top face.
|
|
69
|
+
- Fluid/frosted color blobs must never be placed directly in screen coordinates.
|
|
70
|
+
- Fluid/frosted must not use `feDisplacementMap`; it turns the smooth surface field into raster clouds.
|
|
71
|
+
- Annotations render after the effect, so text and dash stay readable and stay glued to the top plane.
|
|
72
|
+
- Side wall geometry, layer offsets, hover transitions, and annotation transforms do not change when the effect changes.
|
|
73
|
+
- Effect colors are derived from the selected alpha palette's top and side stops, except neutral white veil/rim overlays used only for glassy sharpness.
|
|
74
|
+
|
|
21
75
|
## Sharpness Edge
|
|
22
76
|
|
|
23
77
|
Every filled face has a tiny in-family edge stroke:
|
|
@@ -42,16 +96,15 @@ The top face is drawn after the side wall, so it hides the back half of the extr
|
|
|
42
96
|
|
|
43
97
|
The middle-layer dashed squircle is generated from the same superellipse at `0.6 * a` and projected at `z = h`, so it lies on the top plane. The static copies are:
|
|
44
98
|
|
|
45
|
-
|
|
46
|
-
- `#top-inlay-wire` for wireframe rendering
|
|
99
|
+
`SquircleScene` renders the dashed inlay as the same top-plane polygon in every material. Paint changes by material:
|
|
47
100
|
|
|
48
|
-
By default, solid and transparent inlays use
|
|
101
|
+
By default, solid and transparent inlays use the palette label color, the same contrast token as filled text. Wireframe inlays use the top-face gradient, matching the prism wires.
|
|
49
102
|
|
|
50
|
-
`
|
|
103
|
+
`dashColor: "contrast"` keeps the material default. `dashColor: "white"` and `dashColor: "black"` intentionally use fixed stroke colors on solid/transparent material. Wireframe material ignores fixed dash color and uses the wire gradient.
|
|
51
104
|
|
|
52
105
|
## Label Source
|
|
53
106
|
|
|
54
|
-
React renders top-plane text as one live SVG `<text>` element, so component configs can pass arbitrary strings such as `text: "GPU"`, `text: "CUDA"`, or `text: "AI"`.
|
|
107
|
+
React renders top-plane text as one live SVG `<text>` element, so component configs can pass arbitrary strings such as `text: "GPU"`, `text: "CUDA"`, or `text: "AI"`. `GPU` is only the example string used by the local demos.
|
|
55
108
|
|
|
56
109
|
Current label parameters:
|
|
57
110
|
|
|
@@ -62,7 +115,7 @@ Current label parameters:
|
|
|
62
115
|
- Centered bbox: `x = -63.0293..63.0293`, `y = -22.9473..22.9473`
|
|
63
116
|
- Label wire stroke: `1.1`
|
|
64
117
|
|
|
65
|
-
|
|
118
|
+
The old static snapshots used an outlined glyph path generated with `opentype.js@2.0.0`. Do not use that path technique in new component work; keep live text so arbitrary strings render correctly.
|
|
66
119
|
|
|
67
120
|
```js
|
|
68
121
|
const font = opentype.parse(fs.readFileSync("/System/Library/Fonts/Supplemental/Arial.ttf").buffer);
|
|
@@ -72,11 +125,11 @@ const tx = -((box.x1 + box.x2) / 2);
|
|
|
72
125
|
const ty = -((box.y1 + box.y2) / 2);
|
|
73
126
|
```
|
|
74
127
|
|
|
75
|
-
|
|
128
|
+
If a legacy snapshot ever needs refreshing, apply `tx` and `ty` to every path command coordinate before writing the static `d` attribute, and keep `fill-rule="evenodd"` plus `clip-rule="evenodd"` so counters remain true holes.
|
|
76
129
|
|
|
77
130
|
## Label Transform And Paint
|
|
78
131
|
|
|
79
|
-
Every
|
|
132
|
+
Every React label is a single `<text>` element transformed onto the top plane with:
|
|
80
133
|
|
|
81
134
|
```text
|
|
82
135
|
matrix(cosA, sinA, -cosA, sinA, cx, cy - h)
|
|
@@ -90,27 +143,27 @@ matrix(0.94, 0.342, -0.94, 0.342, 400, 145.6)
|
|
|
90
143
|
|
|
91
144
|
The transform never changes between solid and wireframe modes; only paint changes. React and constructor defaults intentionally mirror the original generated GPU path: `textSize: 62`, `textFontFamily: "Arial, Helvetica, sans-serif"`, and `textFontWeight: 400`.
|
|
92
145
|
|
|
93
|
-
Solid
|
|
146
|
+
Solid text style:
|
|
94
147
|
|
|
95
|
-
-
|
|
96
|
-
-
|
|
148
|
+
- The label uses palette label paint when `textColor` is `contrast`.
|
|
149
|
+
- Solid/transparent dash uses the same palette label paint by default.
|
|
97
150
|
- `15 Alpha` uses `#f7fbff` because its top gradient is dark.
|
|
98
151
|
- Lighter variants use dark in-family label fills.
|
|
99
152
|
|
|
100
|
-
Wireframe
|
|
153
|
+
Wireframe text style:
|
|
101
154
|
|
|
102
155
|
- `textStyle: "wireframe"` uses the same live text element as filled mode.
|
|
103
|
-
- It sets `fill:none
|
|
104
|
-
- On solid/transparent material,
|
|
105
|
-
- On wireframe material,
|
|
106
|
-
-
|
|
156
|
+
- It sets `fill: none` and uses a stroke.
|
|
157
|
+
- On solid/transparent material, outline paint comes from `textColor`; `contrast` resolves to the palette label paint, matching filled text and solid dash.
|
|
158
|
+
- On wireframe material, outline paint resolves to the label-local `textWire` gradient.
|
|
159
|
+
- Wireframe dash uses the top-face gradient so dashed inlays match prism wires.
|
|
107
160
|
- It must remain an outline around the font figures, not a single-stroke lettering replacement.
|
|
108
161
|
- Keep the outline stroke thin relative to text size. The default `labelWire` is `1.1` at `textSize: 62`, safely below the ratio where counters start merging.
|
|
109
162
|
|
|
110
|
-
Do not sample the full-face
|
|
163
|
+
Do not sample the full-face top ramp directly for the text outline on wireframe material; it is too large for the label geometry and makes the color read wrong. Use one text element for all text styles. Use `textColor` for solid/transparent outline paint and the label-local wire gradient for wireframe-material outline paint.
|
|
111
164
|
|
|
112
|
-
|
|
165
|
+
Deprecated `gpuColor` aliases are accepted only for old snippets and map to React `textColor`. They override label paint only on solid/transparent material. On wireframe material, `textStyle: "solid"` renders a fully opaque filled label using the text surface gradient, and `textStyle: "wireframe"` renders an outlined label using the text wire gradient.
|
|
113
166
|
|
|
114
|
-
Do not introduce `textStyle: "transparent"` as a third paint control. Legacy
|
|
167
|
+
Do not introduce `textStyle: "transparent"` as a third paint control. Legacy configs with `gpuStyle: "transparent"` should normalize to `solid`.
|
|
115
168
|
|
|
116
169
|
Do not build filled letters from `<rect>`, `<line>`, or separate stem/bowl paths. Do not add a second label copy and do not replace the text with monoline lettering for outline mode.
|
|
@@ -1,121 +1,59 @@
|
|
|
1
1
|
# Single-Squircle State Constructors
|
|
2
2
|
|
|
3
|
-
This file
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
This file describes reusable one-layer constructors for `SquircleScene`. Use these recipes when another agent wants one squircle outside a full multi-layer composition.
|
|
4
|
+
|
|
5
|
+
## Base Layer Shape
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import type { SquircleLayerConfig } from "@dstackai/sqircle";
|
|
9
|
+
|
|
10
|
+
const layer: SquircleLayerConfig = {
|
|
11
|
+
id: "single",
|
|
12
|
+
base: {
|
|
13
|
+
material: "solid",
|
|
14
|
+
paletteId: "15",
|
|
15
|
+
text: "GPU",
|
|
16
|
+
textStyle: "solid",
|
|
17
|
+
dash: true
|
|
18
|
+
}
|
|
19
|
+
};
|
|
13
20
|
```
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- `--top-fill`
|
|
18
|
-
- `--side-fill`
|
|
19
|
-
- `--label-fill`
|
|
20
|
-
- `--top-edge`
|
|
21
|
-
- `--side-edge`
|
|
22
|
-
- `--label-wire-width`
|
|
23
|
-
- `--face-edge-width`
|
|
24
|
-
- `--face-edge-opacity`
|
|
25
|
-
|
|
26
|
-
The global transparent/wireframe switch does not affect this drawer. The drawer always shows all constructor states at once.
|
|
27
|
-
|
|
28
|
-
## Building Blocks
|
|
29
|
-
|
|
30
|
-
| Part | SVG use | CSS class | Purpose |
|
|
31
|
-
| --- | --- | --- | --- |
|
|
32
|
-
| Solid prism | `<use href="#prism-active" />` | `.single-active` | Filled, selected-looking prism with top and side gradients |
|
|
33
|
-
| Transparent prism | `<use href="#prism-ghost" />` | `.single-ghost` inside `.single-transparent` | Translucent filled prism |
|
|
34
|
-
| Wireframe prism | `<use href="#prism-ghost" />` | `.single-ghost` inside `.single-wire` | Gradient outline with transparent faces |
|
|
35
|
-
| Solid/transparent dash | `<use href="#top-inlay" />` | `.single-inlay` | Dashed top-plane squircle using `--label-fill` |
|
|
36
|
-
| Wireframe dash | `<use href="#top-inlay-wire" />` | `.single-wire-inlay.wire-inlay` | Gradient dashed top-plane squircle |
|
|
37
|
-
| Text label | `<use href="#label-gpu" />` | `.single-label.plane-label` | Compound path label on the top plane; the current static glyph spells `GPU` |
|
|
38
|
-
|
|
39
|
-
The label always uses this transform:
|
|
40
|
-
|
|
41
|
-
```html
|
|
42
|
-
transform="matrix(0.94,0.342,-0.94,0.342,400,145.6)"
|
|
43
|
-
```
|
|
22
|
+
`GPU` is only example text. Any string is valid, including `"{}"` or `"CUDA"`.
|
|
44
23
|
|
|
45
24
|
## Constructor Matrix
|
|
46
25
|
|
|
47
|
-
| State |
|
|
48
|
-
| --- | --- |
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Transparent with text and dash:
|
|
74
|
-
|
|
75
|
-
```html
|
|
76
|
-
<svg class="single-squircle" viewBox="-6 -6 812 314" aria-label="Transparent single squircle with text and dashed inlay">
|
|
77
|
-
<use class="single-ghost" href="#prism-ghost" />
|
|
78
|
-
<use class="single-inlay" href="#top-inlay" />
|
|
79
|
-
<use class="single-label plane-label" href="#label-gpu" transform="matrix(0.94,0.342,-0.94,0.342,400,145.6)" />
|
|
80
|
-
</svg>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Wireframe with text and dash:
|
|
84
|
-
|
|
85
|
-
```html
|
|
86
|
-
<svg class="single-squircle" viewBox="-6 -6 812 314" aria-label="Wireframe single squircle with text and dashed inlay">
|
|
87
|
-
<use class="single-ghost" href="#prism-ghost" />
|
|
88
|
-
<use class="single-wire-inlay wire-inlay" href="#top-inlay-wire" />
|
|
89
|
-
<use class="single-label plane-label" href="#label-gpu" transform="matrix(0.94,0.342,-0.94,0.342,400,145.6)" />
|
|
90
|
-
</svg>
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
The text + dash states are reusable variants that combine the top-plane text path with a dashed inlay.
|
|
94
|
-
|
|
95
|
-
In the static single-state drawer, solid and transparent text + dash states use `--label-fill` for both the filled text path and dashed inlay. Wireframe text + dash states use `--top-fill` for both the outlined text path and dashed inlay. `constructor.html` can override GPU color, GPU style, and dash color per layer because it is the GPU example; React generated code maps those controls to `textColor`, `textStyle`, and `dashColor`.
|
|
26
|
+
| State | Config |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| Solid | `{ material: "solid" }` |
|
|
29
|
+
| Solid Text | `{ material: "solid", text: "GPU", textStyle: "solid" }` |
|
|
30
|
+
| Solid Text Outline | `{ material: "solid", text: "GPU", textStyle: "wireframe" }` |
|
|
31
|
+
| Solid Dash | `{ material: "solid", dash: true }` |
|
|
32
|
+
| Solid Text + Dash | `{ material: "solid", text: "GPU", textStyle: "solid", dash: true }` |
|
|
33
|
+
| Transparent | `{ material: "transparent" }` |
|
|
34
|
+
| Transparent Text | `{ material: "transparent", text: "GPU", textStyle: "solid" }` |
|
|
35
|
+
| Transparent Text Outline + Dash | `{ material: "transparent", text: "GPU", textStyle: "wireframe", dash: true }` |
|
|
36
|
+
| Wireframe | `{ material: "wireframe" }` |
|
|
37
|
+
| Wireframe Text Filled | `{ material: "wireframe", text: "GPU", textStyle: "solid" }` |
|
|
38
|
+
| Wireframe Text Outline | `{ material: "wireframe", text: "GPU", textStyle: "wireframe" }` |
|
|
39
|
+
| Wireframe Text Outline + Dash | `{ material: "wireframe", text: "GPU", textStyle: "wireframe", dash: true }` |
|
|
40
|
+
|
|
41
|
+
The local `index.html` example renders these through `createSingleStatePresets()` in `src/pages/exampleData.ts`.
|
|
42
|
+
|
|
43
|
+
## Paint Rules
|
|
44
|
+
|
|
45
|
+
- Solid and transparent text + dash states use palette contrast paint by default.
|
|
46
|
+
- Solid/transparent `textColor` and `dashColor` may be `contrast`, `white`, or `black`.
|
|
47
|
+
- Wireframe dash always uses the wire gradient.
|
|
48
|
+
- Wireframe `textStyle: "wireframe"` uses the label-local text wire gradient.
|
|
49
|
+
- Wireframe `textStyle: "solid"` uses the text surface gradient at full opacity.
|
|
96
50
|
|
|
97
51
|
## Ordering Rules
|
|
98
52
|
|
|
99
|
-
|
|
100
|
-
- Draw the inlay after the prism.
|
|
101
|
-
- Draw the label last.
|
|
102
|
-
- Use `#top-inlay` for solid/transparent states.
|
|
103
|
-
- Use `#top-inlay-wire` for wireframe states.
|
|
104
|
-
- Do not use two label copies. The same `.plane-label` object changes paint through CSS.
|
|
53
|
+
`SquircleScene` draws a variant in this order:
|
|
105
54
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```css
|
|
111
|
-
#variant-15:checked ~ .hero-card,
|
|
112
|
-
#variant-15:checked ~ .single-drawer {
|
|
113
|
-
--top-fill: url("#top-15");
|
|
114
|
-
--side-fill: url("#side-15");
|
|
115
|
-
--label-fill: #f7fbff;
|
|
116
|
-
--top-edge: #7c5fd0;
|
|
117
|
-
--side-edge: #2d1466;
|
|
118
|
-
}
|
|
119
|
-
```
|
|
55
|
+
1. Prism side/top or wireframe prism.
|
|
56
|
+
2. Dashed inlay, when enabled.
|
|
57
|
+
3. Live SVG text, when enabled.
|
|
120
58
|
|
|
121
|
-
|
|
59
|
+
Do not create two text copies for filled and outline states. The same live `<text>` object changes only paint.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# React Example Pages
|
|
2
|
+
|
|
3
|
+
The root HTML files are Vite shells. They should stay small and only mount React entrypoints from `src/pages`.
|
|
4
|
+
|
|
5
|
+
| HTML | React entrypoint | Purpose |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `index.html` | `src/pages/IndexPage.tsx` | Hero scene plus selectable single-squircle state drawer |
|
|
8
|
+
| `demo.html` | `src/pages/DemoPage.tsx` | Selectable generated gallery of 3-layer compositions |
|
|
9
|
+
| `constructor.html` | `src/pages/ConstructorPage.tsx` | Full constructor UI using `SquircleEditor` |
|
|
10
|
+
| `react.html` | `src/pages/ConstructorPage.tsx` | Compatibility alias for the constructor |
|
|
11
|
+
|
|
12
|
+
## Source Files
|
|
13
|
+
|
|
14
|
+
- `src/pages/exampleData.ts`: shared preset and seed-layer constructors.
|
|
15
|
+
- `src/pages/PageShell.tsx`: shared page chrome and theme switch.
|
|
16
|
+
- `src/pages/pages.css`: example-page layout styles.
|
|
17
|
+
|
|
18
|
+
The examples must consume `SquircleScene`, `SquircleEditor`, palettes, and helpers from `src/squircle`. Do not paste generated SVG polygons or duplicate renderer logic in page files.
|
|
19
|
+
|
|
20
|
+
## Behavior
|
|
21
|
+
|
|
22
|
+
- `index.html` renders a main three-layer scene and a collapsed/openable drawer of single-squircle states. Palette buttons recolor the examples through React state.
|
|
23
|
+
- `demo.html` renders 96 generated composition presets, including alpha palettes and solid `off`/`fluid`/`frosted` surfaces. Clicking a card changes the main hero composition. Each layer hover is a state/color swap only.
|
|
24
|
+
- `constructor.html` renders `SquircleEditor` with three default plain wireframe layers. The inspector exposes palette and effect controls. The Code panel exports React code using `@dstackai/sqircle` as the import path.
|
|
25
|
+
- `react.html` intentionally mirrors `constructor.html` for older links.
|
|
26
|
+
|
|
27
|
+
## Rules
|
|
28
|
+
|
|
29
|
+
- Keep root HTML files as shells with one `#root` and one module script.
|
|
30
|
+
- Keep examples transparent-background friendly.
|
|
31
|
+
- Keep hover effects as opacity crossfades between base and hover variants. Do not add movement, shadows, scale, filters, or gap changes.
|
|
32
|
+
- Keep all squircle geometry, palette, stroke, annotation, and theme behavior in the reusable component layer.
|
|
33
|
+
- If a legacy static behavior is still valuable, migrate it into `src/pages` or `src/squircle`; do not edit ignored snapshots as source.
|