json-canvas-viewer 4.1.0 → 4.2.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/dist/chimp.js +396 -1
- package/dist/index.d.ts +29 -618
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/kernel/BaseModule.d.ts +27 -0
- package/dist/kernel/BaseModule.js +2 -2
- package/dist/kernel/BaseModule.js.map +1 -1
- package/dist/kernel/Controller.d.ts +30 -0
- package/dist/kernel/Controller.js +2 -2
- package/dist/kernel/Controller.js.map +1 -1
- package/dist/kernel/DataManager.d.ts +67 -0
- package/dist/kernel/DataManager.js +2 -2
- package/dist/kernel/DataManager.js.map +1 -1
- package/dist/kernel/InteractionHandler.d.ts +51 -0
- package/dist/kernel/InteractionHandler.js +2 -2
- package/dist/kernel/InteractionHandler.js.map +1 -1
- package/dist/kernel/OverlayManager.d.ts +62 -0
- package/dist/kernel/OverlayManager.js +2 -2
- package/dist/kernel/OverlayManager.js.map +1 -1
- package/dist/kernel/Renderer.d.ts +37 -0
- package/dist/kernel/Renderer.js +3 -2
- package/dist/kernel/Renderer.js.map +1 -1
- package/dist/kernel/StyleManager.d.ts +135 -0
- package/dist/kernel/StyleManager.js +2 -2
- package/dist/kernel/StyleManager.js.map +1 -1
- package/dist/kernel/index.d.ts +46 -0
- package/dist/kernel/index.js +2 -2
- package/dist/kernel/index.js.map +1 -1
- package/dist/kernel/styles.js +285 -0
- package/dist/kernel/styles.js.map +1 -0
- package/dist/kernel/types.d.ts +33 -0
- package/dist/kernel/utilities.d.ts +13 -0
- package/dist/kernel/utilities.js +2 -2
- package/dist/kernel/utilities.js.map +1 -1
- package/dist/modules/Controls/index.d.ts +42 -0
- package/dist/modules/Controls/index.js +2 -2
- package/dist/modules/Controls/index.js.map +1 -1
- package/dist/modules/Controls/styles.js +29 -0
- package/dist/modules/Controls/styles.js.map +1 -0
- package/dist/modules/DebugPanel/index.d.ts +14 -0
- package/dist/modules/DebugPanel/index.js +2 -2
- package/dist/modules/DebugPanel/index.js.map +1 -1
- package/dist/modules/DebugPanel/styles.js +13 -0
- package/dist/modules/DebugPanel/styles.js.map +1 -0
- package/dist/modules/Minimap/index.d.ts +36 -0
- package/dist/modules/Minimap/index.js +2 -2
- package/dist/modules/Minimap/index.js.map +1 -1
- package/dist/modules/Minimap/styles.js +56 -0
- package/dist/modules/Minimap/styles.js.map +1 -0
- package/dist/modules/MistouchPreventer/index.d.ts +29 -0
- package/dist/modules/MistouchPreventer/index.js +2 -2
- package/dist/modules/MistouchPreventer/index.js.map +1 -1
- package/dist/modules/MistouchPreventer/styles.js +21 -0
- package/dist/modules/MistouchPreventer/styles.js.map +1 -0
- package/dist/shared/index.d.ts +50 -0
- package/dist/utilities/fetch-canvas.d.ts +7 -0
- package/dist/utilities/fetch-canvas.js +2 -0
- package/dist/utilities/fetch-canvas.js.map +1 -0
- package/dist/utilities/parser.d.ts +5 -0
- package/dist/utilities/parser.js +2 -2
- package/dist/utilities/parser.js.map +1 -1
- package/dist/utilities/render-to-string.d.ts +12 -0
- package/dist/utilities/render-to-string.js +2 -0
- package/dist/utilities/render-to-string.js.map +1 -0
- package/package.json +8 -7
- package/dist/kernel/styles.scss.js +0 -2
- package/dist/kernel/styles.scss.js.map +0 -1
- package/dist/modules/Controls/styles.scss.js +0 -2
- package/dist/modules/Controls/styles.scss.js.map +0 -1
- package/dist/modules/DebugPanel/styles.scss.js +0 -2
- package/dist/modules/DebugPanel/styles.scss.js.map +0 -1
- package/dist/modules/Minimap/styles.scss.js +0 -2
- package/dist/modules/Minimap/styles.scss.js.map +0 -1
- package/dist/modules/MistouchPreventer/styles.scss.js +0 -2
- package/dist/modules/MistouchPreventer/styles.scss.js.map +0 -1
- package/dist/utilities/fetchCanvas.js +0 -2
- package/dist/utilities/fetchCanvas.js.map +0 -1
- package/dist/utilities/renderToString.js +0 -2
- package/dist/utilities/renderToString.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
class
|
|
2
|
-
//# sourceMappingURL=BaseModule.js.map
|
|
1
|
+
var e=class{onStart;onRestart;onDispose;constructor(e,t,n,r,i,a){this.container=e,this.augment=a,this.options=t,this.onStart=n.subscribe,this.onDispose=r.subscribe,this.onRestart=i.subscribe}options};export{e as BaseModule};
|
|
2
|
+
//# sourceMappingURL=BaseModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseModule.js","sources":["../../src/kernel/BaseModule.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { General, GeneralObject, ModuleInput as MI, Orchestratable } from '$/types';\nimport type
|
|
1
|
+
{"version":3,"file":"BaseModule.js","names":[],"sources":["../../src/kernel/BaseModule.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { General, GeneralObject, ModuleInput as MI, Orchestratable } from '$/types';\nimport type { Hook } from '$/utilities';\nimport type { Container } from '@needle-di/core';\n\nexport type GeneralModuleCtor = typeof BaseModule<General, General>;\nexport type GeneralModule = BaseModule<General, General>;\n\nexport type ModuleInputCtor = Array<GeneralModuleCtor>;\nexport type ModuleInput = MI<GeneralModuleCtor>;\nexport type Options<M extends ModuleInput> = Orchestratable<M, 'options'>;\nexport type Augmentation<M extends ModuleInput> = Orchestratable<M, '_Augmentation'>;\n\nexport type BaseArgs = ConstructorParameters<GeneralModuleCtor>;\n\nexport class BaseModule<O extends BaseOptions = BaseOptions, A extends GeneralObject = {}> {\n\t// https://github.com/timocov/dts-bundle-generator/issues/360\n\tdeclare private static readonly _BaseModuleBrand: unique symbol; // Nominal marker\n\tdeclare _Augmentation: A;\n\tonStart: Hook['subscribe'];\n\tonRestart: Hook['subscribe'];\n\tonDispose: Hook['subscribe'];\n\t// oxlint-disable-next-line max-params\n\tconstructor(\n\t\tprotected container: Container,\n\t\toptions: GeneralObject,\n\t\tonStart: Hook,\n\t\tonDispose: Hook,\n\t\tonRestart: Hook,\n\t\tprotected augment: (aug: A) => void,\n\t) {\n\t\tthis.options = options as O;\n\t\tthis.onStart = onStart.subscribe;\n\t\tthis.onDispose = onDispose.subscribe;\n\t\tthis.onRestart = onRestart.subscribe;\n\t}\n\toptions: O;\n}\n"],"mappings":"AAeA,IAAa,EAAb,KAA2F,CAI1F,QACA,UACA,UAEA,YACC,EACA,EACA,EACA,EACA,EACA,EACC,CANS,KAAA,UAAA,EAKA,KAAA,QAAA,EAEV,KAAK,QAAU,EACf,KAAK,QAAU,EAAQ,UACvB,KAAK,UAAY,EAAU,UAC3B,KAAK,UAAY,EAAU,UAE5B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Hook } from "./utilities.js";
|
|
2
|
+
import { BaseArgs, BaseModule } from "./BaseModule.js";
|
|
3
|
+
import { BaseOptions } from "./index.js";
|
|
4
|
+
|
|
5
|
+
//#region src/kernel/Controller.d.ts
|
|
6
|
+
type Augmentation = {
|
|
7
|
+
refresh: Controller['refresh'];
|
|
8
|
+
onRefresh: Controller['onRefresh'];
|
|
9
|
+
onResize: Controller['onResize'];
|
|
10
|
+
};
|
|
11
|
+
declare class Controller extends BaseModule<BaseOptions, Augmentation> {
|
|
12
|
+
private animationId;
|
|
13
|
+
private resizeAnimationId;
|
|
14
|
+
private readonly DM;
|
|
15
|
+
private readonly SM;
|
|
16
|
+
private readonly resizeObserver;
|
|
17
|
+
private perFrame;
|
|
18
|
+
private readonly lastResizeCenter;
|
|
19
|
+
onResize: Hook<[number, number], false>;
|
|
20
|
+
onRefresh: Hook<[], false>;
|
|
21
|
+
constructor(...args: BaseArgs);
|
|
22
|
+
private readonly start;
|
|
23
|
+
private readonly draw;
|
|
24
|
+
refresh: () => void;
|
|
25
|
+
private readonly onResizeCallback;
|
|
26
|
+
private readonly dispose;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { Controller };
|
|
30
|
+
//# sourceMappingURL=Controller.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseModule as e}from"./BaseModule.js";import
|
|
2
|
-
//# sourceMappingURL=Controller.js.map
|
|
1
|
+
import{BaseModule as e}from"./BaseModule.js";import{makeHook as t}from"./utilities.js";import n from"./DataManager.js";import r from"./StyleManager.js";var i=class extends e{animationId;resizeAnimationId;DM;SM;resizeObserver;perFrame={lastOffsets:{x:0,y:0},lastScale:1};lastResizeCenter={x:void 0,y:void 0};onResize=t();onRefresh=t();constructor(...e){super(...e),this.DM=this.container.get(n),this.SM=this.container.get(r),this.resizeObserver=new ResizeObserver(this.onResizeCallback),this.SM.onChangeTheme.subscribe(this.refresh),this.augment({onRefresh:this.onRefresh,onResize:this.onResize,refresh:this.refresh}),this.onStart(this.start),this.onRestart(this.refresh),this.onDispose(this.dispose)}start=()=>{this.resizeObserver.observe(this.DM.data.container),this.animationId=requestAnimationFrame(this.draw)};draw=()=>{(this.perFrame.lastScale!==this.DM.data.scale||this.perFrame.lastOffsets.x!==this.DM.data.offsetX||this.perFrame.lastOffsets.y!==this.DM.data.offsetY)&&this.refresh(),this.animationId=requestAnimationFrame(this.draw)};refresh=()=>{this.perFrame={lastOffsets:{x:this.DM.data.offsetX,y:this.DM.data.offsetY},lastScale:this.DM.data.scale},this.onRefresh()};onResizeCallback=()=>{this.resizeAnimationId=requestAnimationFrame(()=>{let e=this.DM.middleViewer();this.lastResizeCenter.x&&this.lastResizeCenter.y&&(this.DM.data.offsetX=this.DM.data.offsetX+e.x-this.lastResizeCenter.x,this.DM.data.offsetY=this.DM.data.offsetY+e.y-this.lastResizeCenter.y),this.lastResizeCenter.x=e.x,this.lastResizeCenter.y=e.y,this.onResize(e.width,e.height),this.refresh()})};dispose=()=>{this.animationId&&cancelAnimationFrame(this.animationId),this.resizeAnimationId&&cancelAnimationFrame(this.resizeAnimationId),this.resizeObserver.disconnect()}};export{i as default};
|
|
2
|
+
//# sourceMappingURL=Controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Controller.js","sources":["../../src/kernel/Controller.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport {
|
|
1
|
+
{"version":3,"file":"Controller.js","names":[],"sources":["../../src/kernel/Controller.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { BaseArgs } from '$/BaseModule';\nimport { BaseModule } from '$/BaseModule';\nimport DataManager from '$/DataManager';\nimport StyleManager from '$/StyleManager';\nimport { makeHook } from '$/utilities';\n\ntype Augmentation = {\n\trefresh: Controller['refresh'];\n\tonRefresh: Controller['onRefresh'];\n\tonResize: Controller['onResize'];\n};\n\nexport default class Controller extends BaseModule<BaseOptions, Augmentation> {\n\tprivate animationId: undefined | number;\n\tprivate resizeAnimationId: undefined | number;\n\tprivate readonly DM: DataManager;\n\tprivate readonly SM: StyleManager;\n\tprivate readonly resizeObserver: ResizeObserver;\n\tprivate perFrame: {\n\t\tlastScale: number;\n\t\tlastOffsets: { x: number; y: number };\n\t} = {\n\t\tlastOffsets: { x: 0, y: 0 },\n\t\tlastScale: 1,\n\t};\n\tprivate readonly lastResizeCenter: {\n\t\tx: undefined | number;\n\t\ty: undefined | number;\n\t} = {\n\t\tx: undefined,\n\t\ty: undefined,\n\t};\n\n\tonResize = makeHook<[number, number]>();\n\tonRefresh = makeHook();\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis.SM = this.container.get(StyleManager);\n\t\tthis.resizeObserver = new ResizeObserver(this.onResizeCallback);\n\t\tthis.SM.onChangeTheme.subscribe(this.refresh);\n\t\tthis.augment({\n\t\t\tonRefresh: this.onRefresh,\n\t\t\tonResize: this.onResize,\n\t\t\trefresh: this.refresh,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onRestart(this.refresh);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate readonly start = () => {\n\t\tthis.resizeObserver.observe(this.DM.data.container);\n\t\tthis.animationId = requestAnimationFrame(this.draw);\n\t};\n\n\tprivate readonly draw = () => {\n\t\tif (\n\t\t\tthis.perFrame.lastScale !== this.DM.data.scale ||\n\t\t\tthis.perFrame.lastOffsets.x !== this.DM.data.offsetX ||\n\t\t\tthis.perFrame.lastOffsets.y !== this.DM.data.offsetY\n\t\t)\n\t\t\tthis.refresh();\n\t\tthis.animationId = requestAnimationFrame(this.draw);\n\t};\n\n\trefresh = () => {\n\t\tthis.perFrame = {\n\t\t\tlastOffsets: { x: this.DM.data.offsetX, y: this.DM.data.offsetY },\n\t\t\tlastScale: this.DM.data.scale,\n\t\t};\n\t\tthis.onRefresh();\n\t};\n\n\tprivate readonly onResizeCallback = () => {\n\t\tthis.resizeAnimationId = requestAnimationFrame(() => {\n\t\t\tconst center = this.DM.middleViewer();\n\t\t\tif (this.lastResizeCenter.x && this.lastResizeCenter.y) {\n\t\t\t\tthis.DM.data.offsetX = this.DM.data.offsetX + center.x - this.lastResizeCenter.x;\n\t\t\t\tthis.DM.data.offsetY = this.DM.data.offsetY + center.y - this.lastResizeCenter.y;\n\t\t\t}\n\t\t\tthis.lastResizeCenter.x = center.x;\n\t\t\tthis.lastResizeCenter.y = center.y;\n\t\t\tthis.onResize(center.width, center.height);\n\t\t\tthis.refresh();\n\t\t});\n\t};\n\n\tprivate readonly dispose = () => {\n\t\tif (this.animationId) cancelAnimationFrame(this.animationId);\n\t\tif (this.resizeAnimationId) cancelAnimationFrame(this.resizeAnimationId);\n\t\tthis.resizeObserver.disconnect();\n\t};\n}\n"],"mappings":"wJAaA,IAAqB,EAArB,cAAwC,CAAsC,CAC7E,YACA,kBACA,GACA,GACA,eACA,SAGI,CACH,YAAa,CAAE,EAAG,EAAG,EAAG,EAAG,CAC3B,UAAW,EACX,CACD,iBAGI,CACH,EAAG,IAAA,GACH,EAAG,IAAA,GACH,CAED,SAAW,GAA4B,CACvC,UAAY,GAAU,CAEtB,YAAY,GAAG,EAAgB,CAC9B,MAAM,GAAG,EAAK,CACd,KAAK,GAAK,KAAK,UAAU,IAAI,EAAY,CACzC,KAAK,GAAK,KAAK,UAAU,IAAI,EAAa,CAC1C,KAAK,eAAiB,IAAI,eAAe,KAAK,iBAAiB,CAC/D,KAAK,GAAG,cAAc,UAAU,KAAK,QAAQ,CAC7C,KAAK,QAAQ,CACZ,UAAW,KAAK,UAChB,SAAU,KAAK,SACf,QAAS,KAAK,QACd,CAAC,CACF,KAAK,QAAQ,KAAK,MAAM,CACxB,KAAK,UAAU,KAAK,QAAQ,CAC5B,KAAK,UAAU,KAAK,QAAQ,CAG7B,UAA+B,CAC9B,KAAK,eAAe,QAAQ,KAAK,GAAG,KAAK,UAAU,CACnD,KAAK,YAAc,sBAAsB,KAAK,KAAK,EAGpD,SAA8B,EAE5B,KAAK,SAAS,YAAc,KAAK,GAAG,KAAK,OACzC,KAAK,SAAS,YAAY,IAAM,KAAK,GAAG,KAAK,SAC7C,KAAK,SAAS,YAAY,IAAM,KAAK,GAAG,KAAK,UAE7C,KAAK,SAAS,CACf,KAAK,YAAc,sBAAsB,KAAK,KAAK,EAGpD,YAAgB,CACf,KAAK,SAAW,CACf,YAAa,CAAE,EAAG,KAAK,GAAG,KAAK,QAAS,EAAG,KAAK,GAAG,KAAK,QAAS,CACjE,UAAW,KAAK,GAAG,KAAK,MACxB,CACD,KAAK,WAAW,EAGjB,qBAA0C,CACzC,KAAK,kBAAoB,0BAA4B,CACpD,IAAM,EAAS,KAAK,GAAG,cAAc,CACjC,KAAK,iBAAiB,GAAK,KAAK,iBAAiB,IACpD,KAAK,GAAG,KAAK,QAAU,KAAK,GAAG,KAAK,QAAU,EAAO,EAAI,KAAK,iBAAiB,EAC/E,KAAK,GAAG,KAAK,QAAU,KAAK,GAAG,KAAK,QAAU,EAAO,EAAI,KAAK,iBAAiB,GAEhF,KAAK,iBAAiB,EAAI,EAAO,EACjC,KAAK,iBAAiB,EAAI,EAAO,EACjC,KAAK,SAAS,EAAO,MAAO,EAAO,OAAO,CAC1C,KAAK,SAAS,EACb,EAGH,YAAiC,CAC5B,KAAK,aAAa,qBAAqB,KAAK,YAAY,CACxD,KAAK,mBAAmB,qBAAqB,KAAK,kBAAkB,CACxE,KAAK,eAAe,YAAY"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Box, NodeBounds } from "./types.js";
|
|
2
|
+
import { JSONCanvas, JSONCanvasEdge, JSONCanvasNode } from "../shared/index.js";
|
|
3
|
+
import { Hook } from "./utilities.js";
|
|
4
|
+
import { BaseArgs, BaseModule } from "./BaseModule.js";
|
|
5
|
+
import { BaseOptions } from "./index.js";
|
|
6
|
+
|
|
7
|
+
//#region src/kernel/DataManager.d.ts
|
|
8
|
+
type Options = {
|
|
9
|
+
shadowed?: boolean;
|
|
10
|
+
canvas?: JSONCanvas;
|
|
11
|
+
attachmentDir?: string;
|
|
12
|
+
extraCSS?: string;
|
|
13
|
+
attachments?: Record<string, string>;
|
|
14
|
+
noAttachmentRelocation?: boolean;
|
|
15
|
+
} & BaseOptions;
|
|
16
|
+
type Augmentation = {
|
|
17
|
+
resetView: DataManager['resetView'];
|
|
18
|
+
toggleFullscreen: DataManager['toggleFullscreen'];
|
|
19
|
+
onToggleFullscreen: DataManager['onToggleFullscreen'];
|
|
20
|
+
};
|
|
21
|
+
type NodeItem = {
|
|
22
|
+
ref: JSONCanvasNode;
|
|
23
|
+
box: Box;
|
|
24
|
+
fileName?: string;
|
|
25
|
+
onBeforeUnmount?: Hook;
|
|
26
|
+
onActive?: Hook;
|
|
27
|
+
onLoseActive?: Hook;
|
|
28
|
+
};
|
|
29
|
+
type EdgeItem = {
|
|
30
|
+
ref: JSONCanvasEdge;
|
|
31
|
+
box: Box;
|
|
32
|
+
controlPoints?: Array<number>;
|
|
33
|
+
};
|
|
34
|
+
type NodeMap = Record<string, NodeItem>;
|
|
35
|
+
type EdgeMap = Record<string, EdgeItem>;
|
|
36
|
+
declare class DataManager extends BaseModule<Options, Augmentation> {
|
|
37
|
+
onToggleFullscreen: Hook<["enter" | "exit"], false>;
|
|
38
|
+
data: {
|
|
39
|
+
canvasData: Required<JSONCanvas>;
|
|
40
|
+
nodeMap: NodeMap;
|
|
41
|
+
edgeMap: EdgeMap;
|
|
42
|
+
canvasBaseDir: string;
|
|
43
|
+
nodeBounds: NodeBounds;
|
|
44
|
+
offsetX: number;
|
|
45
|
+
offsetY: number;
|
|
46
|
+
scale: number;
|
|
47
|
+
container: HTMLDivElement;
|
|
48
|
+
};
|
|
49
|
+
constructor(...args: BaseArgs);
|
|
50
|
+
private readonly start;
|
|
51
|
+
private readonly processBaseDir;
|
|
52
|
+
private readonly getNodeBox;
|
|
53
|
+
private readonly getEdgeBox;
|
|
54
|
+
private calculateNodeBounds;
|
|
55
|
+
toggleFullscreen: (option?: "enter" | "exit") => Promise<void>;
|
|
56
|
+
resetView: () => void;
|
|
57
|
+
middleViewer: () => {
|
|
58
|
+
height: number;
|
|
59
|
+
width: number;
|
|
60
|
+
x: number;
|
|
61
|
+
y: number;
|
|
62
|
+
};
|
|
63
|
+
private readonly dispose;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { DataManager };
|
|
67
|
+
//# sourceMappingURL=DataManager.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseModule as
|
|
2
|
-
//# sourceMappingURL=DataManager.js.map
|
|
1
|
+
import{BaseModule as e}from"./BaseModule.js";import t from"./styles.js";import{applyStyles as n,getAnchorCoord as r,makeHook as i}from"./utilities.js";var a=class extends e{onToggleFullscreen=i();data={canvasBaseDir:`./`,canvasData:{edges:[],nodes:[]},container:document.createElement(`div`),edgeMap:{},nodeBounds:{centerX:0,centerY:0,height:0,maxX:0,maxY:0,minX:0,minY:0,width:0},nodeMap:{},offsetX:0,offsetY:0,scale:1};constructor(...e){super(...e);let r=this.options.container;for(;r.firstElementChild;)r.firstElementChild.remove();r.innerHTML=``;let i=this.options.shadowed?r.attachShadow({mode:`open`}):r;n(i,t+this.options.extraCSS),this.data.container.classList.add(`JSON-Canvas-Viewer`),i.appendChild(this.data.container),this.augment({onToggleFullscreen:this.onToggleFullscreen,resetView:this.resetView,toggleFullscreen:this.toggleFullscreen}),this.onStart(this.start),this.onRestart(this.start),this.onDispose(this.dispose)}start=()=>{let e={edges:[],nodes:[],...this.options.canvas};Object.assign(this.data,{canvasBaseDir:this.processBaseDir(this.options.attachmentDir),canvasData:e,edgeMap:{},nodeBounds:this.calculateNodeBounds(e),nodeMap:{},offsetX:0,offsetY:0,scale:1}),this.data.canvasData.nodes.forEach(e=>{let t={box:this.getNodeBox(e),ref:e};if(this.data.nodeMap[e.id]=t,e.type===`file`){let n=e.file.split(`/`).pop()??``;if(t.fileName=n,!e.file.startsWith(`http://`)&&!e.file.startsWith(`https://`)){let t=this.options.attachments?.[n];t?e.file=t:this.options.noAttachmentRelocation||(e.file=this.data.canvasBaseDir+n)}}}),this.data.canvasData.edges.forEach(e=>{this.data.edgeMap[e.id]={box:this.getEdgeBox(e),ref:e}}),this.resetView()};processBaseDir=e=>e?e?.slice(-1)===`/`?e:`${e}/`:`./`;getNodeBox=e=>({bottom:e.y+e.height,left:e.x,right:e.width+e.x,top:e.type===`file`||e.type===`group`?e.y-40:e.y});getEdgeBox=e=>{let t=this.data.nodeMap,n=t[e.fromNode].ref,i=t[e.toNode].ref,a=r(n,e.fromSide),o=r(i,e.toSide),s={bottom:Math.max(a.y,o.y),left:Math.min(a.x,o.x),right:Math.max(a.x,o.x),top:Math.min(a.y,o.y)},c=s.right-s.left,l=s.bottom-s.top,u=Math.min(c,l),d=Math.log2(Math.max(c,l)/(u===0?1:u))*10;return{bottom:s.bottom+d,left:s.left-d,right:s.right+d,top:s.top-d}};calculateNodeBounds(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;e.nodes.forEach(e=>{t=Math.min(t,e.x),n=Math.min(n,e.y),r=Math.max(r,e.x+e.width),i=Math.max(i,e.y+e.height)});let a=r-t,o=i-n;return{centerX:t+a/2,centerY:n+o/2,height:o,maxX:r,maxY:i,minX:t,minY:n,width:a}}toggleFullscreen=async e=>{!document.fullscreenElement&&(!e||e===`enter`)?(await this.data.container.requestFullscreen(),this.onToggleFullscreen(`enter`)):document.fullscreenElement&&(!e||e===`exit`)&&(await document.exitFullscreen(),this.onToggleFullscreen(`exit`))};resetView=()=>{let e=this.data.nodeBounds,t=this.data.container;if(!e||!t)return;let n=e.width+200,r=e.height+200,i=t.clientWidth,a=t.clientHeight,o=i/n,s=a/r,c=Math.round(Math.min(o,s)*1e3)/1e3,l=e.centerX,u=e.centerY,d={offsetX:i/2-l*c,offsetY:a/2-u*c,scale:c};this.data.offsetX=d.offsetX,this.data.offsetY=d.offsetY,this.data.scale=d.scale};middleViewer=()=>{let e=this.data.container;return{height:e.clientHeight,width:e.clientWidth,x:e.clientWidth/2,y:e.clientHeight/2}};dispose=()=>{this.data.container.remove()}};export{a as default};
|
|
2
|
+
//# sourceMappingURL=DataManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataManager.js","sources":["../../src/kernel/DataManager.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { Box, NodeBounds } from '$/types';\nimport type { JSONCanvas, JSONCanvasEdge, JSONCanvasNode } from '@repo/shared';\nimport { type BaseArgs, BaseModule } from '$/BaseModule';\nimport style from '$/styles.scss?inline';\nimport utilities, { type Hook } from '$/utilities';\n\nconst INITIAL_VIEWPORT_PADDING = 100;\nconst NODE_LABEL_MARGIN = 40;\nconst EDGE_BOX_HEURISTICS_BASE_MARGIN = 10;\n\ninterface Options extends BaseOptions {\n\tshadowed?: boolean;\n\tcanvas?: JSONCanvas;\n\tattachmentDir?: string;\n\textraCSS?: string;\n\tattachments?: Record<string, string>;\n\tnoAttachmentRelocation?: boolean;\n}\n\ninterface Augmentation {\n\tresetView: DataManager['resetView'];\n\ttoggleFullscreen: DataManager['toggleFullscreen'];\n\tonToggleFullscreen: DataManager['onToggleFullscreen'];\n}\n\nexport interface NodeItem {\n\tref: JSONCanvasNode;\n\tbox: Box;\n\tfileName?: string;\n\tonBeforeUnmount?: Hook;\n\tonActive?: Hook;\n\tonLoseActive?: Hook;\n}\n\nexport interface EdgeItem {\n\tref: JSONCanvasEdge;\n\tbox: Box;\n\tcontrolPoints?: Array<number>;\n}\n\ntype NodeMap = Record<string, NodeItem>;\ntype EdgeMap = Record<string, EdgeItem>;\n\nexport default class DataManager extends BaseModule<Options, Augmentation> {\n\tonToggleFullscreen = utilities.makeHook<['enter' | 'exit']>();\n\n\tdata: {\n\t\tcanvasData: Required<JSONCanvas>;\n\t\tnodeMap: NodeMap;\n\t\tedgeMap: EdgeMap;\n\t\tcanvasBaseDir: string;\n\t\tnodeBounds: NodeBounds;\n\t\toffsetX: number;\n\t\toffsetY: number;\n\t\tscale: number;\n\t\tcontainer: HTMLDivElement;\n\t} = {\n\t\tcanvasData: {\n\t\t\tnodes: [],\n\t\t\tedges: [],\n\t\t},\n\t\tnodeMap: {},\n\t\tedgeMap: {},\n\t\tcanvasBaseDir: './',\n\t\tnodeBounds: {\n\t\t\tmaxX: 0,\n\t\t\tmaxY: 0,\n\t\t\tminX: 0,\n\t\t\tminY: 0,\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\tcenterX: 0,\n\t\t\tcenterY: 0,\n\t\t},\n\t\toffsetX: 0,\n\t\toffsetY: 0,\n\t\tscale: 1,\n\t\tcontainer: document.createElement('div'),\n\t};\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tconst viewerContainer = this.options.container;\n\t\twhile (viewerContainer.firstElementChild) viewerContainer.firstElementChild.remove();\n\t\tviewerContainer.innerHTML = '';\n\n\t\tconst realContainer = this.options.shadowed\n\t\t\t? viewerContainer.attachShadow({ mode: 'open' })\n\t\t\t: viewerContainer;\n\n\t\tutilities.applyStyles(realContainer, style + this.options.extraCSS);\n\n\t\tthis.data.container.classList.add('JSON-Canvas-Viewer');\n\t\trealContainer.appendChild(this.data.container);\n\n\t\tthis.augment({\n\t\t\tresetView: this.resetView,\n\t\t\ttoggleFullscreen: this.toggleFullscreen,\n\t\t\tonToggleFullscreen: this.onToggleFullscreen,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onRestart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate start = () => {\n\t\tconst canvasData = Object.assign(\n\t\t\t{\n\t\t\t\tnodes: [],\n\t\t\t\tedges: [],\n\t\t\t},\n\t\t\tthis.options.canvas,\n\t\t);\n\n\t\tObject.assign(this.data, {\n\t\t\tcanvasData: canvasData,\n\t\t\tnodeMap: {},\n\t\t\tedgeMap: {},\n\t\t\tcanvasBaseDir: this.processBaseDir(this.options.attachmentDir),\n\t\t\tnodeBounds: this.calculateNodeBounds(canvasData),\n\t\t\toffsetX: 0,\n\t\t\toffsetY: 0,\n\t\t\tscale: 1,\n\t\t});\n\n\t\tthis.data.canvasData.nodes.forEach((node) => {\n\t\t\tconst item: NodeItem = {\n\t\t\t\tref: node,\n\t\t\t\tbox: this.getNodeBox(node),\n\t\t\t};\n\t\t\tthis.data.nodeMap[node.id] = item;\n\n\t\t\t// re-process attachments\n\t\t\tif (node.type === 'file') {\n\t\t\t\tconst path = node.file.split('/');\n\t\t\t\tconst fileName = path.pop() ?? '';\n\t\t\t\titem.fileName = fileName;\n\t\t\t\tif (!node.file.startsWith('http://') && !node.file.startsWith('https://')) {\n\t\t\t\t\tconst userDefinedAttachment = this.options.attachments?.[fileName];\n\t\t\t\t\tif (userDefinedAttachment) node.file = userDefinedAttachment;\n\t\t\t\t\telse if (!this.options.noAttachmentRelocation)\n\t\t\t\t\t\tnode.file = this.data.canvasBaseDir + fileName;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.data.canvasData.edges.forEach((edge) => {\n\t\t\tthis.data.edgeMap[edge.id] = {\n\t\t\t\tref: edge,\n\t\t\t\tbox: this.getEdgeBox(edge),\n\t\t\t};\n\t\t});\n\t\tthis.resetView();\n\t};\n\n\tprivate processBaseDir = (baseDir: string | undefined) => {\n\t\tif (!baseDir) return './';\n\t\tconst lastChar = baseDir?.slice(-1);\n\t\tif (lastChar === '/') return baseDir;\n\t\treturn `${baseDir}/`;\n\t};\n\n\tprivate getNodeBox = (node: JSONCanvasNode) => {\n\t\treturn {\n\t\t\tleft: node.x,\n\t\t\ttop:\n\t\t\t\tnode.type === 'file' || node.type === 'group' ? node.y - NODE_LABEL_MARGIN : node.y,\n\t\t\tright: node.width + node.x,\n\t\t\tbottom: node.y + node.height,\n\t\t};\n\t};\n\n\tprivate getEdgeBox = (edge: JSONCanvasEdge) => {\n\t\tconst nodes = this.data.nodeMap;\n\t\tconst from = nodes[edge.fromNode].ref;\n\t\tconst to = nodes[edge.toNode].ref;\n\t\tconst fromAnchor = utilities.getAnchorCoord(from, edge.fromSide);\n\t\tconst toAnchor = utilities.getAnchorCoord(to, edge.toSide);\n\t\tconst strictBox = {\n\t\t\tleft: Math.min(fromAnchor.x, toAnchor.x),\n\t\t\ttop: Math.min(fromAnchor.y, toAnchor.y),\n\t\t\tright: Math.max(fromAnchor.x, toAnchor.x),\n\t\t\tbottom: Math.max(fromAnchor.y, toAnchor.y),\n\t\t};\n\t\t// edge size heuristics\n\t\tconst width = strictBox.right - strictBox.left;\n\t\tconst height = strictBox.bottom - strictBox.top;\n\t\tconst _min = Math.min(width, height);\n\t\tconst min = _min === 0 ? 1 : _min;\n\t\tconst max = Math.max(width, height);\n\t\tconst edgeFactor = Math.log2(max / min);\n\t\tconst margin = edgeFactor * EDGE_BOX_HEURISTICS_BASE_MARGIN;\n\t\treturn {\n\t\t\tleft: strictBox.left - margin,\n\t\t\ttop: strictBox.top - margin,\n\t\t\tright: strictBox.right + margin,\n\t\t\tbottom: strictBox.bottom + margin,\n\t\t};\n\t};\n\n\tprivate calculateNodeBounds(canvasData: Required<JSONCanvas>) {\n\t\tlet minX = Infinity,\n\t\t\tminY = Infinity,\n\t\t\tmaxX = -Infinity,\n\t\t\tmaxY = -Infinity;\n\t\tcanvasData.nodes.forEach((node) => {\n\t\t\tminX = Math.min(minX, node.x);\n\t\t\tminY = Math.min(minY, node.y);\n\t\t\tmaxX = Math.max(maxX, node.x + node.width);\n\t\t\tmaxY = Math.max(maxY, node.y + node.height);\n\t\t});\n\t\tconst width = maxX - minX;\n\t\tconst height = maxY - minY;\n\t\tconst centerX = minX + width / 2;\n\t\tconst centerY = minY + height / 2;\n\t\treturn { minX, minY, maxX, maxY, width, height, centerX, centerY };\n\t}\n\ttoggleFullscreen = async (option?: 'enter' | 'exit') => {\n\t\tif (!document.fullscreenElement && (!option || option === 'enter')) {\n\t\t\tawait this.data.container.requestFullscreen();\n\t\t\tthis.onToggleFullscreen('enter');\n\t\t} else if (document.fullscreenElement && (!option || option === 'exit')) {\n\t\t\tawait document.exitFullscreen();\n\t\t\tthis.onToggleFullscreen('exit');\n\t\t}\n\t};\n\tresetView = () => {\n\t\tconst bounds = this.data.nodeBounds;\n\t\tconst container = this.data.container;\n\t\tif (!bounds || !container) return;\n\t\tconst contentWidth = bounds.width + INITIAL_VIEWPORT_PADDING * 2;\n\t\tconst contentHeight = bounds.height + INITIAL_VIEWPORT_PADDING * 2;\n\t\t// Use logical dimensions for scaling calculations\n\t\tconst viewWidth = container.clientWidth;\n\t\tconst viewHeight = container.clientHeight;\n\t\tconst scaleX = viewWidth / contentWidth;\n\t\tconst scaleY = viewHeight / contentHeight;\n\t\tconst newScale = Math.round(Math.min(scaleX, scaleY) * 1000) / 1000;\n\t\tconst contentCenterX = bounds.centerX;\n\t\tconst contentCenterY = bounds.centerY;\n\t\tconst initialView = {\n\t\t\tscale: newScale,\n\t\t\toffsetX: viewWidth / 2 - contentCenterX * newScale,\n\t\t\toffsetY: viewHeight / 2 - contentCenterY * newScale,\n\t\t};\n\t\tthis.data.offsetX = initialView.offsetX;\n\t\tthis.data.offsetY = initialView.offsetY;\n\t\tthis.data.scale = initialView.scale;\n\t};\n\n\tmiddleViewer = () => {\n\t\tconst container = this.data.container;\n\t\treturn {\n\t\t\tx: container.clientWidth / 2,\n\t\t\ty: container.clientHeight / 2,\n\t\t\twidth: container.clientWidth,\n\t\t\theight: container.clientHeight,\n\t\t};\n\t};\n\n\tprivate dispose = () => {\n\t\tthis.data.container.remove();\n\t};\n}\n"],"names":["DataManager","BaseModule","onToggleFullscreen","utilities","makeHook","data","canvasData","nodes","edges","nodeMap","edgeMap","canvasBaseDir","nodeBounds","maxX","maxY","minX","minY","width","height","centerX","centerY","offsetX","offsetY","scale","container","document","createElement","constructor","args","super","viewerContainer","this","options","firstElementChild","remove","innerHTML","realContainer","shadowed","attachShadow","mode","applyStyles","style","extraCSS","classList","add","appendChild","augment","resetView","toggleFullscreen","onStart","start","onRestart","onDispose","dispose","Object","assign","canvas","processBaseDir","attachmentDir","calculateNodeBounds","forEach","node","item","ref","box","getNodeBox","id","type","fileName","file","split","pop","startsWith","userDefinedAttachment","attachments","noAttachmentRelocation","edge","getEdgeBox","baseDir","lastChar","slice","left","x","top","y","right","bottom","from","fromNode","to","toNode","fromAnchor","getAnchorCoord","fromSide","toAnchor","toSide","strictBox","Math","min","max","_min","margin","log2","Infinity","async","option","fullscreenElement","exitFullscreen","requestFullscreen","bounds","contentWidth","INITIAL_VIEWPORT_PADDING","contentHeight","viewWidth","clientWidth","viewHeight","clientHeight","scaleX","scaleY","newScale","round","initialView","middleViewer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataManager.js","names":["style"],"sources":["../../src/kernel/DataManager.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { BaseArgs } from '$/BaseModule';\nimport type { Box, NodeBounds } from '$/types';\nimport type { Hook } from '$/utilities';\nimport type { JSONCanvas, JSONCanvasEdge, JSONCanvasNode } from '@repo/shared';\nimport { BaseModule } from '$/BaseModule';\nimport style from '$/styles.scss?inline';\nimport { applyStyles, getAnchorCoord, makeHook } from '$/utilities';\n\nconst INITIAL_VIEWPORT_PADDING = 100;\nconst NODE_LABEL_MARGIN = 40;\nconst EDGE_BOX_HEURISTICS_BASE_MARGIN = 10;\n\ntype Options = {\n\tshadowed?: boolean;\n\tcanvas?: JSONCanvas;\n\tattachmentDir?: string;\n\textraCSS?: string;\n\tattachments?: Record<string, string>;\n\tnoAttachmentRelocation?: boolean;\n} & BaseOptions;\n\ntype Augmentation = {\n\tresetView: DataManager['resetView'];\n\ttoggleFullscreen: DataManager['toggleFullscreen'];\n\tonToggleFullscreen: DataManager['onToggleFullscreen'];\n};\n\nexport type NodeItem = {\n\tref: JSONCanvasNode;\n\tbox: Box;\n\tfileName?: string;\n\tonBeforeUnmount?: Hook;\n\tonActive?: Hook;\n\tonLoseActive?: Hook;\n};\n\nexport type EdgeItem = {\n\tref: JSONCanvasEdge;\n\tbox: Box;\n\tcontrolPoints?: Array<number>;\n};\n\ntype NodeMap = Record<string, NodeItem>;\ntype EdgeMap = Record<string, EdgeItem>;\n\nexport default class DataManager extends BaseModule<Options, Augmentation> {\n\tonToggleFullscreen = makeHook<['enter' | 'exit']>();\n\n\tdata: {\n\t\tcanvasData: Required<JSONCanvas>;\n\t\tnodeMap: NodeMap;\n\t\tedgeMap: EdgeMap;\n\t\tcanvasBaseDir: string;\n\t\tnodeBounds: NodeBounds;\n\t\toffsetX: number;\n\t\toffsetY: number;\n\t\tscale: number;\n\t\tcontainer: HTMLDivElement;\n\t} = {\n\t\tcanvasBaseDir: './',\n\t\tcanvasData: {\n\t\t\tedges: [],\n\t\t\tnodes: [],\n\t\t},\n\t\tcontainer: document.createElement('div'),\n\t\tedgeMap: {},\n\t\tnodeBounds: {\n\t\t\tcenterX: 0,\n\t\t\tcenterY: 0,\n\t\t\theight: 0,\n\t\t\tmaxX: 0,\n\t\t\tmaxY: 0,\n\t\t\tminX: 0,\n\t\t\tminY: 0,\n\t\t\twidth: 0,\n\t\t},\n\t\tnodeMap: {},\n\t\toffsetX: 0,\n\t\toffsetY: 0,\n\t\tscale: 1,\n\t};\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tconst viewerContainer = this.options.container;\n\t\twhile (viewerContainer.firstElementChild) viewerContainer.firstElementChild.remove();\n\t\tviewerContainer.innerHTML = '';\n\n\t\tconst realContainer = this.options.shadowed\n\t\t\t? viewerContainer.attachShadow({ mode: 'open' })\n\t\t\t: viewerContainer;\n\n\t\tapplyStyles(realContainer, style + this.options.extraCSS);\n\n\t\tthis.data.container.classList.add('JSON-Canvas-Viewer');\n\t\trealContainer.appendChild(this.data.container);\n\n\t\tthis.augment({\n\t\t\tonToggleFullscreen: this.onToggleFullscreen,\n\t\t\tresetView: this.resetView,\n\t\t\ttoggleFullscreen: this.toggleFullscreen,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onRestart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate readonly start = () => {\n\t\tconst canvasData = {\n\t\t\tedges: [],\n\t\t\tnodes: [],\n\t\t\t...this.options.canvas,\n\t\t};\n\n\t\tObject.assign(this.data, {\n\t\t\tcanvasBaseDir: this.processBaseDir(this.options.attachmentDir),\n\t\t\tcanvasData,\n\t\t\tedgeMap: {},\n\t\t\tnodeBounds: this.calculateNodeBounds(canvasData),\n\t\t\tnodeMap: {},\n\t\t\toffsetX: 0,\n\t\t\toffsetY: 0,\n\t\t\tscale: 1,\n\t\t});\n\n\t\tthis.data.canvasData.nodes.forEach((node) => {\n\t\t\tconst item: NodeItem = {\n\t\t\t\tbox: this.getNodeBox(node),\n\t\t\t\tref: node,\n\t\t\t};\n\t\t\tthis.data.nodeMap[node.id] = item;\n\n\t\t\t// Re-process attachments\n\t\t\tif (node.type === 'file') {\n\t\t\t\tconst path = node.file.split('/');\n\t\t\t\tconst fileName = path.pop() ?? '';\n\t\t\t\titem.fileName = fileName;\n\t\t\t\tif (!node.file.startsWith('http://') && !node.file.startsWith('https://')) {\n\t\t\t\t\tconst userDefinedAttachment = this.options.attachments?.[fileName];\n\t\t\t\t\tif (userDefinedAttachment) node.file = userDefinedAttachment;\n\t\t\t\t\telse if (!this.options.noAttachmentRelocation)\n\t\t\t\t\t\tnode.file = this.data.canvasBaseDir + fileName;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.data.canvasData.edges.forEach((edge) => {\n\t\t\tthis.data.edgeMap[edge.id] = {\n\t\t\t\tbox: this.getEdgeBox(edge),\n\t\t\t\tref: edge,\n\t\t\t};\n\t\t});\n\t\tthis.resetView();\n\t};\n\n\tprivate readonly processBaseDir = (baseDir: string | undefined) => {\n\t\tif (!baseDir) return './';\n\t\tconst lastChar = baseDir?.slice(-1);\n\t\tif (lastChar === '/') return baseDir;\n\t\treturn `${baseDir}/`;\n\t};\n\n\tprivate readonly getNodeBox = (node: JSONCanvasNode) => ({\n\t\tbottom: node.y + node.height,\n\t\tleft: node.x,\n\t\tright: node.width + node.x,\n\t\ttop: node.type === 'file' || node.type === 'group' ? node.y - NODE_LABEL_MARGIN : node.y,\n\t});\n\n\tprivate readonly getEdgeBox = (edge: JSONCanvasEdge) => {\n\t\tconst nodes = this.data.nodeMap;\n\t\tconst from = nodes[edge.fromNode].ref;\n\t\tconst to = nodes[edge.toNode].ref;\n\t\tconst fromAnchor = getAnchorCoord(from, edge.fromSide);\n\t\tconst toAnchor = getAnchorCoord(to, edge.toSide);\n\t\tconst strictBox = {\n\t\t\tbottom: Math.max(fromAnchor.y, toAnchor.y),\n\t\t\tleft: Math.min(fromAnchor.x, toAnchor.x),\n\t\t\tright: Math.max(fromAnchor.x, toAnchor.x),\n\t\t\ttop: Math.min(fromAnchor.y, toAnchor.y),\n\t\t};\n\t\t// Edge size heuristics\n\t\tconst width = strictBox.right - strictBox.left;\n\t\tconst height = strictBox.bottom - strictBox.top;\n\t\tconst _min = Math.min(width, height);\n\t\tconst min = _min === 0 ? 1 : _min;\n\t\tconst max = Math.max(width, height);\n\t\tconst edgeFactor = Math.log2(max / min);\n\t\tconst margin = edgeFactor * EDGE_BOX_HEURISTICS_BASE_MARGIN;\n\t\treturn {\n\t\t\tbottom: strictBox.bottom + margin,\n\t\t\tleft: strictBox.left - margin,\n\t\t\tright: strictBox.right + margin,\n\t\t\ttop: strictBox.top - margin,\n\t\t};\n\t};\n\n\tprivate calculateNodeBounds(canvasData: Required<JSONCanvas>) {\n\t\tlet minX = Infinity,\n\t\t\tminY = Infinity,\n\t\t\tmaxX = -Infinity,\n\t\t\tmaxY = -Infinity;\n\t\tcanvasData.nodes.forEach((node) => {\n\t\t\tminX = Math.min(minX, node.x);\n\t\t\tminY = Math.min(minY, node.y);\n\t\t\tmaxX = Math.max(maxX, node.x + node.width);\n\t\t\tmaxY = Math.max(maxY, node.y + node.height);\n\t\t});\n\t\tconst width = maxX - minX;\n\t\tconst height = maxY - minY;\n\t\tconst centerX = minX + width / 2;\n\t\tconst centerY = minY + height / 2;\n\t\treturn { centerX, centerY, height, maxX, maxY, minX, minY, width };\n\t}\n\ttoggleFullscreen = async (option?: 'enter' | 'exit') => {\n\t\tif (!document.fullscreenElement && (!option || option === 'enter')) {\n\t\t\tawait this.data.container.requestFullscreen();\n\t\t\tthis.onToggleFullscreen('enter');\n\t\t} else if (document.fullscreenElement && (!option || option === 'exit')) {\n\t\t\tawait document.exitFullscreen();\n\t\t\tthis.onToggleFullscreen('exit');\n\t\t}\n\t};\n\tresetView = () => {\n\t\tconst bounds = this.data.nodeBounds;\n\t\tconst container = this.data.container;\n\t\tif (!bounds || !container) return;\n\t\tconst contentWidth = bounds.width + INITIAL_VIEWPORT_PADDING * 2;\n\t\tconst contentHeight = bounds.height + INITIAL_VIEWPORT_PADDING * 2;\n\t\t// Use logical dimensions for scaling calculations\n\t\tconst viewWidth = container.clientWidth;\n\t\tconst viewHeight = container.clientHeight;\n\t\tconst scaleX = viewWidth / contentWidth;\n\t\tconst scaleY = viewHeight / contentHeight;\n\t\tconst newScale = Math.round(Math.min(scaleX, scaleY) * 1000) / 1000;\n\t\tconst contentCenterX = bounds.centerX;\n\t\tconst contentCenterY = bounds.centerY;\n\t\tconst initialView = {\n\t\t\toffsetX: viewWidth / 2 - contentCenterX * newScale,\n\t\t\toffsetY: viewHeight / 2 - contentCenterY * newScale,\n\t\t\tscale: newScale,\n\t\t};\n\t\tthis.data.offsetX = initialView.offsetX;\n\t\tthis.data.offsetY = initialView.offsetY;\n\t\tthis.data.scale = initialView.scale;\n\t};\n\n\tmiddleViewer = () => {\n\t\tconst container = this.data.container;\n\t\treturn {\n\t\t\theight: container.clientHeight,\n\t\t\twidth: container.clientWidth,\n\t\t\tx: container.clientWidth / 2,\n\t\t\ty: container.clientHeight / 2,\n\t\t};\n\t};\n\n\tprivate readonly dispose = () => {\n\t\tthis.data.container.remove();\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Coordinates } from "./types.js";
|
|
2
|
+
import { Hook } from "./utilities.js";
|
|
3
|
+
import { BaseArgs, BaseModule } from "./BaseModule.js";
|
|
4
|
+
import { BaseOptions } from "./index.js";
|
|
5
|
+
import { Click, Drag, Lubricator, MultitouchPanZoom, Options, PointeractInterface, PreventDefault, WheelPanZoom } from "pointeract";
|
|
6
|
+
|
|
7
|
+
//#region src/kernel/InteractionHandler.d.ts
|
|
8
|
+
type LoadedModules = [Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom, Lubricator];
|
|
9
|
+
type Options$1 = {
|
|
10
|
+
pointeract?: Options<LoadedModules>;
|
|
11
|
+
} & BaseOptions;
|
|
12
|
+
type Augmentation = {
|
|
13
|
+
pan: InteractionHandler['pan'];
|
|
14
|
+
panToCoords: InteractionHandler['panToCoords'];
|
|
15
|
+
zoom: InteractionHandler['zoom'];
|
|
16
|
+
zoomToScale: InteractionHandler['zoomToScale'];
|
|
17
|
+
};
|
|
18
|
+
declare class InteractionHandler extends BaseModule<Options$1, Augmentation> {
|
|
19
|
+
pointeract: PointeractInterface<LoadedModules>;
|
|
20
|
+
private readonly DM;
|
|
21
|
+
onClick: Hook<[string | undefined], false>;
|
|
22
|
+
constructor(...args: BaseArgs);
|
|
23
|
+
private readonly start;
|
|
24
|
+
private readonly startInteract;
|
|
25
|
+
private readonly stopInteract;
|
|
26
|
+
private readonly onPan;
|
|
27
|
+
private readonly onZoom;
|
|
28
|
+
trueZoom: (_factor: number, origin: Coordinates) => void;
|
|
29
|
+
truePan: ({
|
|
30
|
+
x,
|
|
31
|
+
y
|
|
32
|
+
}: Coordinates) => void;
|
|
33
|
+
zoom: (_factor: number, origin: Coordinates) => void;
|
|
34
|
+
pan: ({
|
|
35
|
+
x,
|
|
36
|
+
y
|
|
37
|
+
}: Coordinates) => void;
|
|
38
|
+
zoomToScale: (newScale: number, origin: Coordinates) => void;
|
|
39
|
+
panToCoords: ({
|
|
40
|
+
x,
|
|
41
|
+
y
|
|
42
|
+
}: Coordinates) => void;
|
|
43
|
+
private readonly C2C;
|
|
44
|
+
private readonly onTrueClick;
|
|
45
|
+
private readonly isUIControl;
|
|
46
|
+
private readonly findNodeId;
|
|
47
|
+
private readonly dispose;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { InteractionHandler };
|
|
51
|
+
//# sourceMappingURL=InteractionHandler.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseModule as
|
|
2
|
-
//# sourceMappingURL=InteractionHandler.js.map
|
|
1
|
+
import{BaseModule as e}from"./BaseModule.js";import{makeHook as t}from"./utilities.js";import n from"./DataManager.js";import r from"./OverlayManager.js";import{Click as i,Drag as a,Lubricator as o,MultitouchPanZoom as s,Pointeract as c,PreventDefault as l,WheelPanZoom as u,lubricatorDragPreset as d,lubricatorPanPreset as f,lubricatorZoomPreset as p}from"pointeract";var m=class extends e{pointeract;DM;onClick=t();constructor(...e){super(...e),this.DM=this.container.get(n);let t=Object.assign(this.options.pointeract??{},{coordinateOutput:`relative`,element:this.DM.data.container,lubricator:{drag:d,pan:f,zoom:p}});this.pointeract=new c(t,[i,a,u,l,s,o]);let m=this.container.get(r);m.onInteractionStart.subscribe(this.stopInteract),m.onInteractionEnd.subscribe(this.startInteract),this.augment({pan:this.pan,panToCoords:this.panToCoords,zoom:this.zoom,zoomToScale:this.zoomToScale}),this.onStart(this.start),this.onDispose(this.dispose)}start=()=>{this.pointeract.on(`pan`,this.onPan).on(`drag`,this.onPan).on(`zoom`,this.onZoom).on(`trueClick`,this.onTrueClick).start()};startInteract=()=>{this.pointeract.start()};stopInteract=()=>{this.pointeract.stop()};onPan=e=>{this.truePan({x:e.deltaX,y:e.deltaY})};onZoom=e=>{this.trueZoom(e.factor,e)};trueZoom=(e,t)=>{let n=Math.max(Math.min(this.DM.data.scale*e,20),.05);if(n===this.DM.data.scale)return;let r=n/this.DM.data.scale,i=this.C2C(t);this.DM.data.offsetX=t.x-i.x*r,this.DM.data.offsetY=t.y-i.y*r,this.DM.data.scale=n};truePan=({x:e,y:t})=>{this.DM.data.offsetX+=e,this.DM.data.offsetY+=t};zoom=(e,t)=>{this.pointeract.dispatch(`zoom`,{factor:e,...t})};pan=({x:e,y:t})=>{this.pointeract.dispatch(`pan`,{deltaX:e,deltaY:t})};zoomToScale=(e,t)=>{let n=e/this.DM.data.scale;this.pointeract.dispatch(`zoom`,{factor:n,...t})};panToCoords=({x:e,y:t})=>{this.pointeract.dispatch(`pan`,{deltaX:e-this.DM.data.offsetX,deltaY:t-this.DM.data.offsetY})};C2C=({x:e,y:t})=>({x:e-this.DM.data.offsetX,y:t-this.DM.data.offsetY});onTrueClick=e=>{let t=e.target;if(this.isUIControl(t))return;let n=this.findNodeId(t);this.onClick(n)};isUIControl=e=>e?e.closest(`.controls`)||e.closest(`button`)||e.closest(`input`):!1;findNodeId=e=>{if(!e)return;let t=e;for(;(!t.id||t.id===``)&&t.parentElement;)t=t.parentElement;if(!(t.id===`overlays`||!t.id||t.id===``))return t.id};dispose=()=>this.pointeract.dispose()};export{m as default};
|
|
2
|
+
//# sourceMappingURL=InteractionHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionHandler.js","sources":["../../src/kernel/InteractionHandler.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { Coordinates } from '$/types';\nimport {
|
|
1
|
+
{"version":3,"file":"InteractionHandler.js","names":[],"sources":["../../src/kernel/InteractionHandler.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { BaseArgs } from '$/BaseModule';\nimport type { Coordinates } from '$/types';\nimport type { Options as PointeractOptions, Events, PointeractInterface } from 'pointeract';\nimport { BaseModule } from '$/BaseModule';\nimport DataManager from '$/DataManager';\nimport OverlayManager from '$/OverlayManager';\nimport { makeHook } from '$/utilities';\nimport {\n\tClick,\n\tDrag,\n\tMultitouchPanZoom,\n\tPointeract,\n\tPreventDefault,\n\tWheelPanZoom,\n\tLubricator,\n\tlubricatorPanPreset as pan,\n\tlubricatorZoomPreset as zoom,\n\tlubricatorDragPreset as drag,\n} from 'pointeract';\n\ntype LoadedModules = [Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom, Lubricator];\n\ntype LoadedEvents = Events<LoadedModules>;\n\ntype Options = {\n\tpointeract?: PointeractOptions<LoadedModules>;\n} & BaseOptions;\n\ntype Augmentation = {\n\tpan: InteractionHandler['pan'];\n\tpanToCoords: InteractionHandler['panToCoords'];\n\tzoom: InteractionHandler['zoom'];\n\tzoomToScale: InteractionHandler['zoomToScale'];\n};\n\nexport default class InteractionHandler extends BaseModule<Options, Augmentation> {\n\tpointeract: PointeractInterface<LoadedModules>;\n\tprivate readonly DM: DataManager;\n\tonClick = makeHook<[string | undefined]>();\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tconst options = Object.assign(this.options.pointeract ?? {}, {\n\t\t\tcoordinateOutput: 'relative',\n\t\t\telement: this.DM.data.container,\n\t\t\tlubricator: { drag, pan, zoom },\n\t\t} satisfies PointeractOptions<LoadedModules>);\n\t\tthis.pointeract = new Pointeract(options, [\n\t\t\tClick,\n\t\t\tDrag,\n\t\t\tWheelPanZoom,\n\t\t\tPreventDefault,\n\t\t\tMultitouchPanZoom,\n\t\t\tLubricator,\n\t\t]);\n\t\tconst OM = this.container.get(OverlayManager);\n\t\tOM.onInteractionStart.subscribe(this.stopInteract);\n\t\tOM.onInteractionEnd.subscribe(this.startInteract);\n\n\t\tthis.augment({\n\t\t\tpan: this.pan,\n\t\t\tpanToCoords: this.panToCoords,\n\t\t\tzoom: this.zoom,\n\t\t\tzoomToScale: this.zoomToScale,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate readonly start = () => {\n\t\tthis.pointeract\n\t\t\t.on('pan', this.onPan)\n\t\t\t.on('drag', this.onPan)\n\t\t\t.on('zoom', this.onZoom)\n\t\t\t.on('trueClick', this.onTrueClick)\n\t\t\t.start();\n\t};\n\n\tprivate readonly startInteract = () => {\n\t\tthis.pointeract.start();\n\t};\n\tprivate readonly stopInteract = () => {\n\t\tthis.pointeract.stop();\n\t};\n\n\tprivate readonly onPan = (event: LoadedEvents['pan']) => {\n\t\tthis.truePan({\n\t\t\tx: event.deltaX,\n\t\t\ty: event.deltaY,\n\t\t});\n\t};\n\tprivate readonly onZoom = (event: LoadedEvents['zoom']) => {\n\t\tthis.trueZoom(event.factor, event);\n\t};\n\n\ttrueZoom = (_factor: number, origin: Coordinates) => {\n\t\tconst newScale = Math.max(Math.min(this.DM.data.scale * _factor, 20), 0.05);\n\t\tconst scale = this.DM.data.scale;\n\t\tif (newScale === scale) return;\n\t\tconst factor = newScale / this.DM.data.scale;\n\t\tconst canvasCoords = this.C2C(origin);\n\t\tthis.DM.data.offsetX = origin.x - canvasCoords.x * factor;\n\t\tthis.DM.data.offsetY = origin.y - canvasCoords.y * factor;\n\t\tthis.DM.data.scale = newScale;\n\t};\n\ttruePan = ({ x, y }: Coordinates) => {\n\t\tthis.DM.data.offsetX += x;\n\t\tthis.DM.data.offsetY += y;\n\t};\n\n\tzoom = (_factor: number, origin: Coordinates) => {\n\t\tthis.pointeract.dispatch('zoom', { factor: _factor, ...origin });\n\t};\n\tpan = ({ x, y }: Coordinates) => {\n\t\tthis.pointeract.dispatch('pan', { deltaX: x, deltaY: y });\n\t};\n\tzoomToScale = (newScale: number, origin: Coordinates) => {\n\t\tconst factor = newScale / this.DM.data.scale;\n\t\tthis.pointeract.dispatch('zoom', { factor, ...origin });\n\t};\n\tpanToCoords = ({ x, y }: Coordinates) => {\n\t\tthis.pointeract.dispatch('pan', {\n\t\t\tdeltaX: x - this.DM.data.offsetX,\n\t\t\tdeltaY: y - this.DM.data.offsetY,\n\t\t});\n\t};\n\n\t// Container Coords to Canvas Coords relative to the top-left corner of the scaled canvas\n\tprivate readonly C2C = ({ x: containerX, y: containerY }: Coordinates) => ({\n\t\tx: containerX - this.DM.data.offsetX,\n\t\ty: containerY - this.DM.data.offsetY,\n\t});\n\n\tprivate readonly onTrueClick = (e: LoadedEvents['trueClick']) => {\n\t\tconst element = e.target as HTMLElement | undefined;\n\t\tif (this.isUIControl(element)) return;\n\t\tconst node = this.findNodeId(element);\n\t\tthis.onClick(node);\n\t};\n\n\tprivate readonly isUIControl = (target?: HTMLElement) => {\n\t\tif (!target) return false;\n\t\treturn target.closest('.controls') || target.closest('button') || target.closest('input');\n\t};\n\n\tprivate readonly findNodeId = (element?: HTMLElement) => {\n\t\tif (!element) return;\n\t\tlet ele = element;\n\t\twhile (!ele.id || ele.id === '') {\n\t\t\tif (!ele.parentElement) break;\n\t\t\tele = ele.parentElement;\n\t\t}\n\t\tif (ele.id === 'overlays' || !ele.id || ele.id === '') return;\n\t\treturn ele.id;\n\t};\n\n\tprivate readonly dispose = () => this.pointeract.dispose();\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { JSONCanvasFileNode, JSONCanvasLinkNode, JSONCanvasNode, JSONCanvasTextNode, Parser } from "../shared/index.js";
|
|
2
|
+
import { Hook } from "./utilities.js";
|
|
3
|
+
import { BaseArgs, BaseModule } from "./BaseModule.js";
|
|
4
|
+
import { BaseOptions } from "./index.js";
|
|
5
|
+
|
|
6
|
+
//#region src/kernel/OverlayManager.d.ts
|
|
7
|
+
type Options = {
|
|
8
|
+
parser?: Parser;
|
|
9
|
+
nodeComponents?: Partial<ComponentDict>;
|
|
10
|
+
} & BaseOptions;
|
|
11
|
+
type Augmentation = {
|
|
12
|
+
onNodeActive: OverlayManager['onNodeActive'];
|
|
13
|
+
onNodeLosesActive: OverlayManager['onNodeLosesActive'];
|
|
14
|
+
};
|
|
15
|
+
type NodeComponentHook<N extends JSONCanvasNode> = (options: {
|
|
16
|
+
container: HTMLDivElement;
|
|
17
|
+
content: string;
|
|
18
|
+
node: N;
|
|
19
|
+
onBeforeUnmount: Hook;
|
|
20
|
+
onActive: Hook;
|
|
21
|
+
onLoseActive: Hook;
|
|
22
|
+
}) => void | Promise<void>;
|
|
23
|
+
type ComponentNodeMap = {
|
|
24
|
+
text: JSONCanvasTextNode;
|
|
25
|
+
markdown: JSONCanvasFileNode;
|
|
26
|
+
image: JSONCanvasFileNode;
|
|
27
|
+
audio: JSONCanvasFileNode;
|
|
28
|
+
video: JSONCanvasFileNode;
|
|
29
|
+
link: JSONCanvasLinkNode;
|
|
30
|
+
};
|
|
31
|
+
type ComponentDict = { [K in keyof ComponentNodeMap]: NodeComponentHook<ComponentNodeMap[K]> };
|
|
32
|
+
declare class OverlayManager extends BaseModule<Options, Augmentation> {
|
|
33
|
+
private _overlaysLayer;
|
|
34
|
+
private overlays;
|
|
35
|
+
private selectedId;
|
|
36
|
+
private aborted;
|
|
37
|
+
private eventListeners;
|
|
38
|
+
private readonly DM;
|
|
39
|
+
private readonly SM;
|
|
40
|
+
private readonly parse;
|
|
41
|
+
private readonly componentDict;
|
|
42
|
+
private get overlaysLayer();
|
|
43
|
+
onInteractionStart: Hook<[], false>;
|
|
44
|
+
onInteractionEnd: Hook<[], false>;
|
|
45
|
+
onNodeActive: Hook<[JSONCanvasNode], false>;
|
|
46
|
+
onNodeLosesActive: Hook<[JSONCanvasNode], false>;
|
|
47
|
+
constructor(...args: BaseArgs);
|
|
48
|
+
private readonly start;
|
|
49
|
+
private readonly restart;
|
|
50
|
+
private readonly renderOverlays;
|
|
51
|
+
private readonly themeChanged;
|
|
52
|
+
private readonly select;
|
|
53
|
+
private readonly updateOverlays;
|
|
54
|
+
private readonly createOverlay;
|
|
55
|
+
private readonly constructOverlay;
|
|
56
|
+
private readonly setOverlayColor;
|
|
57
|
+
private readonly clearOverlays;
|
|
58
|
+
private readonly dispose;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { OverlayManager };
|
|
62
|
+
//# sourceMappingURL=OverlayManager.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseModule as e}from"./BaseModule.js";import t from"./
|
|
2
|
-
//# sourceMappingURL=OverlayManager.js.map
|
|
1
|
+
import{BaseModule as e}from"./BaseModule.js";import{destroyError as t,makeHook as n}from"./utilities.js";import r from"./DataManager.js";import i from"./StyleManager.js";import a from"./Controller.js";import o from"./InteractionHandler.js";const s={audio:/\.(mp3|wav|ogg|opus|aac|m4a|flac)$/i,image:/\.(png|jpg|jpeg|gif|svg|webp|avif|bmp|ico|heic|heif)$/i,markdown:/\.(md|mdx|markdown|txt)$/i,video:/\.(mp4|webm|ogv|mov|m3u8|mpd)$/i},c=[`markdown`,`image`,`audio`,`video`];var l=class extends e{_overlaysLayer=document.createElement(`div`);overlays={};selectedId;aborted=!1;eventListeners={};DM;SM;parse;componentDict={audio:({container:e,content:t})=>{let n=document.createElement(`audio`);n.className=`JCV-audio`,n.src=t,n.controls=!0,e.appendChild(n)},image:({container:e,content:t})=>{let n=document.createElement(`img`);n.className=`JCV-img`,n.src=t,n.loading=`lazy`,e.appendChild(n)},link:({container:e,content:t})=>{let n=document.createElement(`iframe`);n.src=t,n.sandbox=`allow-scripts allow-same-origin`,n.className=`JCV-link-iframe`,n.loading=`lazy`,e.appendChild(n)},markdown:async({container:e,content:t})=>{e.classList.add(`JCV-markdown-content`);let n=document.createElement(`div`);n.textContent=`Loading...`,n.classList.add(`JCV-parsed-content-wrapper`),e.appendChild(n);let r;try{let e=await(await fetch(t)).text(),n=/^---\n([\s\S]*?)\n---\n([\s\S]*)$/.exec(e);r=await this.parse(n?n[2]:e)}catch(e){console.error(`[JSON Canvas Viewer] Failed to load markdown:`,e),r=`Failed to load content.`}n.innerHTML=r},text:({container:e,content:t})=>{e.classList.add(`JCV-markdown-content`);let n=document.createElement(`div`);n.innerHTML=t,n.classList.add(`JCV-parsed-content-wrapper`),e.appendChild(n)},video:({container:e,content:t})=>{let n=document.createElement(`video`);n.className=`JCV-video`,n.src=t,n.controls=!0,e.appendChild(n)}};get overlaysLayer(){if(!this._overlaysLayer)throw t;return this._overlaysLayer}onInteractionStart=n();onInteractionEnd=n();onNodeActive=n();onNodeLosesActive=n();constructor(...e){super(...e),this.parse=this.options.parser??(e=>e),this.DM=this.container.get(r),this.SM=this.container.get(i),this.container.get(a).onRefresh.subscribe(this.updateOverlays),this.SM.onChangeTheme.subscribe(this.themeChanged),this._overlaysLayer=document.createElement(`div`),this._overlaysLayer.className=`JCV-overlays`,this._overlaysLayer.id=`overlays`,this.DM.data.container.appendChild(this.overlaysLayer);let t=this.options.nodeComponents;t&&Object.assign(this.componentDict,t),this.augment({onNodeActive:this.onNodeActive,onNodeLosesActive:this.onNodeLosesActive}),this.onStart(this.start),this.onRestart(this.restart),this.onDispose(this.dispose)}start=()=>{this.container.get(o).onClick.subscribe(this.select),this.renderOverlays()};restart=()=>{this.clearOverlays(),this.renderOverlays()};renderOverlays=()=>{let e=async e=>{switch(e.type){case`text`:this.createOverlay(e,await this.parse(e.text),`text`);break;case`file`:for(let t of c)if(e.file.match(s[t])){this.createOverlay(e,e.file,t);break}break;case`link`:this.createOverlay(e,e.url,`link`);break}};Object.values(this.DM.data.nodeMap).forEach(async t=>{await e(t.ref)})};themeChanged=()=>{Object.values(this.overlays).forEach(e=>{let t=this.DM.data.nodeMap[e.id].ref,n=this.SM.getColor(t.color);this.setOverlayColor(e,n)})};select=e=>{let t=this.selectedId,n=t?this.overlays[t]:void 0,r=e?this.overlays[e]:void 0;if(n&&t){n.classList.remove(`JCV-active`);let e=this.DM.data.nodeMap[t];this.onNodeLosesActive(e.ref),e.onLoseActive?.()}if(r&&e){r.classList.add(`JCV-active`),this.onInteractionStart();let t=this.DM.data.nodeMap[e];this.onNodeActive(t.ref),t.onActive?.()}else this.onInteractionEnd();this.selectedId=e};updateOverlays=()=>{let e=this.DM.data;this.overlaysLayer.style.transform=`translate(${e.offsetX}px, ${e.offsetY}px) scale(${e.scale})`};createOverlay=(...e)=>{if(this.aborted)return;let t=e[0],n=this.overlays[t.id];if(!n){if(n=this.constructOverlay(...e),this.aborted)return;this.overlaysLayer.appendChild(n),this.overlays[t.id]=n,n.style.left=`${t.x}px`,n.style.top=`${t.y}px`,n.style.width=`${t.width}px`,n.style.height=`${t.height}px`}};constructOverlay=(...e)=>{let t=e[0],r=document.createElement(`div`);r.classList.add(`JCV-overlay-container`),r.id=t.id,this.setOverlayColor(r,this.SM.getColor(t.color));let i=document.createElement(`div`);i.classList.add(`JCV-content`),r.appendChild(i);let a=document.createElement(`div`);a.className=`JCV-click-layer`,r.appendChild(a);let o=document.createElement(`div`);o.className=`JCV-overlay-border`,r.appendChild(o);let s=this.DM.data.nodeMap[t.id];s.onActive=n(),s.onLoseActive=n(),s.onBeforeUnmount=n(),this.componentDict[e[2]]({container:i,content:e[1],node:e[0],onActive:s.onActive,onBeforeUnmount:s.onBeforeUnmount,onLoseActive:s.onLoseActive});let c=()=>{t.id===this.selectedId&&this.onInteractionStart()},l=()=>{t.id===this.selectedId&&this.onInteractionEnd()};return r.addEventListener(`pointerenter`,c),r.addEventListener(`pointerleave`,l),r.addEventListener(`touchstart`,c),r.addEventListener(`touchend`,l),this.eventListeners[t.id]=[c,l],r};setOverlayColor=(e,t)=>{Object.entries(t).forEach(([t,n])=>{e.style.setProperty(`--overlay-${t}`,n)})};clearOverlays=()=>{Object.entries(this.overlays).forEach(([e,n])=>{if(this.DM.data.nodeMap[e].onBeforeUnmount?.(),this.eventListeners[e]){let r=this.eventListeners[e][0],i=this.eventListeners[e][1];if(!r||!i)throw t;n.removeEventListener(`pointerenter`,r),n.removeEventListener(`pointerleave`,i),n.removeEventListener(`touchstart`,r),n.removeEventListener(`touchend`,i),this.eventListeners[e][0]=void 0,this.eventListeners[e][1]=void 0}n.remove(),delete this.overlays[e]})};dispose=()=>{this.aborted=!0,this.clearOverlays(),this.overlaysLayer.remove(),this._overlaysLayer=void 0}};export{l as default};
|
|
2
|
+
//# sourceMappingURL=OverlayManager.js.map
|