@weasel-js/labkit 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/_dts/{CanvasStackContext-C0fzFsQg.d.ts → CanvasStackContext-B05ZM04l.d.ts} +3 -1
- package/dist/_dts/{Stage-Cvwxdnfp.d.ts → Stage-CIJlbjrE.d.ts} +5 -3
- package/dist/_dts/{index-DRaswz91.d.ts → index-8geQNQet.d.ts} +83 -11
- package/dist/_dts/{index-DEHRoTXK.d.ts → index-DRi3V5sN.d.ts} +5 -3
- package/dist/_dts/{useTrialState-CS4TdWPW.d.ts → useTrialState-Ar0AFpCe.d.ts} +94 -87
- package/dist/canvas/index.d.ts +4 -4
- package/dist/canvas/index.js +2 -2
- package/dist/chrome/index.d.ts +2 -2
- package/dist/chrome/index.js +7 -7
- package/dist/{chunk-YX75W6EK.js → chunk-4RCVWX4M.js} +8 -8
- package/dist/chunk-4RCVWX4M.js.map +1 -0
- package/dist/{chunk-WIG6XHJ7.js → chunk-6IIKLXBZ.js} +13 -4
- package/dist/chunk-6IIKLXBZ.js.map +1 -0
- package/dist/{chunk-F4ACIK7Z.js → chunk-6Q6ACJ3H.js} +3 -3
- package/dist/{chunk-F4ACIK7Z.js.map → chunk-6Q6ACJ3H.js.map} +1 -1
- package/dist/{chunk-PMLZP7RT.js → chunk-7ALJOVGP.js} +5 -9
- package/dist/chunk-7ALJOVGP.js.map +1 -0
- package/dist/{chunk-XE5HJOPL.js → chunk-7FMZT2WL.js} +3 -3
- package/dist/{chunk-XE5HJOPL.js.map → chunk-7FMZT2WL.js.map} +1 -1
- package/dist/{chunk-XVUKDSYV.js → chunk-AVOILDN2.js} +2 -2
- package/dist/{chunk-XVUKDSYV.js.map → chunk-AVOILDN2.js.map} +1 -1
- package/dist/{chunk-2N7UBSS2.js → chunk-J5MDJEOZ.js} +3 -3
- package/dist/{chunk-2N7UBSS2.js.map → chunk-J5MDJEOZ.js.map} +1 -1
- package/dist/{chunk-NVKBL7ZE.js → chunk-KHB3KRRQ.js} +7 -7
- package/dist/chunk-KHB3KRRQ.js.map +1 -0
- package/dist/{chunk-XXACAPVU.js → chunk-NHIO2O3O.js} +31 -30
- package/dist/chunk-NHIO2O3O.js.map +1 -0
- package/dist/{chunk-EESJUSYR.js → chunk-QMAY74TP.js} +56 -5
- package/dist/chunk-QMAY74TP.js.map +1 -0
- package/dist/{chunk-YDE6XATS.js → chunk-RN7T7OBO.js} +44 -22
- package/dist/chunk-RN7T7OBO.js.map +1 -0
- package/dist/{chunk-3L4MLLQB.js → chunk-RXO5UEGT.js} +4 -11
- package/dist/chunk-RXO5UEGT.js.map +1 -0
- package/dist/{chunk-MOTDMMMN.js → chunk-SQX35X5V.js} +3 -3
- package/dist/{chunk-MOTDMMMN.js.map → chunk-SQX35X5V.js.map} +1 -1
- package/dist/{chunk-J5HJJDLF.js → chunk-T5OEUNCB.js} +7 -2
- package/dist/chunk-T5OEUNCB.js.map +1 -0
- package/dist/{chunk-RL2LOLNI.js → chunk-UX66USTN.js} +2 -2
- package/dist/chunk-UX66USTN.js.map +1 -0
- package/dist/{chunk-WURZTJGQ.js → chunk-V4SMGEYY.js} +4858 -4806
- package/dist/chunk-V4SMGEYY.js.map +1 -0
- package/dist/{chunk-E23Q6A3Y.js → chunk-VCK5T6EP.js} +3 -3
- package/dist/{chunk-E23Q6A3Y.js.map → chunk-VCK5T6EP.js.map} +1 -1
- package/dist/{chunk-T6DLGEJB.js → chunk-XWR2P6MR.js} +23 -6
- package/dist/chunk-XWR2P6MR.js.map +1 -0
- package/dist/{chunk-7KAETQSS.js → chunk-YZA73U4A.js} +7 -7
- package/dist/chunk-YZA73U4A.js.map +1 -0
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +2 -2
- package/dist/controls/index.js +5 -5
- package/dist/dragdrop/index.d.ts +1 -1
- package/dist/dragdrop/index.js +2 -2
- package/dist/index.d.ts +157 -15
- package/dist/index.js +893 -258
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +1 -1
- package/dist/layers/index.js +3 -3
- package/dist/loupe/index.d.ts +175 -27
- package/dist/loupe/index.js +547 -141
- package/dist/loupe/index.js.map +1 -1
- package/dist/overview/index.js +5 -5
- package/dist/passthrough/weasel-ui.js +3 -3
- package/dist/primitives/index.d.ts +4 -19
- package/dist/primitives/index.js +7 -7
- package/dist/state/index.d.ts +5 -7
- package/dist/state/index.js +5 -5
- package/dist/styles.css +173 -38
- package/dist/surface/index.d.ts +20 -1
- package/dist/surface/index.js +2 -2
- package/dist/undo/index.d.ts +18 -7
- package/dist/undo/index.js +1 -1
- package/package.json +11 -11
- package/src/annotations/AnnotationOverlay.abandon.test.tsx +4 -0
- package/src/annotations/AnnotationOverlay.tsx +10 -1
- package/src/annotations/Annotations.less +2 -0
- package/src/annotations/Annotations.overlay.test.tsx +29 -0
- package/src/canvas/CanvasStack.test.tsx +35 -0
- package/src/canvas/CanvasStack.tsx +12 -1
- package/src/canvas/useLayerScheduler.ts +14 -0
- package/src/chrome/builtins.test.ts +14 -0
- package/src/chrome/builtins.tsx +17 -2
- package/src/chrome/regions/StatusRegion.tsx +20 -14
- package/src/chrome/regions/regions.test.tsx +28 -0
- package/src/chrome/types.ts +8 -0
- package/src/clock/clock.browser.test.less +5 -0
- package/src/clock/clock.browser.test.tsx +77 -0
- package/src/clock/clock.integration.test.tsx +95 -0
- package/src/clock/clockRegistry.test.ts +33 -0
- package/src/clock/clockRegistry.ts +46 -0
- package/src/clock/hooks.ts +44 -0
- package/src/clock/index.ts +2 -0
- package/src/clock/trialClock.test.ts +265 -0
- package/src/clock/trialClock.ts +245 -0
- package/src/clock/useClockLoop.ts +45 -0
- package/src/config/resolve.test.ts +12 -0
- package/src/config/resolve.ts +5 -0
- package/src/controls/ControlMatrix.tsx +56 -54
- package/src/index.ts +3 -2
- package/src/instrument/types.ts +21 -1
- package/src/lab/Lab.chrome.test.tsx +8 -1
- package/src/lab/Lab.presentation.test.tsx +113 -0
- package/src/lab/Lab.surface.test.tsx +20 -9
- package/src/lab/Lab.tsx +132 -257
- package/src/lab/LabLightbox.browser.test.less +17 -0
- package/src/lab/LabLightbox.browser.test.tsx +216 -0
- package/src/lab/LabShell.less +10 -3
- package/src/lab/LabSurface.tsx +129 -0
- package/src/lab/Workspace.stories.tsx +18 -0
- package/src/lab/Workspace.surface.test.tsx +4 -0
- package/src/lab/Workspace.test.tsx +37 -1
- package/src/lab/Workspace.tsx +34 -6
- package/src/lab/index.ts +2 -0
- package/src/lab/nebula.ts +30 -0
- package/src/lab/openLab.test.ts +81 -0
- package/src/lab/openLab.ts +119 -0
- package/src/lab/presentation.browser.test.less +5 -0
- package/src/lab/presentation.browser.test.tsx +119 -0
- package/src/lab/presentation.less +64 -0
- package/src/lab/presentation.tsx +47 -0
- package/src/lab/useFocusPick.ts +43 -0
- package/src/lightbox/Lightbox.browser.test.less +14 -0
- package/src/lightbox/Lightbox.browser.test.tsx +113 -0
- package/src/lightbox/Lightbox.less +128 -0
- package/src/lightbox/Lightbox.test.tsx +195 -0
- package/src/lightbox/Lightbox.tsx +205 -0
- package/src/lightbox/LightboxContext.ts +38 -0
- package/src/lightbox/LightboxLayers.tsx +40 -0
- package/src/lightbox/index.ts +8 -0
- package/src/lightbox/modal.ts +94 -0
- package/src/loupe/AGENTS.md +40 -2
- package/src/loupe/CanvasLoupe.tsx +5 -4
- package/src/loupe/DomLoupe.tsx +7 -5
- package/src/loupe/Loupe.less +15 -0
- package/src/loupe/LoupeBubble.tsx +35 -13
- package/src/loupe/SourceLoupe.browser.test.tsx +204 -0
- package/src/loupe/SourceLoupe.tsx +60 -0
- package/src/loupe/TrialLoupe.browser.test.tsx +342 -0
- package/src/loupe/TrialLoupe.tsx +126 -28
- package/src/loupe/canvasLens.ts +20 -17
- package/src/loupe/index.ts +26 -2
- package/src/loupe/sourceLens.test.ts +65 -0
- package/src/loupe/sourceLens.ts +97 -0
- package/src/loupe/types.test.ts +6 -0
- package/src/loupe/types.ts +109 -7
- package/src/loupe/useLoupe.test.tsx +188 -3
- package/src/loupe/useLoupe.ts +106 -11
- package/src/primitives/index.ts +2 -2
- package/src/specimen/Specimen.tsx +0 -7
- package/src/state/helpers.test.ts +4 -11
- package/src/state/helpers.ts +2 -8
- package/src/state/index.ts +0 -2
- package/src/state/openLabStore.test.ts +10 -8
- package/src/state/openLabStore.ts +1 -1
- package/src/state/store.test.ts +2 -2
- package/src/state/store.ts +15 -16
- package/src/state/types.ts +9 -9
- package/src/styles.less +2 -1
- package/src/surface/AGENTS.md +13 -0
- package/src/surface/index.ts +1 -0
- package/src/surface/useSurfaceTile.test.tsx +4 -0
- package/src/surface/useSurfaceTile.ts +17 -1
- package/src/surface/useTiledSurface.test.tsx +65 -0
- package/src/surface/useTiledSurface.ts +68 -1
- package/src/trial/Trial.stories.tsx +0 -1
- package/src/trial/Trial.test.tsx +40 -3
- package/src/trial/Trial.tsx +87 -43
- package/src/trial/TrialChrome.tsx +20 -2
- package/src/trial/trialOps.test.ts +1 -2
- package/src/trial/trialOps.ts +2 -3
- package/src/undo/stateOp.ts +21 -0
- package/src/undo/undoStack.ts +18 -6
- package/dist/chunk-3L4MLLQB.js.map +0 -1
- package/dist/chunk-7KAETQSS.js.map +0 -1
- package/dist/chunk-EESJUSYR.js.map +0 -1
- package/dist/chunk-J5HJJDLF.js.map +0 -1
- package/dist/chunk-NVKBL7ZE.js.map +0 -1
- package/dist/chunk-PMLZP7RT.js.map +0 -1
- package/dist/chunk-RL2LOLNI.js.map +0 -1
- package/dist/chunk-T6DLGEJB.js.map +0 -1
- package/dist/chunk-WIG6XHJ7.js.map +0 -1
- package/dist/chunk-WURZTJGQ.js.map +0 -1
- package/dist/chunk-XXACAPVU.js.map +0 -1
- package/dist/chunk-YDE6XATS.js.map +0 -1
- package/dist/chunk-YX75W6EK.js.map +0 -1
- package/src/primitives/StatusBar.less +0 -34
- package/src/primitives/StatusBar.stories.tsx +0 -24
- package/src/primitives/StatusBar.test.tsx +0 -25
- package/src/primitives/StatusBar.tsx +0 -28
package/dist/layers/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { LayerList, LayerListItem, LayerListProps, LayerMove, moveLayers } from '@weasel-js/ui';
|
|
2
|
-
export {
|
|
2
|
+
export { ae as LayerCapability, af as LayerDescriptor } from '../_dts/index-8geQNQet.js';
|
|
3
3
|
import '@weasel-js/core';
|
|
4
4
|
import 'react';
|
|
5
5
|
import '@weasel-js/theme';
|
package/dist/layers/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../chunk-2RVCB2PT.js';
|
|
2
|
-
export {
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
2
|
+
export { A2 as LayerList, T as moveLayers } from '../chunk-V4SMGEYY.js';
|
|
3
|
+
import '../chunk-VCK5T6EP.js';
|
|
4
|
+
import '../chunk-AVOILDN2.js';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
package/dist/loupe/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LoupePoint, LoupeMode } from '@weasel-js/loupe';
|
|
2
|
-
export { LoupeMode, LoupePoint } from '@weasel-js/loupe';
|
|
1
|
+
import { LoupePoint, LoupeMode, LoupeSize, CanvasSource, SourceCanvas, SourceContext, SourceBox } from '@weasel-js/loupe';
|
|
2
|
+
export { BandPlacement, CanvasSource, CanvasSourceOptions, LoupeMode, LoupePoint, LoupeSize, PlaceBandArgs, SourceBox, SourceCanvas, SourceContext, createCanvasSource, loupeExtent, placeBand } from '@weasel-js/loupe';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactNode, RefObject } from 'react';
|
|
5
5
|
import { CanvasStackSurface, CanvasLayerDescriptor } from '../canvas/index.js';
|
|
@@ -18,7 +18,8 @@ interface CanvasLoupeProps {
|
|
|
18
18
|
aim: LoupePoint;
|
|
19
19
|
factor: number;
|
|
20
20
|
mode: LoupeMode;
|
|
21
|
-
|
|
21
|
+
/** One number for a round or square lens, or a width and a height. */
|
|
22
|
+
diameter: LoupeSize;
|
|
22
23
|
/** The stack being magnified: its layers, its pixels, and its measured box. */
|
|
23
24
|
surface: CanvasStackSurface;
|
|
24
25
|
view: ViewTransform;
|
|
@@ -32,7 +33,7 @@ interface CanvasLoupeProps {
|
|
|
32
33
|
*/
|
|
33
34
|
declare function CanvasLoupe({ aim, factor, mode, diameter, surface, view, frame, worldSpec, }: CanvasLoupeProps): react.JSX.Element;
|
|
34
35
|
|
|
35
|
-
/** The camera a
|
|
36
|
+
/** The camera a lens of `size` shows a magnified region through, and
|
|
36
37
|
* the coordinate system it is read in — the instrument's own `WorldSpec`,
|
|
37
38
|
* resolved against the lens rather than the stack. */
|
|
38
39
|
interface LensCamera {
|
|
@@ -45,7 +46,7 @@ interface LensCamera {
|
|
|
45
46
|
* The lens is its own viewport, so the world spec resolves against its box: an
|
|
46
47
|
* instrument centred on its viewport is centred in the lens too.
|
|
47
48
|
*/
|
|
48
|
-
declare function lensCamera(aim: LoupePoint, outer: ViewTransform, outerFrame: WorldFrame, factor: number,
|
|
49
|
+
declare function lensCamera(aim: LoupePoint, outer: ViewTransform, outerFrame: WorldFrame, factor: number, size: LoupeSize, worldSpec?: WorldSpec): LensCamera;
|
|
49
50
|
/** A rectangle in a backing store's own device pixels. */
|
|
50
51
|
interface SourceRect {
|
|
51
52
|
sx: number;
|
|
@@ -54,10 +55,10 @@ interface SourceRect {
|
|
|
54
55
|
sh: number;
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
|
-
* The region a pixel-mode lens copies out of a presented canvas:
|
|
58
|
-
*
|
|
58
|
+
* The region a pixel-mode lens copies out of a presented canvas: `size /
|
|
59
|
+
* factor` CSS px around `aim`, in that canvas' backing-store pixels.
|
|
59
60
|
*/
|
|
60
|
-
declare function lensSourceRect(aim: LoupePoint, factor: number,
|
|
61
|
+
declare function lensSourceRect(aim: LoupePoint, factor: number, size: LoupeSize, dpr: number): SourceRect;
|
|
61
62
|
/**
|
|
62
63
|
* The color a stack presents at a point: the topmost visible layer with
|
|
63
64
|
* anything opaque there, or `null` when every layer is transparent — which is
|
|
@@ -69,7 +70,7 @@ declare function sampleStack(layers: readonly CanvasLayerDescriptor[], canvases:
|
|
|
69
70
|
declare function drawCanvasLens(ctx: CanvasRenderingContext2D, opts: {
|
|
70
71
|
aim: LoupePoint;
|
|
71
72
|
factor: number;
|
|
72
|
-
diameter:
|
|
73
|
+
diameter: LoupeSize;
|
|
73
74
|
dpr: number;
|
|
74
75
|
mode: 'vector' | 'pixel';
|
|
75
76
|
outer: ViewTransform;
|
|
@@ -79,6 +80,33 @@ declare function drawCanvasLens(ctx: CanvasRenderingContext2D, opts: {
|
|
|
79
80
|
canvases: Map<string, HTMLCanvasElement>;
|
|
80
81
|
}): void;
|
|
81
82
|
|
|
83
|
+
/** Anything a lens can be pointed at for its pixels: a `CanvasSource`, a
|
|
84
|
+
* canvas, a context on one, or a function returning any of those once it
|
|
85
|
+
* exists. */
|
|
86
|
+
type LoupeSourceTarget = CanvasSource | SourceCanvas | SourceContext;
|
|
87
|
+
type LoupeSource = LoupeSourceTarget | (() => LoupeSourceTarget | null | undefined);
|
|
88
|
+
/** `source` as a `CanvasSource`, or `null` while a getter has nothing yet. */
|
|
89
|
+
declare function resolveLoupeSource(source: LoupeSource | undefined): CanvasSource | null;
|
|
90
|
+
/**
|
|
91
|
+
* Where a source canvas sits over the lens's host, in the host's CSS px: its
|
|
92
|
+
* own `box` if it has one, else the canvas's laid-out box measured against the
|
|
93
|
+
* host, else — for an offscreen canvas, or one not on the page — the whole
|
|
94
|
+
* host.
|
|
95
|
+
*/
|
|
96
|
+
declare function sourceBoxIn(source: CanvasSource, host: HTMLElement | null): SourceBox;
|
|
97
|
+
/** The color a source shows at a host point, or `null` where it shows none. */
|
|
98
|
+
declare function sampleSource(source: CanvasSource, p: LoupePoint, box: SourceBox): string | null;
|
|
99
|
+
/** Enlarge the pixels of `source` around `aim` into a lens' own canvas, with
|
|
100
|
+
* smoothing off. Leaves the lens clear while the source has no frame. */
|
|
101
|
+
declare function drawSourceLens(ctx: CanvasRenderingContext2D, opts: {
|
|
102
|
+
aim: LoupePoint;
|
|
103
|
+
factor: number;
|
|
104
|
+
diameter: LoupeSize;
|
|
105
|
+
dpr: number;
|
|
106
|
+
source: CanvasSource;
|
|
107
|
+
box: SourceBox;
|
|
108
|
+
}): void;
|
|
109
|
+
|
|
82
110
|
/** What a DOM loupe's `render` is handed: the camera to draw the content
|
|
83
111
|
* through again. */
|
|
84
112
|
interface LoupeRenderArgs {
|
|
@@ -93,15 +121,62 @@ interface LoupeRenderArgs {
|
|
|
93
121
|
* not the lens. The lens shows a circle cut out of it. */
|
|
94
122
|
size: ViewportSize;
|
|
95
123
|
}
|
|
124
|
+
/** The outline of a lens. On a box that is not square, `'circle'` is an ellipse. */
|
|
125
|
+
type LoupeShape = 'circle' | 'square';
|
|
126
|
+
/** Where a host puts the lens for one aim, in the host's own CSS px. */
|
|
127
|
+
interface LoupePlacement {
|
|
128
|
+
/** Where the lens is drawn: the middle of its box. */
|
|
129
|
+
center: LoupePoint;
|
|
130
|
+
/** The host point the lens shows at its middle. Omitted, `center`; it
|
|
131
|
+
* differs when a lens is moved to stay on the host but keeps showing what
|
|
132
|
+
* it was placed over. */
|
|
133
|
+
shows?: LoupePoint;
|
|
134
|
+
width: number;
|
|
135
|
+
height: number;
|
|
136
|
+
/** The magnification for this placement. Omitted, the wheel's. */
|
|
137
|
+
factor?: number;
|
|
138
|
+
}
|
|
139
|
+
/** Where a lens is drawn and what it shows, once `place` has had its say. */
|
|
140
|
+
interface LoupeLens {
|
|
141
|
+
/** Where the lens is drawn: the middle of its box. */
|
|
142
|
+
center: LoupePoint;
|
|
143
|
+
/** The host point the lens shows at its middle. */
|
|
144
|
+
shows: LoupePoint;
|
|
145
|
+
width: number;
|
|
146
|
+
height: number;
|
|
147
|
+
/** What it magnifies by: the wheel's, unless `place` chose another. */
|
|
148
|
+
factor: number;
|
|
149
|
+
shape: LoupeShape;
|
|
150
|
+
}
|
|
151
|
+
/** What `place` is asked with. */
|
|
152
|
+
interface LoupePlaceArgs {
|
|
153
|
+
aim: LoupePoint;
|
|
154
|
+
factor: number;
|
|
155
|
+
}
|
|
96
156
|
/**
|
|
97
157
|
* How a lens magnifies.
|
|
98
158
|
*
|
|
99
159
|
* With no `render`, the lens re-draws the canvas stack's layers through a
|
|
100
160
|
* zoomed camera, so it stays sharp at any factor. Over DOM content, `render`
|
|
101
|
-
* draws it instead: given a camera, draw me again.
|
|
161
|
+
* draws it instead: given a camera, draw me again. With a `source`, it
|
|
162
|
+
* enlarges the pixels of that canvas — any canvas, labkit's or not.
|
|
102
163
|
*/
|
|
103
164
|
interface LoupeOptions {
|
|
104
165
|
render?: (args: LoupeRenderArgs) => ReactNode;
|
|
166
|
+
/**
|
|
167
|
+
* A canvas to read pixels from instead of the canvas stack: a
|
|
168
|
+
* `CanvasSource` from `createCanvasSource`, a canvas, a context on one, or
|
|
169
|
+
* a function returning one once it exists. 2D, WebGL and WebGL2 all work.
|
|
170
|
+
* Without `render` the lens enlarges its pixels, so the mode is `'pixel'`;
|
|
171
|
+
* with `render`, `render` draws the lens and the source answers
|
|
172
|
+
* `onColorChange`.
|
|
173
|
+
*
|
|
174
|
+
* A WebGL canvas made without `preserveDrawingBuffer` is blank to anyone
|
|
175
|
+
* reading it after the frame that drew it. Make its source with
|
|
176
|
+
* `createCanvasSource(gl)` and call `source.capture()` right after each
|
|
177
|
+
* draw; a canvas that draws on demand also passes `requestRedraw`.
|
|
178
|
+
*/
|
|
179
|
+
source?: LoupeSource;
|
|
105
180
|
/** Opening magnification, clamped to the bounds below. Default 6. */
|
|
106
181
|
factor?: number;
|
|
107
182
|
/** What the wheel clamps to. Defaults 2 and 32. */
|
|
@@ -109,26 +184,61 @@ interface LoupeOptions {
|
|
|
109
184
|
maxFactor?: number;
|
|
110
185
|
/** `'vector'` (default) re-renders the content magnified; `'pixel'` blows up
|
|
111
186
|
* the pixels the instrument presented. A `render` loupe is always vector —
|
|
112
|
-
* DOM has no framebuffer to enlarge. */
|
|
187
|
+
* DOM has no framebuffer to enlarge — and a `source` loupe always pixel. */
|
|
113
188
|
mode?: LoupeMode;
|
|
114
189
|
/** Lens diameter in CSS px. Default 200. */
|
|
115
190
|
diameter?: number;
|
|
191
|
+
/** Default `'circle'`. */
|
|
192
|
+
shape?: LoupeShape;
|
|
193
|
+
/**
|
|
194
|
+
* Puts the lens somewhere other than a `diameter` box on the aim: the lens is
|
|
195
|
+
* drawn with the returned box centered on `center`, and shows what is around
|
|
196
|
+
* `shows` (or `center`) magnified by the returned `factor`, or by the wheel's when it
|
|
197
|
+
* returns none. `factor` in the argument is always the wheel's, so a host
|
|
198
|
+
* lowering it to fit something in keeps the wheel as the ceiling. Returning
|
|
199
|
+
* `null` keeps the default. It is
|
|
200
|
+
* called while the lens renders, so a host whose content moves under a still
|
|
201
|
+
* pointer re-renders the lens to re-place it. The color under the aim is
|
|
202
|
+
* still the one `onColorChange` reports.
|
|
203
|
+
*/
|
|
204
|
+
place?: (at: LoupePlaceArgs) => LoupePlacement | null;
|
|
205
|
+
/**
|
|
206
|
+
* Draw only the lens's outline — ring, shadow, shape — and leave its inside
|
|
207
|
+
* empty, so whatever is under it shows through: for a host that draws the
|
|
208
|
+
* magnified view itself, into the box `onLens` reports. No painter runs; a
|
|
209
|
+
* `source`, if given, still answers `onColorChange`. Under a tiled surface,
|
|
210
|
+
* each move invalidates the tiles under the box it left and the box it now
|
|
211
|
+
* covers, so the host redraws those and no others.
|
|
212
|
+
*/
|
|
213
|
+
hollow?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Called with where the lens is drawn and what it shows, in host CSS px,
|
|
216
|
+
* whenever that changes — an aim, the wheel, `place`, `shape` — and with
|
|
217
|
+
* `null` when a lens that was up goes away.
|
|
218
|
+
*/
|
|
219
|
+
onLens?: (lens: LoupeLens | null) => void;
|
|
116
220
|
/** Held for a momentary peek while the loupe is off. Default `'Alt'`; `null`
|
|
117
221
|
* turns hold-to-peek off. Matched against `KeyboardEvent.key`. */
|
|
118
222
|
peekKey?: string | null;
|
|
119
223
|
/** Called with the color under the aim, wherever the surface can say. The
|
|
120
|
-
* canvas painter
|
|
224
|
+
* canvas painter and a `source` read it back; a DOM loupe with no `source`
|
|
225
|
+
* has no pixels to sample. */
|
|
121
226
|
onColorChange?: (hex: string) => void;
|
|
122
227
|
}
|
|
123
228
|
/** {@link LoupeOptions} with every default filled in. */
|
|
124
229
|
interface ResolvedLoupe {
|
|
125
230
|
render?: (args: LoupeRenderArgs) => ReactNode;
|
|
231
|
+
source?: LoupeSource;
|
|
126
232
|
onColorChange?: (hex: string) => void;
|
|
127
233
|
factor: number;
|
|
128
234
|
minFactor: number;
|
|
129
235
|
maxFactor: number;
|
|
130
236
|
mode: LoupeMode;
|
|
131
237
|
diameter: number;
|
|
238
|
+
shape: LoupeShape;
|
|
239
|
+
place?: (at: LoupePlaceArgs) => LoupePlacement | null;
|
|
240
|
+
hollow: boolean;
|
|
241
|
+
onLens?: (lens: LoupeLens | null) => void;
|
|
132
242
|
peekKey: string | null;
|
|
133
243
|
}
|
|
134
244
|
/** What `resolveLoupe` fills in for anything a declaration leaves unset. */
|
|
@@ -138,10 +248,13 @@ declare const LOUPE_DEFAULTS: {
|
|
|
138
248
|
readonly maxFactor: 32;
|
|
139
249
|
readonly mode: "vector";
|
|
140
250
|
readonly diameter: 200;
|
|
251
|
+
readonly shape: "circle";
|
|
252
|
+
readonly hollow: false;
|
|
141
253
|
readonly peekKey: "Alt";
|
|
142
254
|
};
|
|
143
255
|
/** `options` with every default filled in and `factor` clamped to
|
|
144
|
-
* `[minFactor, maxFactor]`. A loupe with its own `render` is always `'vector'
|
|
256
|
+
* `[minFactor, maxFactor]`. A loupe with its own `render` is always `'vector'`,
|
|
257
|
+
* and one with only a `source` always `'pixel'`. */
|
|
145
258
|
declare function resolveLoupe(options?: LoupeOptions): ResolvedLoupe;
|
|
146
259
|
|
|
147
260
|
/** Props for `<DomLoupe>`. */
|
|
@@ -149,7 +262,8 @@ interface DomLoupeProps {
|
|
|
149
262
|
aim: LoupePoint;
|
|
150
263
|
factor: number;
|
|
151
264
|
mode: LoupeMode;
|
|
152
|
-
|
|
265
|
+
/** One number for a round or square lens, or a width and a height. */
|
|
266
|
+
diameter: LoupeSize;
|
|
153
267
|
/** The host the instrument draws into, which the stage reproduces. */
|
|
154
268
|
size: ViewportSize;
|
|
155
269
|
/** The trial's own camera. */
|
|
@@ -163,28 +277,33 @@ interface DomLoupeProps {
|
|
|
163
277
|
*
|
|
164
278
|
* The stage is a full copy of the host, so the instrument's own layout still
|
|
165
279
|
* holds; the camera is composed about the aimed point, which keeps that point
|
|
166
|
-
* where it already was, and the stage is then slid by
|
|
167
|
-
* bring it to the middle of the lens.
|
|
280
|
+
* where it already was, and the stage is then slid by half the lens less `aim`
|
|
281
|
+
* to bring it to the middle of the lens.
|
|
168
282
|
*/
|
|
169
283
|
declare function DomLoupe({ aim, factor, mode, diameter, size, view, frame, render, }: DomLoupeProps): react.JSX.Element;
|
|
170
284
|
|
|
171
285
|
/** Props for `<LoupeBubble>`. */
|
|
172
286
|
interface LoupeBubbleProps {
|
|
173
|
-
/** Where the lens is
|
|
287
|
+
/** Where the lens is centered, in its container's own pixels. */
|
|
174
288
|
aim: LoupePoint;
|
|
175
|
-
|
|
289
|
+
/** One number for a round or square lens, or a width and a height. */
|
|
290
|
+
diameter: LoupeSize;
|
|
291
|
+
/** Default `'circle'`; on a box that is not square, `'circle'` is an ellipse. */
|
|
292
|
+
shape?: LoupeShape;
|
|
293
|
+
/** Only the ring and shadow: the inside is left clear for what is under it. */
|
|
294
|
+
hollow?: boolean;
|
|
176
295
|
hostRef?: RefObject<HTMLDivElement | null>;
|
|
177
|
-
children
|
|
296
|
+
children?: ReactNode;
|
|
178
297
|
}
|
|
179
298
|
/**
|
|
180
|
-
* The lens itself: a circle
|
|
181
|
-
* painter draws into it.
|
|
299
|
+
* The lens itself: a circle or a rectangle centered on `aim`, clipping whatever
|
|
300
|
+
* a painter draws into it.
|
|
182
301
|
*
|
|
183
302
|
* It takes no pointer events, so the pan, the wheel and anything underneath
|
|
184
303
|
* keep working while it is up — and it is `aria-hidden`, since it magnifies
|
|
185
304
|
* content already on the page rather than adding any.
|
|
186
305
|
*/
|
|
187
|
-
declare function LoupeBubble({ aim, diameter, hostRef, children }: LoupeBubbleProps): react.JSX.Element;
|
|
306
|
+
declare function LoupeBubble({ aim, diameter, shape, hollow, hostRef, children, }: LoupeBubbleProps): react.JSX.Element;
|
|
188
307
|
|
|
189
308
|
/**
|
|
190
309
|
* The loupe's two bindable interactions, as `Action` descriptors the gesture
|
|
@@ -234,6 +353,24 @@ interface LoupeGesturesProps {
|
|
|
234
353
|
*/
|
|
235
354
|
declare function LoupeGestures(props: LoupeGesturesProps): react.JSX.Element | null;
|
|
236
355
|
|
|
356
|
+
/** Props for `<SourceLoupe>`. */
|
|
357
|
+
interface SourceLoupeProps {
|
|
358
|
+
aim: LoupePoint;
|
|
359
|
+
factor: number;
|
|
360
|
+
/** One number for a round or square lens, or a width and a height. */
|
|
361
|
+
diameter: LoupeSize;
|
|
362
|
+
/** The canvas whose pixels the lens enlarges. */
|
|
363
|
+
source: LoupeSource;
|
|
364
|
+
/** The element `aim` is measured in, which the source's box is found against. */
|
|
365
|
+
hostRef: RefObject<HTMLElement | null>;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Paints a pixel lens from any canvas — one labkit drew or one it has never
|
|
369
|
+
* seen, 2D or WebGL. It redraws every frame, since the canvas it reads moves
|
|
370
|
+
* on its own schedule.
|
|
371
|
+
*/
|
|
372
|
+
declare function SourceLoupe({ aim, factor, diameter, source, hostRef }: SourceLoupeProps): react.JSX.Element;
|
|
373
|
+
|
|
237
374
|
/** Props for `<TrialLoupe>`. */
|
|
238
375
|
interface TrialLoupeProps extends LoupeOptions {
|
|
239
376
|
/** Whether the lens is turned on. Omitted, it follows the trial's toolbar
|
|
@@ -256,9 +393,9 @@ interface TrialLoupeProps extends LoupeOptions {
|
|
|
256
393
|
*
|
|
257
394
|
* With no `render` inside a `<CanvasStack>`, it re-draws the stack's own
|
|
258
395
|
* layers through a zoomed camera. With `render`, it asks for the content again
|
|
259
|
-
* at a magnified camera.
|
|
396
|
+
* at a magnified camera. With `source`, it enlarges the pixels of any canvas.
|
|
260
397
|
*/
|
|
261
|
-
declare function TrialLoupe({ enabled, view, hostRef, children, render, factor, minFactor, maxFactor, mode, diameter, peekKey, onColorChange, }: TrialLoupeProps): react.JSX.Element;
|
|
398
|
+
declare function TrialLoupe({ enabled, view, hostRef, children, render, source, factor, minFactor, maxFactor, mode, diameter, shape, place, hollow, onLens, peekKey, onColorChange, }: TrialLoupeProps): react.JSX.Element;
|
|
262
399
|
|
|
263
400
|
/** Options for {@link useLoupe}. */
|
|
264
401
|
interface UseLoupeOptions {
|
|
@@ -270,6 +407,12 @@ interface UseLoupeOptions {
|
|
|
270
407
|
/** Hex color at a host point. Omitted, the loupe reports no color — which
|
|
271
408
|
* is the honest answer for a surface with no pixels to read. */
|
|
272
409
|
sample?: (p: LoupePoint) => string | null;
|
|
410
|
+
/** Run `fn` whenever what `sample` reads changes without the aim moving — a
|
|
411
|
+
* canvas that animates, or a frame that arrives after the aim did; returns
|
|
412
|
+
* an unsubscribe. While the lens is up, each call samples the aim again, on
|
|
413
|
+
* top of the sample every aim takes at once. Omitted, color changes only on
|
|
414
|
+
* an aim. */
|
|
415
|
+
subscribeResample?: (fn: () => void) => () => void;
|
|
273
416
|
}
|
|
274
417
|
/** A loupe as a React view reads it. */
|
|
275
418
|
interface LoupeState {
|
|
@@ -277,11 +420,16 @@ interface LoupeState {
|
|
|
277
420
|
visible: boolean;
|
|
278
421
|
/** Where it is aimed, in the host's own pixels. */
|
|
279
422
|
aim: LoupePoint;
|
|
423
|
+
/** The wheel's magnification. What the lens shows at is `lens.factor`. */
|
|
280
424
|
factor: number;
|
|
425
|
+
/** The box the lens is drawn in, and what it shows. */
|
|
426
|
+
lens: LoupeLens;
|
|
281
427
|
mode: LoupeMode;
|
|
282
428
|
color: string | null;
|
|
283
429
|
setMode: (mode: LoupeMode) => void;
|
|
284
430
|
setFactor: (factor: number) => void;
|
|
431
|
+
/** Sample the aim again, for pixels that changed under a still aim. */
|
|
432
|
+
resample: () => void;
|
|
285
433
|
/** Sample what the lens shows at a point inside it. */
|
|
286
434
|
pick: (p?: LoupePoint) => string | null;
|
|
287
435
|
/** What `<LoupeGestures>` drives the lens through. Stable for the life of
|
|
@@ -299,7 +447,7 @@ interface LoupeState {
|
|
|
299
447
|
* has no continuous-motion entry, and inventing one to carry the lens' aim
|
|
300
448
|
* would be an input taxonomy change, not a loupe change.
|
|
301
449
|
*/
|
|
302
|
-
declare function useLoupe({ options, hostRef, enabled, sample }: UseLoupeOptions): LoupeState;
|
|
450
|
+
declare function useLoupe({ options, hostRef, enabled, sample, subscribeResample, }: UseLoupeOptions): LoupeState;
|
|
303
451
|
|
|
304
|
-
export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LOUPE_MAGNIFY_ID, LOUPE_PEEK_ID, LoupeBubble, LoupeGestures, TrialLoupe, createLoupeActions, drawCanvasLens, lensCamera, lensSourceRect, resolveLoupe, sampleStack, useLoupe };
|
|
305
|
-
export type { CanvasLoupeProps, DomLoupeProps, LensCamera, LoupeBubbleProps, LoupeGesturesProps, LoupeInputApi, LoupeOptions, LoupeRenderArgs, LoupeState, ResolvedLoupe, SourceRect, TrialLoupeProps, UseLoupeOptions };
|
|
452
|
+
export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LOUPE_MAGNIFY_ID, LOUPE_PEEK_ID, LoupeBubble, LoupeGestures, SourceLoupe, TrialLoupe, createLoupeActions, drawCanvasLens, drawSourceLens, lensCamera, lensSourceRect, resolveLoupe, resolveLoupeSource, sampleSource, sampleStack, sourceBoxIn, useLoupe };
|
|
453
|
+
export type { CanvasLoupeProps, DomLoupeProps, LensCamera, LoupeBubbleProps, LoupeGesturesProps, LoupeInputApi, LoupeLens, LoupeOptions, LoupePlaceArgs, LoupePlacement, LoupeRenderArgs, LoupeShape, LoupeSource, LoupeSourceTarget, LoupeState, ResolvedLoupe, SourceLoupeProps, SourceRect, TrialLoupeProps, UseLoupeOptions };
|