@fusion.dev/helix-core 0.187.0 → 0.189.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/custom-elements.json +555 -7
- package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.d.ts +2 -2
- package/dist/controllers/token-color-controller/token-color-controller.d.ts +2 -2
- package/dist/events/details.d.ts +12 -0
- package/dist/events/events.d.ts +6 -2
- package/dist/events/events.js +5 -1
- package/dist/events/names.js +2 -1
- package/dist/events/plot-change.d.ts +10 -0
- package/dist/events/plot-change.js +11 -0
- package/dist/events/plot-turn.d.ts +6 -0
- package/dist/events/plot-turn.js +11 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/mixins/mixin-viewport/mixin-viewport.d.ts +1 -3
- package/dist/utils/context-budget/context-budget.d.ts +47 -0
- package/dist/utils/context-budget/context-budget.js +48 -0
- package/dist/utils/create-sheet/create-sheet.d.ts +1 -1
- package/dist/utils/projection/projection.d.ts +98 -0
- package/dist/utils/projection/projection.js +144 -0
- package/dist/utils/report-runtime/report-runtime.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -38,8 +38,8 @@ type DisableableHost = ReactiveControllerHost & HTMLElement & {
|
|
|
38
38
|
*
|
|
39
39
|
* It adds no API. A group already has `disabled`, from `HelixFormElement` or
|
|
40
40
|
* from the consumer; nothing here introduces a property or a method for anyone
|
|
41
|
-
* to call.
|
|
42
|
-
*
|
|
41
|
+
* to call. Adding no API is what makes it a controller and not a mixin: it
|
|
42
|
+
* reacts to a lifecycle and nothing else.
|
|
43
43
|
*
|
|
44
44
|
* So a group states its members once, at construction, and never thinks about
|
|
45
45
|
* it again:
|
|
@@ -22,8 +22,8 @@ export type TokenColor = [number, number, number];
|
|
|
22
22
|
* written in next, which is the property worth having in a design system whose
|
|
23
23
|
* palette is derived rather than listed.
|
|
24
24
|
*
|
|
25
|
-
* **A controller and not a mixin**,
|
|
26
|
-
*
|
|
25
|
+
* **A controller and not a mixin**, because it adds no property or method a
|
|
26
|
+
* consumer sets. It reacts to lifecycle, holding a probe
|
|
27
27
|
* that has to be created after the host connects and removed when it leaves,
|
|
28
28
|
* and it watches for the color mode changing so the host can repaint.
|
|
29
29
|
*
|
package/dist/events/details.d.ts
CHANGED
|
@@ -363,6 +363,18 @@ export interface GraphPartChangeDetail {
|
|
|
363
363
|
*/
|
|
364
364
|
kind: 'data' | 'focus' | 'gestures';
|
|
365
365
|
}
|
|
366
|
+
/** Detail carried by `helix-plot-change`. */
|
|
367
|
+
export interface PlotChangeDetail {
|
|
368
|
+
/** `data` for the points or the axes, which are drawn again; `focus` for the point the keys rest on. */
|
|
369
|
+
kind: 'data' | 'focus';
|
|
370
|
+
}
|
|
371
|
+
/** Detail carried by `helix-plot-turn`. */
|
|
372
|
+
export interface PlotTurnDetail {
|
|
373
|
+
/** Steps to turn about the vertical, positive to the right. */
|
|
374
|
+
across: number;
|
|
375
|
+
/** Steps to tilt, positive to look from higher. */
|
|
376
|
+
up: number;
|
|
377
|
+
}
|
|
366
378
|
/** One signal between two notes, as the frame's `signal()` sends it. */
|
|
367
379
|
export interface GraphSignalDetail {
|
|
368
380
|
/** The note the signal leaves, by its `id`. */
|
package/dist/events/events.d.ts
CHANGED
|
@@ -91,6 +91,8 @@ import { HelixNextEvent } from './next.js';
|
|
|
91
91
|
import { HelixPanelResizeEvent } from './panel-resize.js';
|
|
92
92
|
import { HelixPastedEvent } from './pasted.js';
|
|
93
93
|
import { HelixPinEvent } from './pin.js';
|
|
94
|
+
import { HelixPlotChangeEvent } from './plot-change.js';
|
|
95
|
+
import { HelixPlotTurnEvent } from './plot-turn.js';
|
|
94
96
|
import { HelixPressEvent } from './press.js';
|
|
95
97
|
import { HelixPreviewEvent } from './preview.js';
|
|
96
98
|
import { HelixPreviousEvent } from './previous.js';
|
|
@@ -121,9 +123,9 @@ import { HelixToggleEvent } from './toggle.js';
|
|
|
121
123
|
import { HelixTourAskEvent } from './tour-ask.js';
|
|
122
124
|
import { HelixTourStatusEvent } from './tour-status.js';
|
|
123
125
|
import { HelixTypingEvent } from './typing.js';
|
|
124
|
-
export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DismissDetail, FacetDetail, FilterDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PasteDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReadingDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ReorderDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, StrandsFallbackDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
|
|
126
|
+
export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DismissDetail, FacetDetail, FilterDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PasteDetail, PlotChangeDetail, PlotTurnDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReadingDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ReorderDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, StrandsFallbackDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
|
|
125
127
|
export { helixEventNames } from './names.js';
|
|
126
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
128
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
127
129
|
/**
|
|
128
130
|
* Every event class, and the one place a new one is registered: a class in a
|
|
129
131
|
* module of its own, imported above, and named here and in `names.ts`.
|
|
@@ -200,6 +202,8 @@ declare const registry: {
|
|
|
200
202
|
readonly HelixPanelResizeEvent: typeof HelixPanelResizeEvent;
|
|
201
203
|
readonly HelixPastedEvent: typeof HelixPastedEvent;
|
|
202
204
|
readonly HelixPinEvent: typeof HelixPinEvent;
|
|
205
|
+
readonly HelixPlotChangeEvent: typeof HelixPlotChangeEvent;
|
|
206
|
+
readonly HelixPlotTurnEvent: typeof HelixPlotTurnEvent;
|
|
203
207
|
readonly HelixPressEvent: typeof HelixPressEvent;
|
|
204
208
|
readonly HelixPreviewEvent: typeof HelixPreviewEvent;
|
|
205
209
|
readonly HelixPreviousEvent: typeof HelixPreviousEvent;
|
package/dist/events/events.js
CHANGED
|
@@ -61,6 +61,8 @@ import { HelixNextEvent } from './next.js';
|
|
|
61
61
|
import { HelixPanelResizeEvent } from './panel-resize.js';
|
|
62
62
|
import { HelixPastedEvent } from './pasted.js';
|
|
63
63
|
import { HelixPinEvent } from './pin.js';
|
|
64
|
+
import { HelixPlotChangeEvent } from './plot-change.js';
|
|
65
|
+
import { HelixPlotTurnEvent } from './plot-turn.js';
|
|
64
66
|
import { HelixPressEvent } from './press.js';
|
|
65
67
|
import { HelixPreviewEvent } from './preview.js';
|
|
66
68
|
import { HelixPreviousEvent } from './previous.js';
|
|
@@ -92,7 +94,7 @@ import { HelixTourAskEvent } from './tour-ask.js';
|
|
|
92
94
|
import { HelixTourStatusEvent } from './tour-status.js';
|
|
93
95
|
import { HelixTypingEvent } from './typing.js';
|
|
94
96
|
export { helixEventNames } from './names.js';
|
|
95
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
97
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
96
98
|
const registry = {
|
|
97
99
|
HelixActionEvent,
|
|
98
100
|
HelixActivateEvent,
|
|
@@ -157,6 +159,8 @@ const registry = {
|
|
|
157
159
|
HelixPanelResizeEvent,
|
|
158
160
|
HelixPastedEvent,
|
|
159
161
|
HelixPinEvent,
|
|
162
|
+
HelixPlotChangeEvent,
|
|
163
|
+
HelixPlotTurnEvent,
|
|
160
164
|
HelixPressEvent,
|
|
161
165
|
HelixPreviewEvent,
|
|
162
166
|
HelixPreviousEvent,
|
package/dist/events/names.js
CHANGED
|
@@ -5,7 +5,8 @@ export const helixEventNames = new Set(('action activate aura-fallback band befo
|
|
|
5
5
|
'connect console copy copy-error create dismiss edit end expand facet filter ' +
|
|
6
6
|
'filtered graph-filter graph-layout graph-pan graph-part-change graph-ready ' +
|
|
7
7
|
'graph-signal graph-zoom history load load-more map-cluster map-pan map-part-change ' +
|
|
8
|
-
'map-ready map-rotate map-tilt map-zoom move navigate next panel-resize pasted pin
|
|
8
|
+
'map-ready map-rotate map-tilt map-zoom move navigate next panel-resize pasted pin plot-change ' +
|
|
9
|
+
'plot-turn press ' +
|
|
9
10
|
'preview previous range-change read reading-change reading-press reconnect reject ' +
|
|
10
11
|
'relabel remove reorder ' +
|
|
11
12
|
'reordered resize resized sample-end sample-start scrolled select selected send ' +
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PlotChangeDetail } from './details.js';
|
|
2
|
+
/**
|
|
3
|
+
* A plot's points or the point the keys rest on changed, which the connector
|
|
4
|
+
* hears and the renderer is told. It stays on the plot, being the family's
|
|
5
|
+
* own bookkeeping rather than news for a page.
|
|
6
|
+
*/
|
|
7
|
+
export declare class HelixPlotChangeEvent extends CustomEvent<PlotChangeDetail> {
|
|
8
|
+
static readonly eventName = "helix-plot-change";
|
|
9
|
+
constructor(detail: PlotChangeDetail);
|
|
10
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PlotTurnDetail } from './details.js';
|
|
2
|
+
/** The reader asked a 3D plot to turn by key: steps across and up, which the renderer turns by. */
|
|
3
|
+
export declare class HelixPlotTurnEvent extends CustomEvent<PlotTurnDetail> {
|
|
4
|
+
static readonly eventName = "helix-plot-turn";
|
|
5
|
+
constructor(detail: PlotTurnDetail);
|
|
6
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export { UpgradeController, type UpgradeOptions, } from './controllers/upgrade-c
|
|
|
38
38
|
export { type Rendered, VirtualizeController, type VirtualizeOptions, type Window as VirtualizeWindow, } from './controllers/virtualize-controller/virtualize-controller.js';
|
|
39
39
|
export { Waterfall } from './controllers/virtualize-controller/waterfall.js';
|
|
40
40
|
export { eventsForTag, registerElementEvents } from './events/element-events.js';
|
|
41
|
-
export { type ActivateDetail, type AuraFallbackDetail, type BandDetail, type CanvasView, type CaretDetail, type ChangeDetail, type CompleteDetail, type ConnectDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DismissDetail, type FacetDetail, type FilterDetail, type GraphFilterDetail, type GraphLayoutDetail, type GraphPartChangeDetail, type GraphSignalDetail, HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, type MapClusterDetail, type MapPanDetail, type MapPartChangeDetail, type MapRotateDetail, type MapTiltDetail, type MapZoomDetail, type MoveDetail, type NavigateDetail, type OpenDetail, type PasteDetail, type PressDetail, type PressPointerType, type RangeDetail, type ReadDetail, type ReadingDetail, type ReconnectDetail, type Refusal, type RefusedFile, type RejectDetail, type RelabelDetail, type RemoveDetail, type ReorderDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type StrandsFallbackDetail, type ToggleDetail, type TourStatusDetail, type TypingDetail, type ViewportPanDetail, type ViewportZoomDetail, } from './events/events.js';
|
|
41
|
+
export { type ActivateDetail, type AuraFallbackDetail, type BandDetail, type CanvasView, type CaretDetail, type ChangeDetail, type CompleteDetail, type ConnectDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DismissDetail, type FacetDetail, type FilterDetail, type GraphFilterDetail, type GraphLayoutDetail, type GraphPartChangeDetail, type GraphSignalDetail, HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, type MapClusterDetail, type MapPanDetail, type MapPartChangeDetail, type MapRotateDetail, type MapTiltDetail, type MapZoomDetail, type MoveDetail, type NavigateDetail, type OpenDetail, type PasteDetail, type PlotChangeDetail, type PlotTurnDetail, type PressDetail, type PressPointerType, type RangeDetail, type ReadDetail, type ReadingDetail, type ReconnectDetail, type Refusal, type RefusedFile, type RejectDetail, type RelabelDetail, type RemoveDetail, type ReorderDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type StrandsFallbackDetail, type ToggleDetail, type TourStatusDetail, type TypingDetail, type ViewportPanDetail, type ViewportZoomDetail, } from './events/events.js';
|
|
42
42
|
export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
|
|
43
43
|
export { MIRROR_RULE, SCROLLER_RULE, SPOKEN_RULE, VIRTUAL_RULE, } from './helix-element/mark-rules.js';
|
|
44
44
|
export { HelixFormElement } from './helix-form-element/helix-form-element.js';
|
|
@@ -74,6 +74,7 @@ export { clockLocale, dayPeriod, type HourCycle, isTwelveHour, nearestTime, offe
|
|
|
74
74
|
export { closestInstance } from './utils/closest-instance/closest-instance.js';
|
|
75
75
|
export { type ColorWords, colorName, hueName } from './utils/color-name/color-name.js';
|
|
76
76
|
export { columnStep } from './utils/column-step/column-step.js';
|
|
77
|
+
export { contextBudget, type Holder, LIVE, pageBudget, } from './utils/context-budget/context-budget.js';
|
|
77
78
|
export { countLabel } from './utils/count-label/count-label.js';
|
|
78
79
|
export { createSheet } from './utils/create-sheet/create-sheet.js';
|
|
79
80
|
export { type Color, type ColorFormat, formatColor, parseColor, toCss, toHsl, toOklch, toRgb, } from './utils/css-color/css-color.js';
|
|
@@ -119,6 +120,7 @@ export { applyOwnRule, type OwnRule } from './utils/own-rule/own-rule.js';
|
|
|
119
120
|
export { plainClick } from './utils/plain-click/plain-click.js';
|
|
120
121
|
export { appleTouch, onAndroid, onApple, type Platform } from './utils/platform/platform.js';
|
|
121
122
|
export { pressType, type RecentPress } from './utils/press-type/press-type.js';
|
|
123
|
+
export { type Camera, type Drawn, depthOrder, type Face, ISOMETRIC, LOWEST_TILT, type PagePoint, type Projection, pathData, projectionOf, type Solid, shortNumber, solid, } from './utils/projection/projection.js';
|
|
122
124
|
export { rangeAdd } from './utils/range-add/range-add.js';
|
|
123
125
|
export { type ColorBytes, type ColorBytesAlpha, readColor, readColorAlpha, rgbOf, } from './utils/read-color/read-color.js';
|
|
124
126
|
export { type ChartData, type ChartDatum, rowsFromData, seriesFromData, } from './utils/read-data/read-data.js';
|
package/dist/index.js
CHANGED
|
@@ -38,7 +38,7 @@ export { UpgradeController, } from './controllers/upgrade-controller/upgrade-con
|
|
|
38
38
|
export { VirtualizeController, } from './controllers/virtualize-controller/virtualize-controller.js';
|
|
39
39
|
export { Waterfall } from './controllers/virtualize-controller/waterfall.js';
|
|
40
40
|
export { eventsForTag, registerElementEvents } from './events/element-events.js';
|
|
41
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, } from './events/events.js';
|
|
41
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, } from './events/events.js';
|
|
42
42
|
export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
|
|
43
43
|
export { MIRROR_RULE, SCROLLER_RULE, SPOKEN_RULE, VIRTUAL_RULE, } from './helix-element/mark-rules.js';
|
|
44
44
|
export { HelixFormElement } from './helix-form-element/helix-form-element.js';
|
|
@@ -74,6 +74,7 @@ export { clockLocale, dayPeriod, isTwelveHour, nearestTime, offeredTimes, timeBa
|
|
|
74
74
|
export { closestInstance } from './utils/closest-instance/closest-instance.js';
|
|
75
75
|
export { colorName, hueName } from './utils/color-name/color-name.js';
|
|
76
76
|
export { columnStep } from './utils/column-step/column-step.js';
|
|
77
|
+
export { contextBudget, LIVE, pageBudget, } from './utils/context-budget/context-budget.js';
|
|
77
78
|
export { countLabel } from './utils/count-label/count-label.js';
|
|
78
79
|
export { createSheet } from './utils/create-sheet/create-sheet.js';
|
|
79
80
|
export { formatColor, parseColor, toCss, toHsl, toOklch, toRgb, } from './utils/css-color/css-color.js';
|
|
@@ -119,6 +120,7 @@ export { applyOwnRule } from './utils/own-rule/own-rule.js';
|
|
|
119
120
|
export { plainClick } from './utils/plain-click/plain-click.js';
|
|
120
121
|
export { appleTouch, onAndroid, onApple } from './utils/platform/platform.js';
|
|
121
122
|
export { pressType } from './utils/press-type/press-type.js';
|
|
123
|
+
export { depthOrder, ISOMETRIC, LOWEST_TILT, pathData, projectionOf, shortNumber, solid, } from './utils/projection/projection.js';
|
|
122
124
|
export { rangeAdd } from './utils/range-add/range-add.js';
|
|
123
125
|
export { readColor, readColorAlpha, rgbOf, } from './utils/read-color/read-color.js';
|
|
124
126
|
export { rowsFromData, seriesFromData, } from './utils/read-data/read-data.js';
|
|
@@ -128,9 +128,7 @@ export declare class ViewportElement {
|
|
|
128
128
|
* first and its frame turned out to be a surface a reader can move, fill the
|
|
129
129
|
* screen with, and stop touching: a canvas of notes and a graph of nodes want
|
|
130
130
|
* the same four hundred lines, and the only thing that made them Map's was
|
|
131
|
-
* being written there. Extracted before the second consumer
|
|
132
|
-
* which is the opposite of what [#383](queue.md) had to conclude about a
|
|
133
|
-
* controller promoted ahead of one.
|
|
131
|
+
* being written there. Extracted before the second consumer arrived.
|
|
134
132
|
*
|
|
135
133
|
* **Nothing here moves anything, either.** Both controls ask, through an event
|
|
136
134
|
* a family names, and the answer is the consumer's: the surface a reader is
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How many WebGL contexts Helix's three.js drivers keep live on one page.
|
|
3
|
+
*
|
|
4
|
+
* **A browser holds only so many, and drops the oldest without asking**:
|
|
5
|
+
* Chrome about sixteen on a desktop and fewer on a phone. A page of 3D panels
|
|
6
|
+
* past that lost a graph it could not get back, and the maps, Aura, and
|
|
7
|
+
* Strands on the same page count against the same limit. Six leaves them
|
|
8
|
+
* room.
|
|
9
|
+
*/
|
|
10
|
+
export declare const LIVE = 6;
|
|
11
|
+
/** One drawing that holds a context: it gives the context back, and takes it again. */
|
|
12
|
+
export interface Holder {
|
|
13
|
+
release(): void;
|
|
14
|
+
restore(): void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Keeps the contexts a page's drawings hold under `cap`.
|
|
18
|
+
*
|
|
19
|
+
* **A drawing near the screen always keeps its context.** Past the cap, the
|
|
20
|
+
* drawings off screen give theirs back, the one away longest first, and each
|
|
21
|
+
* takes its context again as it comes near. So a page of any number of
|
|
22
|
+
* graphs holds as many contexts as it shows at once, and never more than
|
|
23
|
+
* `cap` beyond that.
|
|
24
|
+
*/
|
|
25
|
+
export declare const contextBudget: (cap?: number) => {
|
|
26
|
+
/** A drawing far from the screen, from `now`. */
|
|
27
|
+
far(holder: Holder, now: number): void;
|
|
28
|
+
/** How many drawings hold a context now. */
|
|
29
|
+
readonly holding: number;
|
|
30
|
+
/** A new drawing, which made a context to draw with. */
|
|
31
|
+
join(holder: Holder): void;
|
|
32
|
+
/** A drawing that ended and freed its context itself. */
|
|
33
|
+
leave(holder: Holder): void;
|
|
34
|
+
/** A drawing near the screen, which takes its context again where it gave it back. */
|
|
35
|
+
near(holder: Holder): void;
|
|
36
|
+
};
|
|
37
|
+
type Budget = ReturnType<typeof contextBudget>;
|
|
38
|
+
/**
|
|
39
|
+
* The budget every three.js driver on the page shares: the graph's and the
|
|
40
|
+
* plot's, whichever package and whichever copy of Helix each came from.
|
|
41
|
+
*
|
|
42
|
+
* **Kept on the page, under a registered symbol**, since a page can load two
|
|
43
|
+
* copies of this module, one bundled with each driver, and two budgets of six
|
|
44
|
+
* would let the page hold twelve.
|
|
45
|
+
*/
|
|
46
|
+
export declare const pageBudget: () => Budget;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const LIVE = 6;
|
|
2
|
+
export const contextBudget = (cap = LIVE) => {
|
|
3
|
+
const holding = new Set();
|
|
4
|
+
const away = new Map();
|
|
5
|
+
const balance = () => {
|
|
6
|
+
const longest = [...away]
|
|
7
|
+
.filter(([holder]) => holding.has(holder))
|
|
8
|
+
.sort((one, other) => one[1] - other[1]);
|
|
9
|
+
for (const [holder] of longest) {
|
|
10
|
+
if (holding.size <= cap) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
holding.delete(holder);
|
|
14
|
+
holder.release();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
far(holder, now) {
|
|
19
|
+
away.set(holder, now);
|
|
20
|
+
balance();
|
|
21
|
+
},
|
|
22
|
+
get holding() {
|
|
23
|
+
return holding.size;
|
|
24
|
+
},
|
|
25
|
+
join(holder) {
|
|
26
|
+
holding.add(holder);
|
|
27
|
+
balance();
|
|
28
|
+
},
|
|
29
|
+
leave(holder) {
|
|
30
|
+
holding.delete(holder);
|
|
31
|
+
away.delete(holder);
|
|
32
|
+
},
|
|
33
|
+
near(holder) {
|
|
34
|
+
away.delete(holder);
|
|
35
|
+
if (!holding.has(holder)) {
|
|
36
|
+
holding.add(holder);
|
|
37
|
+
holder.restore();
|
|
38
|
+
}
|
|
39
|
+
balance();
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export const pageBudget = () => {
|
|
44
|
+
const key = Symbol.for('fusion.dev/helix/context-budget');
|
|
45
|
+
const page = globalThis;
|
|
46
|
+
page[key] ??= contextBudget();
|
|
47
|
+
return page[key];
|
|
48
|
+
};
|
|
@@ -9,7 +9,7 @@ import { type CSSResult } from 'lit';
|
|
|
9
9
|
*
|
|
10
10
|
* The `unsafe` in `unsafeCSS` warns about interpolating untrusted input into a
|
|
11
11
|
* stylesheet. That is not what happens here: the argument is a build-time
|
|
12
|
-
* constant read from a file in
|
|
12
|
+
* constant read from a file in the package, never a runtime value. Wrapping it
|
|
13
13
|
* keeps the warning where it belongs, on `unsafeCSS` itself, and gives one seam
|
|
14
14
|
* to change if constructable stylesheets become the better primitive.
|
|
15
15
|
*/
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a drawing in three dimensions stands on the page, seen from a camera
|
|
3
|
+
* that can turn and tilt, with no perspective, as SVG path data. Shared by
|
|
4
|
+
* every spatial drawing Helix makes in SVG: the graph's isometric diagram,
|
|
5
|
+
* the spatial heatmap, and the spatial charts' own drawings.
|
|
6
|
+
*
|
|
7
|
+
* Pure, so the arithmetic a picture hides is held by a spec: a solid painted
|
|
8
|
+
* in the wrong order is covered by the one it should cover, and a face turned
|
|
9
|
+
* away is drawn over the faces in front of it.
|
|
10
|
+
*
|
|
11
|
+
* **The floor is measured in cells.** A place at `x: 2, y: 1` stands two
|
|
12
|
+
* cells across and one back, and a height is in the same unit. From the
|
|
13
|
+
* isometric camera, across runs down to the right on the page and back runs
|
|
14
|
+
* up to the right, as a plan is seen from its front left corner.
|
|
15
|
+
*/
|
|
16
|
+
/** A point on the page, in cells. */
|
|
17
|
+
export interface PagePoint {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Where the diagram is seen from, in degrees: `turn`, the compass bearing
|
|
23
|
+
* the camera looks from, and `tilt`, its height above the floor, from a low
|
|
24
|
+
* angle to 90, a plan seen straight down.
|
|
25
|
+
*/
|
|
26
|
+
export interface Camera {
|
|
27
|
+
tilt: number;
|
|
28
|
+
turn: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The isometric camera: from the front left corner, at the height where the
|
|
32
|
+
* floor's two axes and the vertical are drawn the same length, 35.26 degrees.
|
|
33
|
+
*/
|
|
34
|
+
export declare const ISOMETRIC: Camera;
|
|
35
|
+
/** The lowest a camera may tilt, below which the floor folds to a line. */
|
|
36
|
+
export declare const LOWEST_TILT = 15;
|
|
37
|
+
/** A camera's view of the floor. */
|
|
38
|
+
export interface Projection {
|
|
39
|
+
/** A place on the floor and a height, on the page. */
|
|
40
|
+
at(x: number, y: number, z?: number): PagePoint;
|
|
41
|
+
/** How near the camera a place on the floor stands: the larger, the nearer. */
|
|
42
|
+
depth(x: number, y: number): number;
|
|
43
|
+
/** The place on the floor drawn at a point on the page. */
|
|
44
|
+
floorAt(point: PagePoint): PagePoint;
|
|
45
|
+
/** Toward the camera from the floor, a unit length: across, back, and up. */
|
|
46
|
+
toward: readonly [number, number, number];
|
|
47
|
+
/** Across the page, in floor directions: how far a step across or back goes to the right. */
|
|
48
|
+
across: readonly [number, number];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The view from `camera`, an orthographic one: the floor turned by `turn`
|
|
52
|
+
* and seen from `tilt` above it, with no perspective, so a cell is the same
|
|
53
|
+
* size wherever it stands.
|
|
54
|
+
*/
|
|
55
|
+
export declare const projectionOf: (camera: Camera) => Projection;
|
|
56
|
+
/** The solids a note can be drawn as, a block, a cylinder, or a pyramid. */
|
|
57
|
+
export type Solid = 'block' | 'cylinder' | 'pyramid';
|
|
58
|
+
/** A number written short enough for path data, and never as `-0`. */
|
|
59
|
+
export declare const shortNumber: (value: number) => string;
|
|
60
|
+
export declare const pathData: (points: readonly PagePoint[]) => string;
|
|
61
|
+
/** One face of a solid, as path data, and how far it is darkened toward black. */
|
|
62
|
+
export interface Face {
|
|
63
|
+
d: string;
|
|
64
|
+
/** From 0, the note's own color, as a top facing the light takes it. */
|
|
65
|
+
darken: number;
|
|
66
|
+
}
|
|
67
|
+
/** One note drawn as a solid: the faces the camera sees, in the order to paint them. */
|
|
68
|
+
export interface Drawn {
|
|
69
|
+
/** How high the solid reaches on the page: the top of its outline, which its name is drawn above. */
|
|
70
|
+
crown: number;
|
|
71
|
+
/** The faces the camera sees, the sides first and the top last. */
|
|
72
|
+
faces: Face[];
|
|
73
|
+
/** The outline of the whole solid, which a ring is drawn along. */
|
|
74
|
+
outline: string;
|
|
75
|
+
/** The middle of the solid's top, which its name is centered over. */
|
|
76
|
+
peak: PagePoint;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A note as a solid, standing on the floor at `x` and `y`, `width` cells
|
|
80
|
+
* across its footprint and `height` cells tall, as the camera sees it.
|
|
81
|
+
*
|
|
82
|
+
* **Each face is drawn only where it turns toward the camera**, so a block
|
|
83
|
+
* shows its top and the two sides that face the viewer from any turn, and a
|
|
84
|
+
* plan seen from straight above shows tops alone.
|
|
85
|
+
*/
|
|
86
|
+
export declare const solid: (projection: Projection, kind: Solid, x: number, y: number, width: number, height: number) => Drawn;
|
|
87
|
+
/**
|
|
88
|
+
* The order to paint notes in, back to front: by how near the camera each
|
|
89
|
+
* stands on the floor, and the taller first where two stand level.
|
|
90
|
+
*
|
|
91
|
+
* Exact for notes on whole cells, which do not overlap on the floor; two
|
|
92
|
+
* notes placed inside one cell can still cross.
|
|
93
|
+
*/
|
|
94
|
+
export declare const depthOrder: <T extends {
|
|
95
|
+
height: number;
|
|
96
|
+
x: number;
|
|
97
|
+
y: number;
|
|
98
|
+
}>(projection: Projection, notes: readonly T[]) => T[];
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export const ISOMETRIC = { tilt: (Math.atan(Math.SQRT1_2) * 180) / Math.PI, turn: 45 };
|
|
2
|
+
export const LOWEST_TILT = 15;
|
|
3
|
+
const SCALE = Math.sqrt(1.5);
|
|
4
|
+
export const projectionOf = (camera) => {
|
|
5
|
+
const turn = (camera.turn * Math.PI) / 180;
|
|
6
|
+
const tilt = (Math.min(Math.max(camera.tilt, LOWEST_TILT), 90) * Math.PI) / 180;
|
|
7
|
+
const [cos, sin] = [Math.cos(turn), Math.sin(turn)];
|
|
8
|
+
const [rise, fall] = [Math.sin(tilt), Math.cos(tilt)];
|
|
9
|
+
return {
|
|
10
|
+
across: [cos, sin],
|
|
11
|
+
at: (x, y, z = 0) => ({
|
|
12
|
+
x: (x * cos + y * sin) * SCALE,
|
|
13
|
+
y: ((x * sin - y * cos) * rise - z * fall) * SCALE,
|
|
14
|
+
}),
|
|
15
|
+
depth: (x, y) => x * sin - y * cos,
|
|
16
|
+
floorAt: (point) => {
|
|
17
|
+
const u = point.x / SCALE;
|
|
18
|
+
const v = point.y / SCALE / rise;
|
|
19
|
+
return { x: u * cos + v * sin, y: u * sin - v * cos };
|
|
20
|
+
},
|
|
21
|
+
toward: [sin * fall, -cos * fall, rise],
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export const shortNumber = (value) => String(Math.round(value * 1000) / 1000 || 0);
|
|
25
|
+
export const pathData = (points) => `M${points.map((point) => `${shortNumber(point.x)} ${shortNumber(point.y)}`).join('L')}Z`;
|
|
26
|
+
const hullOf = (points) => {
|
|
27
|
+
const sorted = [...points].sort((one, other) => one.x - other.x || one.y - other.y);
|
|
28
|
+
if (sorted.length < 3) {
|
|
29
|
+
return sorted;
|
|
30
|
+
}
|
|
31
|
+
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
|
32
|
+
const half = (list) => {
|
|
33
|
+
const kept = [];
|
|
34
|
+
for (const point of list) {
|
|
35
|
+
while (kept.length >= 2 &&
|
|
36
|
+
cross(kept.at(-2), kept.at(-1), point) <= 0) {
|
|
37
|
+
kept.pop();
|
|
38
|
+
}
|
|
39
|
+
kept.push(point);
|
|
40
|
+
}
|
|
41
|
+
kept.pop();
|
|
42
|
+
return kept;
|
|
43
|
+
};
|
|
44
|
+
return [...half(sorted), ...half([...sorted].reverse())];
|
|
45
|
+
};
|
|
46
|
+
const darkenOf = (normal, projection) => {
|
|
47
|
+
const [x, y, z] = normal;
|
|
48
|
+
const length = Math.hypot(x, y, z) || 1;
|
|
49
|
+
const level = Math.hypot(x, y) || 1;
|
|
50
|
+
const right = (x * projection.across[0] + y * projection.across[1]) / level;
|
|
51
|
+
return Math.max(0, 0.28 + 0.113 * right) * (1 - z / length);
|
|
52
|
+
};
|
|
53
|
+
const facing = (normal, projection) => normal[0] * projection.toward[0] +
|
|
54
|
+
normal[1] * projection.toward[1] +
|
|
55
|
+
normal[2] * projection.toward[2] >
|
|
56
|
+
1e-6;
|
|
57
|
+
const ARC = 12;
|
|
58
|
+
export const solid = (projection, kind, x, y, width, height) => {
|
|
59
|
+
const half = width / 2;
|
|
60
|
+
const tall = Math.max(0, height);
|
|
61
|
+
const on = (corner) => projection.at(corner[0], corner[1], corner[2]);
|
|
62
|
+
if (kind === 'cylinder') {
|
|
63
|
+
const turn = Math.atan2(projection.across[1], projection.across[0]);
|
|
64
|
+
const rim = (z, from, to) => Array.from({ length: ARC + 1 }, (_, step) => {
|
|
65
|
+
const angle = from + ((to - from) * step) / ARC;
|
|
66
|
+
return projection.at(x + Math.cos(angle) * half, y + Math.sin(angle) * half, z);
|
|
67
|
+
});
|
|
68
|
+
const near = rim(0, turn + Math.PI, turn + 2 * Math.PI);
|
|
69
|
+
const nearTop = rim(tall, turn + Math.PI, turn + 2 * Math.PI);
|
|
70
|
+
const farTop = rim(tall, turn, turn + Math.PI);
|
|
71
|
+
const top = rim(tall, 0, 2 * Math.PI).slice(0, -1);
|
|
72
|
+
const side = projection.toward[2] < 0.9999 && tall > 0;
|
|
73
|
+
const outline = hullOf([...farTop, ...nearTop, ...near]);
|
|
74
|
+
return {
|
|
75
|
+
crown: Math.min(...outline.map((point) => point.y)),
|
|
76
|
+
faces: [
|
|
77
|
+
...(side ? [{ d: pathData([...nearTop, ...[...near].reverse()]), darken: 0.28 }] : []),
|
|
78
|
+
{ d: pathData(top), darken: 0 },
|
|
79
|
+
],
|
|
80
|
+
outline: pathData(outline),
|
|
81
|
+
peak: projection.at(x, y, tall),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const floor = [
|
|
85
|
+
[x - half, y - half, 0],
|
|
86
|
+
[x + half, y - half, 0],
|
|
87
|
+
[x + half, y + half, 0],
|
|
88
|
+
[x - half, y + half, 0],
|
|
89
|
+
];
|
|
90
|
+
const outward = [
|
|
91
|
+
[0, -1, 0],
|
|
92
|
+
[1, 0, 0],
|
|
93
|
+
[0, 1, 0],
|
|
94
|
+
[-1, 0, 0],
|
|
95
|
+
];
|
|
96
|
+
const faces = [];
|
|
97
|
+
let corners;
|
|
98
|
+
let peak;
|
|
99
|
+
if (kind === 'pyramid') {
|
|
100
|
+
const apex = [x, y, Math.max(tall, width)];
|
|
101
|
+
corners = [...floor, apex];
|
|
102
|
+
peak = on(apex);
|
|
103
|
+
floor.forEach((corner, at) => {
|
|
104
|
+
const next = floor[(at + 1) % 4];
|
|
105
|
+
const [ox, oy] = outward[at];
|
|
106
|
+
const normal = [ox * apex[2], oy * apex[2], half];
|
|
107
|
+
if (facing(normal, projection)) {
|
|
108
|
+
faces.push({
|
|
109
|
+
d: pathData([on(corner), on(next), on(apex)]),
|
|
110
|
+
darken: darkenOf(normal, projection),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
const up = (corner) => [corner[0], corner[1], tall];
|
|
117
|
+
corners = [...floor, ...floor.map(up)];
|
|
118
|
+
peak = projection.at(x, y, tall);
|
|
119
|
+
if (tall > 0) {
|
|
120
|
+
floor.forEach((corner, at) => {
|
|
121
|
+
const next = floor[(at + 1) % 4];
|
|
122
|
+
const normal = outward[at];
|
|
123
|
+
if (facing(normal, projection)) {
|
|
124
|
+
faces.push({
|
|
125
|
+
d: pathData([on(up(corner)), on(up(next)), on(next), on(corner)]),
|
|
126
|
+
darken: darkenOf(normal, projection),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
faces.push({ d: pathData(floor.map(up).map(on)), darken: 0 });
|
|
132
|
+
}
|
|
133
|
+
const outline = hullOf(corners.map(on));
|
|
134
|
+
return {
|
|
135
|
+
crown: Math.min(...outline.map((point) => point.y)),
|
|
136
|
+
faces,
|
|
137
|
+
outline: pathData(outline),
|
|
138
|
+
peak,
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
export const depthOrder = (projection, notes) => [...notes].sort((one, other) => {
|
|
142
|
+
const nearer = projection.depth(one.x, one.y) - projection.depth(other.x, other.y);
|
|
143
|
+
return Math.abs(nearer) > 1e-9 ? nearer : other.height - one.height;
|
|
144
|
+
});
|
|
@@ -61,6 +61,8 @@ export type RuntimeKind =
|
|
|
61
61
|
| 'negative-value'
|
|
62
62
|
/** A Graph connector was handed an element that is no Graph frame. */
|
|
63
63
|
| 'not-a-graph'
|
|
64
|
+
/** A plot connector was handed an element that is not the spatial chart it connects. */
|
|
65
|
+
| 'not-a-plot'
|
|
64
66
|
/** The browser refused picture in picture. */
|
|
65
67
|
| 'picture-in-picture-refused'
|
|
66
68
|
/** A Grid's `min` is no length it can write, so the grid lays out by its column count. */
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.189.0';
|