figureone 1.7.0 → 1.8.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/figureone.min.js +1 -1
- package/index.js +417 -164
- package/llms-full.txt +65 -0
- package/llms.txt +17 -0
- package/package.json +1 -1
- package/types/js/figure/DrawingObjects/GLObject/GLObject.d.ts +18 -0
- package/types/js/figure/FigurePrimitives/FigurePrimitiveTypes.d.ts +73 -0
- package/types/js/figure/webgl/shaders.d.ts +22 -5
package/llms-full.txt
CHANGED
|
@@ -20,6 +20,10 @@ Colors are `[r, g, b, a]` with values 0-1. Default scene is `[-1, -1, 2, 2]` (x,
|
|
|
20
20
|
| lineWidth | number | | Default line width |
|
|
21
21
|
| length | number | | Default primary dimension |
|
|
22
22
|
| backgroundColor | TypeColor | | Background color |
|
|
23
|
+
| textStyle | `'italic'` \| `'normal'` | `'italic'` | Default equation text style (also settable on FigurePrimitives and Equation) |
|
|
24
|
+
| antialias | boolean | `true` | Enable WebGL anti-aliasing |
|
|
25
|
+
| atlasScale | number | `2` | GL text atlas texture resolution relative to 1:1 pixel mapping |
|
|
26
|
+
| onWebGLUnavailable | () => void | | Callback fired once during construction if no WebGL context is available (figure is still created but renders nothing) |
|
|
23
27
|
|
|
24
28
|
### Key Figure Methods
|
|
25
29
|
|
|
@@ -45,6 +49,11 @@ figure.resize(); // Resize after container change
|
|
|
45
49
|
figure.animateNextFrame(); // Request next animation frame
|
|
46
50
|
figure.isAnimating(); // Check if any animation running
|
|
47
51
|
|
|
52
|
+
// WebGL context state
|
|
53
|
+
figure.webglAvailable; // false if no live WebGL context (e.g. context lost)
|
|
54
|
+
figure.notifications.add('contextLost', () => { /* context removed by browser */ });
|
|
55
|
+
figure.notifications.add('contextRestored', () => { /* context returned */ });
|
|
56
|
+
|
|
48
57
|
// Coordinate transforms
|
|
49
58
|
figure.transformPoint(point, fromSpace, toSpace);
|
|
50
59
|
figure.spaceTransformMatrix(fromSpace, toSpace);
|
|
@@ -92,6 +101,7 @@ Path to figure element(s) within a collection. Supports multiple formats:
|
|
|
92
101
|
| underline | boolean \| object | `false` | Underline options |
|
|
93
102
|
| outline | boolean \| object | `false` | Outline options |
|
|
94
103
|
| render | `'gl'` \| `'2d'` \| `'html'` | `'gl'` | Render target |
|
|
104
|
+
| atlasId | string | | Share a single GL atlas texture across text elements with different sizes (elements with the same `atlasId` reuse one atlas) |
|
|
95
105
|
|
|
96
106
|
### OBJ_Texture
|
|
97
107
|
|
|
@@ -119,6 +129,11 @@ Path to figure element(s) within a collection. Supports multiple formats:
|
|
|
119
129
|
| defaultColor | TypeColor | | Color when undimmed |
|
|
120
130
|
| scenarios | OBJ_Scenarios | | Named presets |
|
|
121
131
|
| scene | Scene \| OBJ_Scene | | Custom scene |
|
|
132
|
+
| isFormIgnored | boolean | `false` | Exclude from equation form changes — skipped by form layout, show/hide, transform/color sets, and `elementMods`, so its user-applied transform, color, and visibility persist across `showForm` / `goToForm` (contributes zero size to layout) |
|
|
133
|
+
| allowSetColor | `'all'` \| `'opacity'` \| `'none'` | `'all'` | Freeze color: `'opacity'` allows only the alpha channel to change; `'none'` blocks all `setColor` |
|
|
134
|
+
| ignoreSetColor | string \| string[] | `[]` | Source label(s) whose tagged `setColor` commands are ignored (e.g. the equation's default `'form'` color cascade), while explicit/untagged commands (`dim`/`undim`, direct `setColor`) are still honored |
|
|
135
|
+
|
|
136
|
+
These element properties are also settable at runtime; `setColor(color, setDefault?, from?)` takes an optional `from` source label that is matched against `ignoreSetColor`.
|
|
122
137
|
|
|
123
138
|
### OBJ_Collection
|
|
124
139
|
|
|
@@ -1252,6 +1267,26 @@ Array: `{ color: [content, [r, g, b, a]] }`
|
|
|
1252
1267
|
| color | TypeColor | | Color to apply |
|
|
1253
1268
|
| fullContentBounds | boolean | `false` | Use full bounds |
|
|
1254
1269
|
|
|
1270
|
+
#### EQN_Opacity (`opacity`)
|
|
1271
|
+
Array: `{ opacity: [content, opacity_value] }`. Wraps a phrase in an opacity multiplier that cascades multiplicatively through nested `opacity` wrappers (outer `0.5` × inner `0.5` = `0.25` on inner content). The cascaded opacity is assigned to each wrapped element whenever the form is shown, overriding externally-set element opacity — set `ignoreOpacity: true` on the form to suppress this and preserve external opacities.
|
|
1272
|
+
|
|
1273
|
+
| Property | Type | Default | Description |
|
|
1274
|
+
|---|---|---|---|
|
|
1275
|
+
| content | TypeEquationPhrase | | Content |
|
|
1276
|
+
| opacity | number | | Opacity multiplier in range `[0, 1]` |
|
|
1277
|
+
| fullContentBounds | boolean | `false` | Use full bounds |
|
|
1278
|
+
|
|
1279
|
+
#### EQN_Front (`front`) / EQN_Back (`back`)
|
|
1280
|
+
Array: `{ front: [content, num] }` / `{ back: [content, num] }`. Reorder a phrase's elements within the equation's draw stack, per-form. All elements in `content` move together as a group, keeping their relative draw order. Applied whenever the form is shown, relative to the equation's natural definition order, so each form deterministically defines its own stacking. The same operations are available as `front` / `back` element mods (e.g. `elementMods: { a: { back: {} } }`).
|
|
1281
|
+
|
|
1282
|
+
| Property | Type | Default | Description |
|
|
1283
|
+
|---|---|---|---|
|
|
1284
|
+
| content | TypeEquationPhrase | | Content |
|
|
1285
|
+
| num | number | | `front`: places to move forward (positive) or `\|num\|` places behind the front (negative). `back`: places to move back (positive) or `\|num\|` places ahead of the back (negative). With `before`/`after`, it's the offset from the anchor (default `0`). If omitted with no anchor, moves fully to front/back |
|
|
1286
|
+
| before | string \| string[] | | Anchor element name(s) — position the group just before (behind) the most-back anchor |
|
|
1287
|
+
| after | string \| string[] | | Anchor element name(s) — position the group just after (in front of) the most-front anchor |
|
|
1288
|
+
| fullContentBounds | boolean | `false` | Use full bounds |
|
|
1289
|
+
|
|
1255
1290
|
#### EQN_Container (`container`)
|
|
1256
1291
|
Array: `{ container: [content, width] }`
|
|
1257
1292
|
|
|
@@ -1452,10 +1487,17 @@ forms: {
|
|
|
1452
1487
|
scale: { elementName: 1.5 }, // Per-element target scales during animation
|
|
1453
1488
|
fromPrev: { elementName: 'otherElement' }, // Animate from another element's position
|
|
1454
1489
|
fromNext: { elementName: 'otherElement' }, // Animate from another element's position (reverse)
|
|
1490
|
+
ignoreColor: false, // true preserves externally-set element colors (suppresses color cascade)
|
|
1491
|
+
ignoreOpacity: false, // true preserves externally-set element opacities (suppresses opacity cascade)
|
|
1492
|
+
elementMods: { // Per-element property mods applied when form shows
|
|
1493
|
+
elementName: { back: {} }, // e.g. front/back reorder mods (see EQN_Front/EQN_Back)
|
|
1494
|
+
},
|
|
1455
1495
|
},
|
|
1456
1496
|
}
|
|
1457
1497
|
```
|
|
1458
1498
|
|
|
1499
|
+
Every equation layout function (container, frac, matrix, brac, annotate, color, opacity, front, back, etc.) also accepts an optional `name` property — purely a label with no layout effect, used to address the function's sub-tree via `eqn.getFunctionElements(name)`.
|
|
1500
|
+
|
|
1459
1501
|
### Forms and Animation
|
|
1460
1502
|
|
|
1461
1503
|
```js
|
|
@@ -1474,9 +1516,24 @@ const eqn = figure.add({
|
|
|
1474
1516
|
});
|
|
1475
1517
|
|
|
1476
1518
|
eqn.showForm('1');
|
|
1519
|
+
eqn.showForm('1', false); // notify=false suppresses the formChanged event for this call
|
|
1477
1520
|
eqn.goToForm({ form: '2', delay: 1, duration: 1.5, animate: 'move' });
|
|
1478
1521
|
eqn.nextForm(); // Navigate formSeries
|
|
1479
1522
|
eqn.prevForm();
|
|
1523
|
+
|
|
1524
|
+
// Element lookup within forms
|
|
1525
|
+
eqn.getFormElements(formName, includeHidden?); // All elements in a form
|
|
1526
|
+
eqn.getPhraseElements(phrase); // All elements in a phrase
|
|
1527
|
+
// Elements inside a named layout function (any function tagged with `name`).
|
|
1528
|
+
// (name, formName? = current, mode? = 'all', includeHidden? = false).
|
|
1529
|
+
// mode 'first' = first match; 'all' = de-duplicated union across all matches.
|
|
1530
|
+
eqn.getFunctionElements('myFrac');
|
|
1531
|
+
```
|
|
1532
|
+
|
|
1533
|
+
`Equation` publishes a `formChanged` notification whenever the displayed form may have changed, with payload `{ phase, form, fromForm?, progress? }`. `phase` is one of: `'showForm'` (form set via `showForm`; suppress with `notify: false`), `'goToFormStart'`, `'goToFormStep'` (per animation frame, with `progress` 0–1; a final step with `progress: 1` precedes the end), `'goToFormEnd'`. `fromForm` is present only on the `goToForm*` phases.
|
|
1534
|
+
|
|
1535
|
+
```js
|
|
1536
|
+
eqn.notifications.add('formChanged', ({ phase, form, progress }) => { /* drive UI */ });
|
|
1480
1537
|
```
|
|
1481
1538
|
|
|
1482
1539
|
### Phrases (reusable sub-expressions)
|
|
@@ -1488,6 +1545,14 @@ eqn.prevForm();
|
|
|
1488
1545
|
}
|
|
1489
1546
|
```
|
|
1490
1547
|
|
|
1548
|
+
### LaTeX Parsing
|
|
1549
|
+
`Fig.latexToFigureOne(latex)` converts a LaTeX math expression into `{ elements, form }` for use in an equation definition (basic support).
|
|
1550
|
+
|
|
1551
|
+
```js
|
|
1552
|
+
const { elements, form } = Fig.latexToFigureOne('\\frac{a}{b} = c');
|
|
1553
|
+
figure.add({ make: 'equation', elements, forms: { base: form } });
|
|
1554
|
+
```
|
|
1555
|
+
|
|
1491
1556
|
---
|
|
1492
1557
|
|
|
1493
1558
|
## 7. Animation System
|
package/llms.txt
CHANGED
|
@@ -24,6 +24,8 @@ figure.add({ make: 'triangle', width: 0.5, height: 0.5, color: [1, 0, 0, 1] });
|
|
|
24
24
|
|
|
25
25
|
Colors are `[r, g, b, a]` with values 0-1. Coordinates default to a scene of `[-1, -1, 2, 2]` (x, y, width, height). Override with `new Fig.Figure({ scene: [-2, -2, 4, 4] })`.
|
|
26
26
|
|
|
27
|
+
Other `Fig.Figure` options: `textStyle` (`'italic'` default | `'normal'` — default equation text style), `antialias` (default `true`), `atlasScale` (GL text atlas resolution, default `2`), `onWebGLUnavailable` (callback if no WebGL context). Check `figure.webglAvailable` and subscribe to `contextLost` / `contextRestored` notifications for runtime WebGL context transitions.
|
|
28
|
+
|
|
27
29
|
## Core Concepts
|
|
28
30
|
|
|
29
31
|
- **Figure** — top-level container that manages all elements and rendering
|
|
@@ -105,6 +107,9 @@ All elements accept these common options alongside shape-specific ones:
|
|
|
105
107
|
- `color` — `[r, g, b, a]`
|
|
106
108
|
- `position` — `[x, y]` shorthand for translation
|
|
107
109
|
- `rotation` — rotation in radians
|
|
110
|
+
- `isFormIgnored` — exclude from equation form changes (its transform/color/visibility persist across `showForm`/`goToForm`)
|
|
111
|
+
- `allowSetColor` — `'all'` (default), `'opacity'` (alpha only), or `'none'` to freeze color
|
|
112
|
+
- `ignoreSetColor` — source label(s) whose tagged `setColor` is ignored (e.g. the equation's `'form'` color cascade), while explicit commands still apply
|
|
108
113
|
|
|
109
114
|
When `options` is used, shape-specific properties go inside it:
|
|
110
115
|
|
|
@@ -256,9 +261,14 @@ Any element type can be created inline in forms using `make`:
|
|
|
256
261
|
| `prodOf` | `{ prodOf: { symbol, content, from, to } }` | Product |
|
|
257
262
|
| `scale` | `{ scale: [content, scale_factor] }` | Scale content |
|
|
258
263
|
| `color` | `{ color: [content, [r,g,b,a]] }` | Color content |
|
|
264
|
+
| `opacity` | `{ opacity: [content, 0.3] }` | Opacity multiplier (cascades multiplicatively through nesting) |
|
|
265
|
+
| `front` | `{ front: [content, num] }` | Bring content forward in draw stack (per-form); supports `before`/`after` anchors |
|
|
266
|
+
| `back` | `{ back: [content, num] }` | Send content back in draw stack (per-form); supports `before`/`after` anchors |
|
|
259
267
|
| `container` | `{ container: { content, width, ... } }` | Fixed-size container |
|
|
260
268
|
| `lines` | `{ lines: { content: [...], justify } }` | Multi-line layout |
|
|
261
269
|
|
|
270
|
+
Any layout function also accepts a `name` label to address its elements via `eqn.getFunctionElements(name)`. Form objects accept `ignoreColor` / `ignoreOpacity` to preserve externally-set element color/opacity (suppress the cascade).
|
|
271
|
+
|
|
262
272
|
### Symbols
|
|
263
273
|
|
|
264
274
|
Define symbols in `elements` with `{ symbol: 'type' }`:
|
|
@@ -302,9 +312,12 @@ const eqn = figure.add({
|
|
|
302
312
|
});
|
|
303
313
|
|
|
304
314
|
eqn.showForm('1');
|
|
315
|
+
eqn.showForm('1', false); // notify=false suppresses the formChanged event
|
|
305
316
|
eqn.goToForm({ form: '2', delay: 1, duration: 1.5, animate: 'move' });
|
|
306
317
|
```
|
|
307
318
|
|
|
319
|
+
Equation publishes a `formChanged` notification with payload `{ phase, form, fromForm?, progress? }`, where `phase` is `'showForm'`, `'goToFormStart'`, `'goToFormStep'` (with `progress` 0–1), or `'goToFormEnd'`. Use `eqn.getFunctionElements(name)` to fetch elements inside a named layout function.
|
|
320
|
+
|
|
308
321
|
Use `formSeries` to define an ordered list of forms, then navigate with `eqn.nextForm()` and `eqn.prevForm()`.
|
|
309
322
|
|
|
310
323
|
Use `phrases` to define reusable sub-expressions:
|
|
@@ -529,6 +542,10 @@ new Fig.Transform() // Transform builder
|
|
|
529
542
|
.scale(sx, sy)
|
|
530
543
|
Fig.round(value, precision) // Round to N decimal places
|
|
531
544
|
|
|
545
|
+
// Convert a LaTeX math expression to an equation form (basic support)
|
|
546
|
+
const { elements, form } = Fig.latexToFigureOne('\\frac{a}{b} = c');
|
|
547
|
+
figure.add({ make: 'equation', elements, forms: { base: form } });
|
|
548
|
+
|
|
532
549
|
// Color format: [r, g, b, a] with values 0 to 1
|
|
533
550
|
// [1, 0, 0, 1] = red, [0, 0, 1, 0.5] = semi-transparent blue
|
|
534
551
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figureone",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Draw, animate and interact with shapes, text, plots and equations in Javascript. Create interactive slide shows, and interactive videos.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -42,6 +42,12 @@ declare class GLObject extends DrawingObject {
|
|
|
42
42
|
loadColor: TypeColor;
|
|
43
43
|
[key: string]: any;
|
|
44
44
|
} | null;
|
|
45
|
+
maskTextures: Array<{
|
|
46
|
+
id: string;
|
|
47
|
+
src: string;
|
|
48
|
+
loadColor: TypeColor;
|
|
49
|
+
uniformName: string;
|
|
50
|
+
}>;
|
|
45
51
|
attributes: {
|
|
46
52
|
[attributeName: string]: {
|
|
47
53
|
buffer: WebGLBuffer | null;
|
|
@@ -85,6 +91,18 @@ declare class GLObject extends DrawingObject {
|
|
|
85
91
|
* Buffer a texture for the shape to be painted with.
|
|
86
92
|
*/
|
|
87
93
|
addTexture(location: string, mapFrom?: Rect, mapTo?: Rect, mapToBuffer?: string, points?: Array<number>, repeat?: boolean, onLoad?: null | (() => void), loadColor?: TypeColor): void;
|
|
94
|
+
/**
|
|
95
|
+
* Buffer a mask texture for the `textureMap` color mode. Each call appends a
|
|
96
|
+
* mask, bound to the next u_mask{i} sampler. Masks share the base texture's
|
|
97
|
+
* coordinates, so only a source and load color are needed. The default load
|
|
98
|
+
* color is fully transparent so that, until the mask loads, no region is
|
|
99
|
+
* recolored and the base texture shows through unchanged.
|
|
100
|
+
*
|
|
101
|
+
* An empty `location` registers a transparent placeholder, which keeps the
|
|
102
|
+
* u_mask{i} indexing aligned with the tint blocks when a caller supplies an
|
|
103
|
+
* invalid/missing mask in a positional list (the slot becomes a no-op).
|
|
104
|
+
*/
|
|
105
|
+
addMaskTexture(location?: string, loadColor?: TypeColor): void;
|
|
88
106
|
updateTexture(data: HTMLImageElement): void;
|
|
89
107
|
initTexture(force?: boolean): void;
|
|
90
108
|
createTextureMap(xMinGL?: number, xMaxGL?: number, yMinGL?: number, yMaxGL?: number, xMinTex?: number, xMaxTex?: number, yMinTex?: number, yMaxTex?: number): void;
|
|
@@ -224,6 +224,30 @@ export type OBJ_Texture = {
|
|
|
224
224
|
repeat?: boolean;
|
|
225
225
|
onLoad?: () => void;
|
|
226
226
|
};
|
|
227
|
+
/**
|
|
228
|
+
* Mask texture used by the `gl` primitive to recolor regions of a base
|
|
229
|
+
* `texture`. A mask shares the base texture's coordinates, so it must be the
|
|
230
|
+
* same dimensions and aligned with the base image. Each of a mask's `r`, `g`,
|
|
231
|
+
* `b` and `a` channels selects a region recolored by an entry of the
|
|
232
|
+
* primitive's `tints` option.
|
|
233
|
+
*
|
|
234
|
+
* Supply a single mask with `mask`, or several with `masks` (an array). Mask `m`
|
|
235
|
+
* (0-based) uses `tints[4m]`, `tints[4m + 1]`, `tints[4m + 2]` and
|
|
236
|
+
* `tints[4m + 3]` for its r, g, b and a channels - so each mask adds four
|
|
237
|
+
* recolorable regions. A single mask costs one extra texture fetch and four
|
|
238
|
+
* mixes; each additional mask adds one fetch and four mixes.
|
|
239
|
+
*
|
|
240
|
+
* @property {string} [src] url of the mask image
|
|
241
|
+
* @property {TypeColor} [loadColor] color shown while the mask loads
|
|
242
|
+
* (`[0, 0, 0, 0]` - fully transparent, so nothing is recolored until the mask
|
|
243
|
+
* has loaded)
|
|
244
|
+
* @interface
|
|
245
|
+
* @group Shaders
|
|
246
|
+
*/
|
|
247
|
+
export type OBJ_TextureMask = {
|
|
248
|
+
src?: string;
|
|
249
|
+
loadColor?: TypeColor;
|
|
250
|
+
};
|
|
227
251
|
/**
|
|
228
252
|
* Pulse options object
|
|
229
253
|
*
|
|
@@ -443,6 +467,12 @@ export type TypeText = 'gl' | '2d';
|
|
|
443
467
|
* {@link OBJ_FragmentShader} for names of attributes and uniforms used in the
|
|
444
468
|
* shaders, and when they are used.
|
|
445
469
|
*
|
|
470
|
+
* A texture can be recolored by region using one or more masks (see the mask
|
|
471
|
+
* examples below):
|
|
472
|
+
*
|
|
473
|
+
* 
|
|
474
|
+
* 
|
|
475
|
+
*
|
|
446
476
|
* @property {TypeGLPrimitive} [glPrimitive]
|
|
447
477
|
* @property {TypeVertexShader} [vertexShader]
|
|
448
478
|
* @property {TypeFragmentShader} [fragmentShader]
|
|
@@ -585,6 +615,46 @@ export type TypeText = 'gl' | '2d';
|
|
|
585
615
|
* },
|
|
586
616
|
* ],
|
|
587
617
|
* });
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* // Recolor regions of a texture with a mask. The mask image marks regions to
|
|
621
|
+
* // recolor in its red, green, blue and alpha channels, which map to tints 0,
|
|
622
|
+
* // 1, 2 and 3. Unmasked pixels keep the base texture's color.
|
|
623
|
+
* const p = figure.add({
|
|
624
|
+
* make: 'gl',
|
|
625
|
+
* vertices: [-0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5],
|
|
626
|
+
* numVertices: 6,
|
|
627
|
+
* texture: {
|
|
628
|
+
* src: './base.png',
|
|
629
|
+
* coords: [0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1],
|
|
630
|
+
* loadColor: [0, 0, 0, 0],
|
|
631
|
+
* },
|
|
632
|
+
* mask: { src: './mask.png' },
|
|
633
|
+
* tints: [[1, 0, 0, 1], [0, 0, 1, 1]],
|
|
634
|
+
* });
|
|
635
|
+
* // Change the first region's color at runtime
|
|
636
|
+
* p.custom.setTint(0, [0, 1, 0, 1]);
|
|
637
|
+
*
|
|
638
|
+
* @example
|
|
639
|
+
* // Recolor with two masks. Each mask adds four regions (its r, g, b, a
|
|
640
|
+
* // channels), so mask 0 uses tints 0-3 and mask 1 uses tints 4-7. Here mask 0
|
|
641
|
+
* // recolors three circles (tints 0, 1, 2) and mask 1 recolors a bar (tint 4).
|
|
642
|
+
* figure.add({
|
|
643
|
+
* make: 'gl',
|
|
644
|
+
* vertices: [-0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5],
|
|
645
|
+
* numVertices: 6,
|
|
646
|
+
* texture: {
|
|
647
|
+
* src: './base.png',
|
|
648
|
+
* coords: [0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1],
|
|
649
|
+
* loadColor: [0, 0, 0, 0],
|
|
650
|
+
* },
|
|
651
|
+
* masks: [{ src: './mask.png' }, { src: './mask1.png' }],
|
|
652
|
+
* tints: [
|
|
653
|
+
* [1, 0, 0, 1], [0, 0.6, 0, 1], [0, 0, 1, 1], null, // mask 0: circles
|
|
654
|
+
* [0.6, 0, 0.8, 1], // mask 1: bar
|
|
655
|
+
* ],
|
|
656
|
+
* });
|
|
657
|
+
*
|
|
588
658
|
* @interface
|
|
589
659
|
* @group Shaders
|
|
590
660
|
*/
|
|
@@ -595,6 +665,9 @@ export type OBJ_GenericGL = {
|
|
|
595
665
|
attributes?: Array<OBJ_GLAttribute>;
|
|
596
666
|
uniforms?: Array<OBJ_GLUniform>;
|
|
597
667
|
texture?: OBJ_Texture;
|
|
668
|
+
mask?: OBJ_TextureMask;
|
|
669
|
+
masks?: Array<OBJ_TextureMask>;
|
|
670
|
+
tints?: Array<TypeColor | null>;
|
|
598
671
|
dimension?: 2 | 3;
|
|
599
672
|
light?: 'directional' | 'point' | null;
|
|
600
673
|
vertices?: OBJ_GLVertexBuffer;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Number of recolorable regions a single mask texture provides in the
|
|
3
|
+
* `textureMap` color mode - one per channel (r, g, b, a). N masks therefore
|
|
4
|
+
* define `CHANNELS_PER_MASK * N` tints.
|
|
5
|
+
* @group Shaders
|
|
6
|
+
*/
|
|
7
|
+
export declare const CHANNELS_PER_MASK = 4;
|
|
1
8
|
/**
|
|
2
9
|
* Options used to compose vertex shader source code.
|
|
3
10
|
*
|
|
@@ -53,14 +60,14 @@
|
|
|
53
60
|
* to fragment shader used when `light = 'point'`
|
|
54
61
|
*
|
|
55
62
|
* @property {2 | 3} [dimension] (`2`)
|
|
56
|
-
* @property {'vertex' | 'uniform' | 'texture'} [color] (`uniform`)
|
|
63
|
+
* @property {'vertex' | 'uniform' | 'texture' | 'textureMap'} [color] (`uniform`)
|
|
57
64
|
* @property {'point' | 'directional' | null} [light] (`null`)
|
|
58
65
|
* @interface
|
|
59
66
|
* @group Shaders
|
|
60
67
|
*/
|
|
61
68
|
export type OBJ_VertexShader = {
|
|
62
69
|
light?: 'point' | 'directional' | null;
|
|
63
|
-
color?: 'vertex' | 'uniform' | 'texture';
|
|
70
|
+
color?: 'vertex' | 'uniform' | 'texture' | 'textureMap';
|
|
64
71
|
dimension?: 2 | 3;
|
|
65
72
|
};
|
|
66
73
|
/**
|
|
@@ -93,7 +100,16 @@ export type TypeVertexShader = string | {
|
|
|
93
100
|
* - `vec4 u_color`: global color for all vertices used all times. When
|
|
94
101
|
* `color = 'texture'` or `color = 'vertex'`, only the alpha channel of
|
|
95
102
|
* `u_color` is used.
|
|
96
|
-
* - `sampler2D u_texture`: texture used when `color = 'texture'
|
|
103
|
+
* - `sampler2D u_texture`: texture used when `color = 'texture'`,
|
|
104
|
+
* `color = 'textureAlpha'` or `color = 'textureMap'`.
|
|
105
|
+
* - `sampler2D u_mask0`, `u_mask1`, ...: mask textures used when
|
|
106
|
+
* `color = 'textureMap'` (one per mask, set by the `masks` count). Each mask's
|
|
107
|
+
* `r`, `g`, `b` and `a` channels select four regions of `u_texture` to
|
|
108
|
+
* recolor. Mask `m`'s four channels map to tints `u_tint{4m+0..3}`.
|
|
109
|
+
* - `vec4 u_tint0`, `u_tint1`, ...: region tint colors used when
|
|
110
|
+
* `color = 'textureMap'` (four per mask). The `rgb` channels are the tint
|
|
111
|
+
* color and the `a` channel is the tint strength (`0` leaves the base texture
|
|
112
|
+
* unchanged).
|
|
97
113
|
* - `vec3 u_directionalLight`: world space position of directional light
|
|
98
114
|
* source used when `light = 'directional'`
|
|
99
115
|
* - `float u_ambientLight`: ambient light used when `light = 'directional'` or
|
|
@@ -113,14 +129,15 @@ export type TypeVertexShader = string | {
|
|
|
113
129
|
* from vertex shader used when `light = 'point'`
|
|
114
130
|
*
|
|
115
131
|
* @property {2 | 3} [dimension] (`2`)
|
|
116
|
-
* @property {'vertex' | 'uniform' | 'texture'} [color] (`uniform`)
|
|
132
|
+
* @property {'vertex' | 'uniform' | 'texture' | 'textureMap'} [color] (`uniform`)
|
|
117
133
|
* @property {'point' | 'directional' | null} [light] (`null`)
|
|
118
134
|
* @interface
|
|
119
135
|
* @group Shaders
|
|
120
136
|
*/
|
|
121
137
|
export type OBJ_FragmentShader = {
|
|
122
138
|
light?: 'point' | 'directional' | null;
|
|
123
|
-
color?: 'vertex' | 'uniform' | 'texture';
|
|
139
|
+
color?: 'vertex' | 'uniform' | 'texture' | 'textureMap';
|
|
140
|
+
masks?: number;
|
|
124
141
|
};
|
|
125
142
|
/**
|
|
126
143
|
* A fragment shader can be defined with either:
|