json-canvas-viewer 3.0.4 → 3.1.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/LICENSE +20 -20
- package/README.md +387 -211
- package/dist/cjs/controls.js +1 -0
- package/dist/cjs/debugPanel.js +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/minimap.js +1 -0
- package/dist/cjs/mistouchPreventer.js +1 -0
- package/dist/es/controls.js +1 -0
- package/dist/es/debugPanel.js +1 -0
- package/dist/es/index.js +1 -0
- package/dist/es/minimap.js +1 -0
- package/dist/es/mistouchPreventer.js +1 -0
- package/dist/types/canvasViewer.d.ts +15 -0
- package/dist/types/dataManager.d.ts +30 -0
- package/dist/{controls.d.ts → types/extensions/controls.d.ts} +6 -7
- package/dist/types/extensions/debugPanel.d.ts +8 -0
- package/dist/types/extensions/minimap.d.ts +21 -0
- package/dist/types/extensions/mistouchPreventer.d.ts +14 -0
- package/dist/types/interactionHandler.d.ts +12 -0
- package/dist/{interactor.d.ts → types/interactor.d.ts} +4 -15
- package/dist/types/overlayManager.d.ts +19 -0
- package/dist/types/renderer.d.ts +24 -0
- package/dist/types/utilities.d.ts +16 -0
- package/dist/utilities-9mYNj6lG.js +1 -0
- package/dist/utilities-C1DbXNeO.cjs +1 -0
- package/package.json +38 -14
- package/dist/canvasViewer.cjs.js +0 -2
- package/dist/canvasViewer.d.ts +0 -70
- package/dist/canvasViewer.esm.js +0 -1
- package/dist/minimap.d.ts +0 -39
- package/dist/mistouchPreventer.d.ts +0 -15
- package/dist/overlayManager.d.ts +0 -20
- package/dist/previewModal.d.ts +0 -20
- package/dist/renderer.d.ts +0 -50
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Hesprs
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Hesprs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,211 +1,387 @@
|
|
|
1
|
-
# JSON Canvas Viewer
|
|
2
|
-
|
|
3
|
-

|
|
4
|
-
[](https://www.npmjs.com/package/json-canvas-viewer)
|
|
5
|
-
[](https://packagephobia.now.sh/result?p=json-canvas-viewer)
|
|
6
|
-
|
|
7
|
-

|
|
8
|
-
|
|
9
|
-
A **TypeScript-based** viewer for **JSON Canvas** files. View and interact with your canvas files directly in the browser, or embed the viewer in front-end projects with ease. It is built without frameworks so it can be easily integrated into any framework.
|
|
10
|
-
|
|
11
|
-
This project is inspired by [sofanati-nour/obsidian-canvas-web-renderer](https://github.com/sofanati-nour/obsidian-canvas-web-renderer), but is far more developed and optimized.
|
|
12
|
-
|
|
13
|
-
For more about **JSON Canvas**, also known as **Obsidian Canvas**, please visit [jsoncanvas.org](https://jsoncanvas.org/).
|
|
14
|
-
|
|
15
|
-
## 📦 Installation
|
|
16
|
-
|
|
17
|
-
We recommend using your favorite package manager to install the package. **Note: This package requires `marked` as dependency, your package manager will automatically install it.**
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
# npm
|
|
21
|
-
npm install json-canvas-viewer
|
|
22
|
-
|
|
23
|
-
# pnpm
|
|
24
|
-
pnpm add json-canvas-viewer
|
|
25
|
-
|
|
26
|
-
# yarn
|
|
27
|
-
yarn add json-canvas-viewer
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- `
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- `
|
|
141
|
-
- `
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
1
|
+
# JSON Canvas Viewer
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://www.npmjs.com/package/json-canvas-viewer)
|
|
5
|
+
[](https://packagephobia.now.sh/result?p=json-canvas-viewer)
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
A **TypeScript-based** viewer for **JSON Canvas** files. View and interact with your canvas files directly in the browser, or embed the viewer in front-end projects with ease. It is built without frameworks so it can be easily integrated into any framework.
|
|
10
|
+
|
|
11
|
+
This project is inspired by [sofanati-nour/obsidian-canvas-web-renderer](https://github.com/sofanati-nour/obsidian-canvas-web-renderer), but is far more developed and optimized.
|
|
12
|
+
|
|
13
|
+
For more about **JSON Canvas**, also known as **Obsidian Canvas**, please visit [jsoncanvas.org](https://jsoncanvas.org/).
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
We recommend using your favorite package manager to install the package. **Note: This package requires `marked` as dependency, your package manager will automatically install it.**
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# npm
|
|
21
|
+
npm install json-canvas-viewer
|
|
22
|
+
|
|
23
|
+
# pnpm
|
|
24
|
+
pnpm add json-canvas-viewer
|
|
25
|
+
|
|
26
|
+
# yarn
|
|
27
|
+
yarn add json-canvas-viewer
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
After installation, you can import the package as a module. It supports both ES module and CommonJS. JS, here we take ESM as an example:
|
|
31
|
+
|
|
32
|
+
```TypeScript
|
|
33
|
+
import canvasViewer from 'json-canvas-viewer';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 🚀 Quick Start
|
|
37
|
+
|
|
38
|
+
Instantiate the viewer:
|
|
39
|
+
|
|
40
|
+
```HTML
|
|
41
|
+
<div id="myCanvasContainer" style="width:800px; height:600px;"></div>
|
|
42
|
+
<script type="module">
|
|
43
|
+
import canvasViewer from 'json-canvas-viewer';
|
|
44
|
+
const viewer = new canvasViewer(document.getElementById('myCanvasContainer'));
|
|
45
|
+
viewer.loadCanvas('example/introduction.canvas');
|
|
46
|
+
// dispose when not needed
|
|
47
|
+
viewer.dispose();
|
|
48
|
+
</script>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
And the viewer should be right in your container, you can instantiate the viewer multiple times to render multiple canvases simultaneously.
|
|
52
|
+
|
|
53
|
+
**Methods**:
|
|
54
|
+
|
|
55
|
+
- `loadCanvas(path)` — Load a canvas file (by path), **please put all the related files (files embedded in the canvas) in the same folder as the canvas file, wherever they originally are**.
|
|
56
|
+
- `dispose()` — Clean up and remove viewer from DOM.
|
|
57
|
+
|
|
58
|
+
## 🐶 Features
|
|
59
|
+
|
|
60
|
+
- View JSON Canvas files (`.canvas`) in a web browser
|
|
61
|
+
- Full markdown syntax support (auto-parsed to HTML)
|
|
62
|
+
- Embed into websites easily
|
|
63
|
+
- Interactive pan and zoom functionality
|
|
64
|
+
- Support for different node types:
|
|
65
|
+
- Text nodes
|
|
66
|
+
- File nodes (including Markdown files)
|
|
67
|
+
- Link nodes (embedded web content)
|
|
68
|
+
- Group nodes with custom colors
|
|
69
|
+
- Edge connections between nodes with labels
|
|
70
|
+
- Minimap for easy navigation (optional extension)
|
|
71
|
+
- Mistouch prevention (optional extension)
|
|
72
|
+
- Responsive design with mobile and touchpad adaptation
|
|
73
|
+
- Out-of-the-box extensibility and tree-shaking
|
|
74
|
+
- TypeScript native support
|
|
75
|
+
- 🔥 **Much more performant** than rendering canvases in Obsidian!
|
|
76
|
+
|
|
77
|
+
## 🧩 Extensibility
|
|
78
|
+
|
|
79
|
+
### Registry
|
|
80
|
+
|
|
81
|
+
The viewer implements the `registry`, which is a powerful orchestrator to streamline the development and extension of the viewer. The registry is the core of the viewer.
|
|
82
|
+
|
|
83
|
+
```TypeScript
|
|
84
|
+
new canvasViewer(container, registry);
|
|
85
|
+
|
|
86
|
+
interface registry {
|
|
87
|
+
options: Record<string, Record<string, any>>;
|
|
88
|
+
extensions: Array<Class<runtimeData, registry>>;
|
|
89
|
+
hooks: Record<string, Array<Function>>;
|
|
90
|
+
api: Record<string, Record<string, Function>>;
|
|
91
|
+
register: (userRegistry: userRegistry) => void;
|
|
92
|
+
}
|
|
93
|
+
interface Class<T> { new (...args: any[]): T }
|
|
94
|
+
interface Function { (...args: any[]): any }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The second parameter of the constructor is an object which is then merged with the default registry. You can also manually register using the `register` method.
|
|
98
|
+
|
|
99
|
+
**Default Options and Values**:
|
|
100
|
+
|
|
101
|
+
```TypeScript
|
|
102
|
+
{
|
|
103
|
+
main: {
|
|
104
|
+
noShadow: false,
|
|
105
|
+
},
|
|
106
|
+
interactor: {
|
|
107
|
+
preventDefault: true,
|
|
108
|
+
proControlSchema: false,
|
|
109
|
+
zoomFactor: 0.002,
|
|
110
|
+
lockControlSchema: false,
|
|
111
|
+
},
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- `noShadow` — Disables shadow DOM, DOM elements will be appended to the light DOM directly. The canvas viewer will still be functional, but the styles may be affected.
|
|
116
|
+
- `preventDefault` — Prevents default behavior of mouse events, the viewer may not work properly if set to false.
|
|
117
|
+
- `proControlSchema` — Uses control keybindings in professional software (`mouse wheel`: scroll vertically; `mouse wheel + shift`: scroll horizontally; `mouse wheel + ctrl`: zoom), rather than zooming with the mouse wheel. The canvas viewer automatically detects and adjusts the control schema by default, but you can explicitly configure it. This option doesn't affect mobile control.
|
|
118
|
+
- `zoomFactor` — The zoom factor, how fast the canvas zooms in or out.
|
|
119
|
+
- `lockControlSchema` — Locks the control schema.
|
|
120
|
+
|
|
121
|
+
**Default Hooks**:
|
|
122
|
+
|
|
123
|
+
```TypeScript
|
|
124
|
+
{
|
|
125
|
+
onDispose: [],
|
|
126
|
+
onRender: [],
|
|
127
|
+
onResize: [(width: number, height: number) => {}],
|
|
128
|
+
onClick: [(id: string | null) => {}],
|
|
129
|
+
onZoom: [],
|
|
130
|
+
onToggleFullscreen: [],
|
|
131
|
+
onInteractionStart: [],
|
|
132
|
+
onInteractionEnd: [],
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
- `onDispose` — Called when the viewer is disposed.
|
|
137
|
+
- `onRender` — Called when the viewer is rendered every frame.
|
|
138
|
+
- `onResize` — Called when the viewer container is resized.
|
|
139
|
+
- `width` — The width of the resized viewer container.
|
|
140
|
+
- `height` — The height of the resized viewer container.
|
|
141
|
+
- `onClick` — Called when the canvas is clicked.
|
|
142
|
+
- `id` — The id of the node that is clicked, or `null` if no node is clicked.
|
|
143
|
+
- `onZoom` — Called when the zoom level changes.
|
|
144
|
+
- `onToggleFullscreen` — Called when the fullscreen mode is toggled.
|
|
145
|
+
- `onInteractionStart` — Called when the pointer enters a selected node.
|
|
146
|
+
- `onInteractionEnd` — Called when the pointer leaves a selected node.
|
|
147
|
+
|
|
148
|
+
**Default API**:
|
|
149
|
+
|
|
150
|
+
```TypeScript
|
|
151
|
+
{
|
|
152
|
+
main: {
|
|
153
|
+
loadCanvas: (path: string) => Promise<void>,
|
|
154
|
+
refresh: () => void, // Manually trigger a render
|
|
155
|
+
pan: (x: number, y: number) => void,
|
|
156
|
+
zoom: (factor: number, origin: Coordinates) => void,
|
|
157
|
+
zoomToScale: (newScale: number, origin: Coordinates) => void,
|
|
158
|
+
panToCoords: (x: number, y: number) => void,
|
|
159
|
+
shiftFullscreen: (option: 'toggle' | 'enter' | 'exit' = 'toggle') => void,
|
|
160
|
+
resetView: () => void, // Reset the scale and offset to default that the whole canvas is visible
|
|
161
|
+
},
|
|
162
|
+
dataManager: {
|
|
163
|
+
middleViewer: () => {
|
|
164
|
+
x: number; // half of the container width
|
|
165
|
+
y: number; // half of the container height
|
|
166
|
+
width: number; // container width
|
|
167
|
+
height: number; // container height
|
|
168
|
+
},
|
|
169
|
+
findNodeAtMousePosition: (mousePosition: Coordinates) => JSONCanvasNode | null,
|
|
170
|
+
},
|
|
171
|
+
interactionHandler: {
|
|
172
|
+
stop: () => void, // Stop receiving interaction
|
|
173
|
+
start: () => void, // Start receiving interaction
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Extensions
|
|
179
|
+
|
|
180
|
+
The viewer is built with extensibility in mind, and it is easy to extend the viewer with custom extensions.
|
|
181
|
+
|
|
182
|
+
#### Official Extensions
|
|
183
|
+
|
|
184
|
+
**minimap**: Renders the minimap with an overview of the canvas.
|
|
185
|
+
- used with:
|
|
186
|
+
```TypeScript
|
|
187
|
+
import minimap from 'json-canvas-viewer/minimap';
|
|
188
|
+
new canvasViewer(container, { extensions: [minimap] });
|
|
189
|
+
```
|
|
190
|
+
- new options and API:
|
|
191
|
+
```TypeScript
|
|
192
|
+
{
|
|
193
|
+
options: {
|
|
194
|
+
minimap: {
|
|
195
|
+
collapsed: false,
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
api: {
|
|
199
|
+
minimap: {
|
|
200
|
+
toggleCollapse: () => void,
|
|
201
|
+
},
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**mistouchPreventer**: Prevents mistouch by freezing the canvas when clicking outside the viewer.
|
|
207
|
+
- used with:
|
|
208
|
+
```TypeScript
|
|
209
|
+
import mistouchPreventer from 'json-canvas-viewer/mistouchPreventer';
|
|
210
|
+
new canvasViewer(container, { extensions: [mistouchPreventer] });
|
|
211
|
+
```
|
|
212
|
+
- new options and API:
|
|
213
|
+
```TypeScript
|
|
214
|
+
{
|
|
215
|
+
options: {
|
|
216
|
+
mistouchPreventer: {
|
|
217
|
+
preventAtStart: true,
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
api: {
|
|
221
|
+
mistouchPreventer: {
|
|
222
|
+
startPrevention: () => void,
|
|
223
|
+
endPrevention: () => void,
|
|
224
|
+
},
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**controls**: Shows a control bar with zoom, pan, scale slider, and fullscreen buttons.
|
|
230
|
+
- used with:
|
|
231
|
+
```TypeScript
|
|
232
|
+
import controls from 'json-canvas-viewer/controls';
|
|
233
|
+
new canvasViewer(container, { extensions: [controls] });
|
|
234
|
+
```
|
|
235
|
+
- new options and API:
|
|
236
|
+
```TypeScript
|
|
237
|
+
{
|
|
238
|
+
options: {
|
|
239
|
+
controls: {
|
|
240
|
+
collapsed: false,
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
api: {
|
|
244
|
+
controls: {
|
|
245
|
+
toggleCollapse: () => void,
|
|
246
|
+
},
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**debugPanel**: Shows a debug panel with scale and offset.
|
|
252
|
+
- used with:
|
|
253
|
+
```TypeScript
|
|
254
|
+
import debugPanel from 'json-canvas-viewer/debugPanel';
|
|
255
|
+
new canvasViewer(container, { extensions: [debugPanel] });
|
|
256
|
+
```
|
|
257
|
+
- new API:
|
|
258
|
+
```TypeScript
|
|
259
|
+
{
|
|
260
|
+
api: {
|
|
261
|
+
debugPanel: {
|
|
262
|
+
update: () => void,
|
|
263
|
+
},
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### Develop an Extension
|
|
269
|
+
|
|
270
|
+
An extension, in essence, is a class that follows a fixed pattern. You can do almost anything with the viewer by using an extension. Actually, the viewer runs with only four core extensions: `renderer`, `interactionHandler`, `overlayManager` and `dataManager`. Here is the fixed pattern:
|
|
271
|
+
- receive `runtimeData` and `registry` as parameters in the constructor.
|
|
272
|
+
- calls `registry.register` first in the constructor to define default options, register hooks and provide API.
|
|
273
|
+
|
|
274
|
+
Here comes a minimal sample extension of a debug panel (JavaScript for simplicity):
|
|
275
|
+
|
|
276
|
+
```JavaScript
|
|
277
|
+
import { round } from '../utilities';
|
|
278
|
+
|
|
279
|
+
export default class debugPanel {
|
|
280
|
+
constructor(data, registry) {
|
|
281
|
+
registry.register({
|
|
282
|
+
hooks: {
|
|
283
|
+
onRender: [this.update],
|
|
284
|
+
onDispose: [this.dispose],
|
|
285
|
+
},
|
|
286
|
+
api: {
|
|
287
|
+
debugPanel: {
|
|
288
|
+
update: this.update,
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
this.debugPanel = document.createElement('div');
|
|
293
|
+
this.debugPanel.className = 'debug-panel';
|
|
294
|
+
this.data = data;
|
|
295
|
+
data.container.appendChild(this.debugPanel);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private update = () => {
|
|
299
|
+
this.debugPanel.innerHTML = `
|
|
300
|
+
<p>Scale: ${round(this.data.scale, 3)}</p>
|
|
301
|
+
<p>Offset: ${round(this.data.offsetX, 1)}, ${round(this.data.offsetY, 1)}</p>
|
|
302
|
+
`;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
private dispose = () => {
|
|
306
|
+
this.debugPanel.remove();
|
|
307
|
+
this.debugPanel = null;
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## 📂 Canvas File Structure
|
|
313
|
+
|
|
314
|
+
The viewer expects JSON Canvas files in JSON format (a combination of official [JSON Canvas spec](https://jsoncanvas.org/spec/1.0/) and [Developer-Mike/obsidian-advanced-canvas spec](https://github.com/Developer-Mike/obsidian-advanced-canvas)):
|
|
315
|
+
|
|
316
|
+
```TypeScript
|
|
317
|
+
interface JSONCanvas {
|
|
318
|
+
nodes: Array<JSONCanvasNode>;
|
|
319
|
+
edges: Array<JSONCanvasEdge>;
|
|
320
|
+
metadata: {
|
|
321
|
+
version: string;
|
|
322
|
+
frontmatter: Record<string, string>;
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
interface JSONCanvasNode {
|
|
327
|
+
id: string;
|
|
328
|
+
type: 'group' | 'file' | 'text' | 'link';
|
|
329
|
+
x: number;
|
|
330
|
+
y: number;
|
|
331
|
+
width: number;
|
|
332
|
+
height: number;
|
|
333
|
+
label?: string;
|
|
334
|
+
background?: string;
|
|
335
|
+
backgroundStyle?: 'cover' | 'ratio' | 'repeat';
|
|
336
|
+
styleAttributes?: Record<string, string>;
|
|
337
|
+
color?: string;
|
|
338
|
+
text?: string;
|
|
339
|
+
file?: string;
|
|
340
|
+
subpath?: string;
|
|
341
|
+
url?: string;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
interface JSONCanvasEdge {
|
|
345
|
+
id: string;
|
|
346
|
+
fromNode: string;
|
|
347
|
+
toNode: string;
|
|
348
|
+
fromSide: 'right' | 'left' | 'top' | 'bottom';
|
|
349
|
+
toSide: 'right' | 'left' | 'top' | 'bottom';
|
|
350
|
+
toEnd?: 'arrow' | 'none';
|
|
351
|
+
label?: string;
|
|
352
|
+
styleAttributes?: Record<string, string>;
|
|
353
|
+
color?: string;
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## 💻 Development
|
|
358
|
+
|
|
359
|
+
Built with `TypeScript`, `SCSS` and `HTML5 Canvas`.
|
|
360
|
+
|
|
361
|
+
**Project Structure**:
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
root
|
|
365
|
+
├── src/
|
|
366
|
+
│ ├── extensions/
|
|
367
|
+
│ │ ├── controls.ts // Control panel
|
|
368
|
+
│ │ ├── minimap.ts // Minimap extension
|
|
369
|
+
│ │ ├── mistouchPreventer.ts // MistouchPrevention extension
|
|
370
|
+
│ │ └── debugPanel.ts // Debug panel
|
|
371
|
+
│ ├── canvasViewer.ts // Main entry point
|
|
372
|
+
│ ├── interactor.ts // Handles pointer events for user pan/zoom
|
|
373
|
+
│ ├── dataManager.ts // Manages canvas data
|
|
374
|
+
│ ├── interactionHandler.ts // Handles interaction events (wrapper of interactor)
|
|
375
|
+
│ ├── overlayManager.ts // Renderer for interactive nodes
|
|
376
|
+
│ ├── renderer.ts // Renderer for non-interactive stuff
|
|
377
|
+
│ ├── declarations.d.ts // Public types
|
|
378
|
+
│ ├── utilities.ts // Utility functions
|
|
379
|
+
│ └── styles.scss // Styles for the viewer
|
|
380
|
+
└── example/
|
|
381
|
+
├── index.html // Example/test entry point
|
|
382
|
+
└── Example Canvas/ // Example/test canvas file
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## 📝 Copyright & License
|
|
386
|
+
|
|
387
|
+
Copyright ©️ 2025 Hesprs (Hēsperus) | [MIT License](https://mit-license.org/)
|