@knotx/plugins-canvas 0.4.11 → 0.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +371 -0
- package/README.md +371 -0
- package/dist/index.cjs +27 -26
- package/dist/index.d.cts +3 -2
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +29 -28
- package/package.json +11 -11
package/README.en.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# @knotx/plugins-canvas
|
|
2
|
+
|
|
3
|
+
Canvas plugin that provides canvas container, transformation controls, and interaction features for KnotX.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @knotx/plugins-canvas
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The Canvas plugin is one of the core plugins for KnotX, providing canvas container, zoom, pan, scroll, and other basic functionalities. This plugin is built on top of the `react-zoom-pan-pinch` library and provides transformation state and container information for other plugins.
|
|
14
|
+
|
|
15
|
+
## Implementation Principle
|
|
16
|
+
|
|
17
|
+
The Canvas plugin implements canvas functionality through:
|
|
18
|
+
|
|
19
|
+
1. **Transform Management**: Uses the `react-zoom-pan-pinch` library to manage canvas zoom and pan
|
|
20
|
+
2. **Event System**: Provides canvas-level event listening and handling
|
|
21
|
+
3. **Edge Scrolling**: Supports automatic scrolling when dragging to edges
|
|
22
|
+
4. **Content Size Management**: Tracks and manages canvas content dimensions
|
|
23
|
+
|
|
24
|
+
## Dependencies
|
|
25
|
+
|
|
26
|
+
### Core Dependencies
|
|
27
|
+
- `@knotx/core`: Provides base plugin architecture
|
|
28
|
+
- `@knotx/decorators`: Provides decorator support
|
|
29
|
+
- `@knotx/react-zoom-pan-pinch`: Provides zoom and pan functionality
|
|
30
|
+
- `lodash-es`: Provides utility functions
|
|
31
|
+
- `rxjs`: Provides reactive programming support
|
|
32
|
+
|
|
33
|
+
### Optional Dependencies
|
|
34
|
+
- `@knotx/plugins-history`: Provides history functionality
|
|
35
|
+
- `react`: React framework support
|
|
36
|
+
|
|
37
|
+
## API Documentation
|
|
38
|
+
|
|
39
|
+
### Main Classes
|
|
40
|
+
|
|
41
|
+
#### Canvas
|
|
42
|
+
|
|
43
|
+
The main class of the Canvas plugin, extending `BasePlugin`.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
export class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
47
|
+
name = 'canvas' as const
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Configuration Options
|
|
52
|
+
|
|
53
|
+
#### CanvasConfig
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
export type CanvasConfig = ReactZoomPanPinchProps & {
|
|
57
|
+
defaultLocated?: DefaultLocatedOptions
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Inherits all configuration options from `react-zoom-pan-pinch` and adds:
|
|
62
|
+
|
|
63
|
+
- `defaultLocated`: Default positioning options
|
|
64
|
+
|
|
65
|
+
### Plugin Data (PluginData)
|
|
66
|
+
|
|
67
|
+
The Canvas plugin provides the following data to other plugins:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface PluginData {
|
|
71
|
+
canvas: {
|
|
72
|
+
transform: CanvasTransformState
|
|
73
|
+
rootElement: Element | null
|
|
74
|
+
contentSize: CanvasContentSize | undefined
|
|
75
|
+
updateContentSize: (contentSize: CanvasContentSize) => void
|
|
76
|
+
addListener: (event: CanvasEventType, listener: CanvasEventListener) => void
|
|
77
|
+
removeListener: (event: CanvasEventType, listener: CanvasEventListener) => void
|
|
78
|
+
edgeScroll: {
|
|
79
|
+
config: EdgeScrollConfig
|
|
80
|
+
setConfig: (config: Partial<EdgeScrollConfig>) => void
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Plugin Tools (PluginTools)
|
|
87
|
+
|
|
88
|
+
The Canvas plugin provides the following tool methods:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
interface PluginTools {
|
|
92
|
+
canvas: {
|
|
93
|
+
scrollNodeIntoView: (params: ScrollNodeIntoViewOptions) => void
|
|
94
|
+
zoomIn: (params: { step?: number, animationTime?: number }) => void
|
|
95
|
+
zoomOut: (params: { step?: number, animationTime?: number }) => void
|
|
96
|
+
setTransform: (params: {
|
|
97
|
+
positionX: number
|
|
98
|
+
positionY: number
|
|
99
|
+
scale: number
|
|
100
|
+
animationTime?: number
|
|
101
|
+
}) => void
|
|
102
|
+
resetTransform: (params: { animationTime?: number }) => void
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Type Definitions
|
|
108
|
+
|
|
109
|
+
#### CanvasTransformState
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
interface CanvasTransformState {
|
|
113
|
+
positionX: number
|
|
114
|
+
positionY: number
|
|
115
|
+
scale: number
|
|
116
|
+
previousScale: number
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### CanvasContentSize
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
interface CanvasContentSize {
|
|
124
|
+
width: number
|
|
125
|
+
height: number
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### EdgeScrollConfig
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
interface EdgeScrollConfig {
|
|
133
|
+
enabled: boolean
|
|
134
|
+
edgeSize: number
|
|
135
|
+
maxSpeed: number
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Usage Examples
|
|
140
|
+
|
|
141
|
+
### Basic Usage
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
145
|
+
|
|
146
|
+
const engine = new Engine({
|
|
147
|
+
plugins: [Canvas],
|
|
148
|
+
pluginConfig: {
|
|
149
|
+
canvas: {
|
|
150
|
+
minScale: 0.1,
|
|
151
|
+
maxScale: 3,
|
|
152
|
+
limitToBounds: false,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Custom Zoom Configuration
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const engine = new Engine({
|
|
162
|
+
plugins: [Canvas],
|
|
163
|
+
pluginConfig: {
|
|
164
|
+
canvas: {
|
|
165
|
+
minScale: 0.2,
|
|
166
|
+
maxScale: 5,
|
|
167
|
+
wheel: {
|
|
168
|
+
step: 0.1,
|
|
169
|
+
smoothStep: 0.006,
|
|
170
|
+
},
|
|
171
|
+
panning: {
|
|
172
|
+
allowLeftClickPan: false,
|
|
173
|
+
allowRightClickPan: true,
|
|
174
|
+
wheelPanning: true,
|
|
175
|
+
},
|
|
176
|
+
zoomAnimation: {
|
|
177
|
+
size: 0.1,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Edge Scrolling Configuration
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const engine = new Engine({
|
|
188
|
+
plugins: [Canvas],
|
|
189
|
+
pluginConfig: {
|
|
190
|
+
canvas: {
|
|
191
|
+
// Basic configuration
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
// Enable edge scrolling
|
|
197
|
+
engine.callTool('canvas', 'edgeScroll.setConfig', {
|
|
198
|
+
enabled: true,
|
|
199
|
+
edgeSize: 100,
|
|
200
|
+
maxSpeed: 10,
|
|
201
|
+
})
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Tool Methods Usage
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// Zoom in
|
|
208
|
+
engine.callTool('canvas', 'zoomIn', { step: 0.2, animationTime: 300 })
|
|
209
|
+
|
|
210
|
+
// Zoom out
|
|
211
|
+
engine.callTool('canvas', 'zoomOut', { step: 0.2, animationTime: 300 })
|
|
212
|
+
|
|
213
|
+
// Set transform
|
|
214
|
+
engine.callTool('canvas', 'setTransform', {
|
|
215
|
+
positionX: 100,
|
|
216
|
+
positionY: 100,
|
|
217
|
+
scale: 1.5,
|
|
218
|
+
animationTime: 500,
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// Reset transform
|
|
222
|
+
engine.callTool('canvas', 'resetTransform', { animationTime: 300 })
|
|
223
|
+
|
|
224
|
+
// Scroll node into view
|
|
225
|
+
engine.callTool('canvas', 'scrollNodeIntoView', {
|
|
226
|
+
nodeId: 'node-1',
|
|
227
|
+
scale: 1.2,
|
|
228
|
+
block: 'center',
|
|
229
|
+
inline: 'center',
|
|
230
|
+
})
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Event Listening
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
// Get canvas data
|
|
237
|
+
const canvasData = engine.getPluginData('canvas')
|
|
238
|
+
|
|
239
|
+
// Add click event listener
|
|
240
|
+
function handleClick(event: MouseEvent) {
|
|
241
|
+
console.log('Canvas clicked:', event)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
canvasData.addListener('click', handleClick)
|
|
245
|
+
|
|
246
|
+
// Remove listener
|
|
247
|
+
canvasData.removeListener('click', handleClick)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Getting Transform State
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// Get transform state in other plugins
|
|
254
|
+
class MyPlugin extends BasePlugin {
|
|
255
|
+
@inject.canvas.transform()
|
|
256
|
+
transform!: CanvasTransformState
|
|
257
|
+
|
|
258
|
+
someMethod() {
|
|
259
|
+
console.log('Current scale:', this.transform.scale)
|
|
260
|
+
console.log('Position:', this.transform.positionX, this.transform.positionY)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Integration with Other Plugins
|
|
266
|
+
|
|
267
|
+
### Integration with History Plugin
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
271
|
+
import { History } from '@knotx/plugins-history'
|
|
272
|
+
|
|
273
|
+
const engine = new Engine({
|
|
274
|
+
plugins: [Canvas, History],
|
|
275
|
+
pluginConfig: {
|
|
276
|
+
canvas: {
|
|
277
|
+
minScale: 0.1,
|
|
278
|
+
maxScale: 3,
|
|
279
|
+
},
|
|
280
|
+
history: {
|
|
281
|
+
maxHistory: 50,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
})
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Integration with Background Plugin
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { Background } from '@knotx/plugins-background'
|
|
291
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
292
|
+
|
|
293
|
+
const engine = new Engine({
|
|
294
|
+
plugins: [Canvas, Background],
|
|
295
|
+
pluginConfig: {
|
|
296
|
+
canvas: {
|
|
297
|
+
minScale: 0.1,
|
|
298
|
+
maxScale: 3,
|
|
299
|
+
},
|
|
300
|
+
background: {
|
|
301
|
+
variant: 'dots',
|
|
302
|
+
color: '#ddd',
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
})
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## File Directory Structure
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
packages/plugins-canvas/
|
|
312
|
+
├── src/
|
|
313
|
+
│ ├── canvas.tsx # Main implementation file
|
|
314
|
+
│ ├── transform.ts # Transform calculation utilities
|
|
315
|
+
│ ├── types.ts # Type definitions
|
|
316
|
+
│ └── index.ts # Export file
|
|
317
|
+
├── dist/ # Build output directory
|
|
318
|
+
├── package.json # Package configuration
|
|
319
|
+
├── build.config.ts # Build configuration
|
|
320
|
+
├── tsconfig.json # TypeScript configuration
|
|
321
|
+
├── eslint.config.mjs # ESLint configuration
|
|
322
|
+
└── CHANGELOG.md # Changelog
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Core Files Description
|
|
326
|
+
|
|
327
|
+
- **canvas.tsx**: Contains the main implementation of the Canvas plugin, including transform management, event handling, and tool methods
|
|
328
|
+
- **transform.ts**: Transform calculation utility functions
|
|
329
|
+
- **types.ts**: TypeScript type definitions
|
|
330
|
+
- **index.ts**: Exports the Canvas class and related type definitions
|
|
331
|
+
|
|
332
|
+
## Advanced Features
|
|
333
|
+
|
|
334
|
+
### Custom Transform Calculation
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
// Use utility functions from transform.ts
|
|
338
|
+
import { calculateTransform } from '@knotx/plugins-canvas/transform'
|
|
339
|
+
|
|
340
|
+
const result = calculateTransform({
|
|
341
|
+
// Transform parameters
|
|
342
|
+
})
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Dynamic Content Size
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
// Dynamically update content size in plugins
|
|
349
|
+
class MyPlugin extends BasePlugin {
|
|
350
|
+
@inject.canvas.updateContentSize()
|
|
351
|
+
updateContentSize!: (size: CanvasContentSize) => void
|
|
352
|
+
|
|
353
|
+
updateSize() {
|
|
354
|
+
this.updateContentSize({
|
|
355
|
+
width: 2000,
|
|
356
|
+
height: 1500,
|
|
357
|
+
})
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Notes
|
|
363
|
+
|
|
364
|
+
1. **Performance Optimization**: The Canvas plugin frequently triggers re-renders; only listen to transform state when necessary
|
|
365
|
+
2. **Event Bubbling**: Canvas events may conflict with other events; pay attention to event handling priority
|
|
366
|
+
3. **Memory Management**: Remove unnecessary event listeners promptly to avoid memory leaks
|
|
367
|
+
4. **React Version**: Ensure React version compatibility with `react-zoom-pan-pinch`
|
|
368
|
+
|
|
369
|
+
## License
|
|
370
|
+
|
|
371
|
+
MIT
|
package/README.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# @knotx/plugins-canvas
|
|
2
|
+
|
|
3
|
+
画布插件,为 KnotX 提供画布容器、变换控制和交互功能。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @knotx/plugins-canvas
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 概述
|
|
12
|
+
|
|
13
|
+
Canvas 插件是 KnotX 的核心插件之一,提供了画布容器、缩放、平移、滚动等基础功能。该插件基于 `react-zoom-pan-pinch` 库实现,为其他插件提供了变换状态和容器信息。
|
|
14
|
+
|
|
15
|
+
## 实现原理
|
|
16
|
+
|
|
17
|
+
Canvas 插件通过以下方式实现画布功能:
|
|
18
|
+
|
|
19
|
+
1. **变换管理**:使用 `react-zoom-pan-pinch` 库管理画布的缩放和平移
|
|
20
|
+
2. **事件系统**:提供画布级别的事件监听和处理
|
|
21
|
+
3. **边缘滚动**:支持拖拽到边缘时的自动滚动
|
|
22
|
+
4. **内容尺寸管理**:跟踪和管理画布内容的尺寸
|
|
23
|
+
|
|
24
|
+
## 依赖关系
|
|
25
|
+
|
|
26
|
+
### 核心依赖
|
|
27
|
+
- `@knotx/core`:提供基础插件架构
|
|
28
|
+
- `@knotx/decorators`:提供装饰器支持
|
|
29
|
+
- `@knotx/react-zoom-pan-pinch`:提供缩放和平移功能
|
|
30
|
+
- `lodash-es`:提供工具函数
|
|
31
|
+
- `rxjs`:提供响应式编程支持
|
|
32
|
+
|
|
33
|
+
### 可选依赖
|
|
34
|
+
- `@knotx/plugins-history`:提供历史记录功能
|
|
35
|
+
- `react`:React 框架支持
|
|
36
|
+
|
|
37
|
+
## API 文档
|
|
38
|
+
|
|
39
|
+
### 主要类
|
|
40
|
+
|
|
41
|
+
#### Canvas
|
|
42
|
+
|
|
43
|
+
画布插件的主要类,继承自 `BasePlugin`。
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
export class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
47
|
+
name = 'canvas' as const
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 配置选项
|
|
52
|
+
|
|
53
|
+
#### CanvasConfig
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
export type CanvasConfig = ReactZoomPanPinchProps & {
|
|
57
|
+
defaultLocated?: DefaultLocatedOptions
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
继承自 `react-zoom-pan-pinch` 的所有配置选项,并添加了:
|
|
62
|
+
|
|
63
|
+
- `defaultLocated`:默认定位选项
|
|
64
|
+
|
|
65
|
+
### 插件数据 (PluginData)
|
|
66
|
+
|
|
67
|
+
Canvas 插件向其他插件提供以下数据:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface PluginData {
|
|
71
|
+
canvas: {
|
|
72
|
+
transform: CanvasTransformState
|
|
73
|
+
rootElement: Element | null
|
|
74
|
+
contentSize: CanvasContentSize | undefined
|
|
75
|
+
updateContentSize: (contentSize: CanvasContentSize) => void
|
|
76
|
+
addListener: (event: CanvasEventType, listener: CanvasEventListener) => void
|
|
77
|
+
removeListener: (event: CanvasEventType, listener: CanvasEventListener) => void
|
|
78
|
+
edgeScroll: {
|
|
79
|
+
config: EdgeScrollConfig
|
|
80
|
+
setConfig: (config: Partial<EdgeScrollConfig>) => void
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 插件工具 (PluginTools)
|
|
87
|
+
|
|
88
|
+
Canvas 插件提供以下工具方法:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
interface PluginTools {
|
|
92
|
+
canvas: {
|
|
93
|
+
scrollNodeIntoView: (params: ScrollNodeIntoViewOptions) => void
|
|
94
|
+
zoomIn: (params: { step?: number, animationTime?: number }) => void
|
|
95
|
+
zoomOut: (params: { step?: number, animationTime?: number }) => void
|
|
96
|
+
setTransform: (params: {
|
|
97
|
+
positionX: number
|
|
98
|
+
positionY: number
|
|
99
|
+
scale: number
|
|
100
|
+
animationTime?: number
|
|
101
|
+
}) => void
|
|
102
|
+
resetTransform: (params: { animationTime?: number }) => void
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 类型定义
|
|
108
|
+
|
|
109
|
+
#### CanvasTransformState
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
interface CanvasTransformState {
|
|
113
|
+
positionX: number
|
|
114
|
+
positionY: number
|
|
115
|
+
scale: number
|
|
116
|
+
previousScale: number
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### CanvasContentSize
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
interface CanvasContentSize {
|
|
124
|
+
width: number
|
|
125
|
+
height: number
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### EdgeScrollConfig
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
interface EdgeScrollConfig {
|
|
133
|
+
enabled: boolean
|
|
134
|
+
edgeSize: number
|
|
135
|
+
maxSpeed: number
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 使用示例
|
|
140
|
+
|
|
141
|
+
### 基本用法
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
145
|
+
|
|
146
|
+
const engine = new Engine({
|
|
147
|
+
plugins: [Canvas],
|
|
148
|
+
pluginConfig: {
|
|
149
|
+
canvas: {
|
|
150
|
+
minScale: 0.1,
|
|
151
|
+
maxScale: 3,
|
|
152
|
+
limitToBounds: false,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 自定义缩放配置
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const engine = new Engine({
|
|
162
|
+
plugins: [Canvas],
|
|
163
|
+
pluginConfig: {
|
|
164
|
+
canvas: {
|
|
165
|
+
minScale: 0.2,
|
|
166
|
+
maxScale: 5,
|
|
167
|
+
wheel: {
|
|
168
|
+
step: 0.1,
|
|
169
|
+
smoothStep: 0.006,
|
|
170
|
+
},
|
|
171
|
+
panning: {
|
|
172
|
+
allowLeftClickPan: false,
|
|
173
|
+
allowRightClickPan: true,
|
|
174
|
+
wheelPanning: true,
|
|
175
|
+
},
|
|
176
|
+
zoomAnimation: {
|
|
177
|
+
size: 0.1,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 边缘滚动配置
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const engine = new Engine({
|
|
188
|
+
plugins: [Canvas],
|
|
189
|
+
pluginConfig: {
|
|
190
|
+
canvas: {
|
|
191
|
+
// 基础配置
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
// 启用边缘滚动
|
|
197
|
+
engine.callTool('canvas', 'edgeScroll.setConfig', {
|
|
198
|
+
enabled: true,
|
|
199
|
+
edgeSize: 100,
|
|
200
|
+
maxSpeed: 10,
|
|
201
|
+
})
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### 工具方法使用
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// 放大
|
|
208
|
+
engine.callTool('canvas', 'zoomIn', { step: 0.2, animationTime: 300 })
|
|
209
|
+
|
|
210
|
+
// 缩小
|
|
211
|
+
engine.callTool('canvas', 'zoomOut', { step: 0.2, animationTime: 300 })
|
|
212
|
+
|
|
213
|
+
// 设置变换
|
|
214
|
+
engine.callTool('canvas', 'setTransform', {
|
|
215
|
+
positionX: 100,
|
|
216
|
+
positionY: 100,
|
|
217
|
+
scale: 1.5,
|
|
218
|
+
animationTime: 500,
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// 重置变换
|
|
222
|
+
engine.callTool('canvas', 'resetTransform', { animationTime: 300 })
|
|
223
|
+
|
|
224
|
+
// 滚动节点到视野内
|
|
225
|
+
engine.callTool('canvas', 'scrollNodeIntoView', {
|
|
226
|
+
nodeId: 'node-1',
|
|
227
|
+
scale: 1.2,
|
|
228
|
+
block: 'center',
|
|
229
|
+
inline: 'center',
|
|
230
|
+
})
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 事件监听
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
// 获取画布数据
|
|
237
|
+
const canvasData = engine.getPluginData('canvas')
|
|
238
|
+
|
|
239
|
+
// 添加点击事件监听
|
|
240
|
+
function handleClick(event: MouseEvent) {
|
|
241
|
+
console.log('Canvas clicked:', event)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
canvasData.addListener('click', handleClick)
|
|
245
|
+
|
|
246
|
+
// 移除监听
|
|
247
|
+
canvasData.removeListener('click', handleClick)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### 获取变换状态
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// 在其他插件中获取变换状态
|
|
254
|
+
class MyPlugin extends BasePlugin {
|
|
255
|
+
@inject.canvas.transform()
|
|
256
|
+
transform!: CanvasTransformState
|
|
257
|
+
|
|
258
|
+
someMethod() {
|
|
259
|
+
console.log('Current scale:', this.transform.scale)
|
|
260
|
+
console.log('Position:', this.transform.positionX, this.transform.positionY)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## 与其他插件的集成
|
|
266
|
+
|
|
267
|
+
### 与 History 插件集成
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
271
|
+
import { History } from '@knotx/plugins-history'
|
|
272
|
+
|
|
273
|
+
const engine = new Engine({
|
|
274
|
+
plugins: [Canvas, History],
|
|
275
|
+
pluginConfig: {
|
|
276
|
+
canvas: {
|
|
277
|
+
minScale: 0.1,
|
|
278
|
+
maxScale: 3,
|
|
279
|
+
},
|
|
280
|
+
history: {
|
|
281
|
+
maxHistory: 50,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
})
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 与 Background 插件集成
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { Background } from '@knotx/plugins-background'
|
|
291
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
292
|
+
|
|
293
|
+
const engine = new Engine({
|
|
294
|
+
plugins: [Canvas, Background],
|
|
295
|
+
pluginConfig: {
|
|
296
|
+
canvas: {
|
|
297
|
+
minScale: 0.1,
|
|
298
|
+
maxScale: 3,
|
|
299
|
+
},
|
|
300
|
+
background: {
|
|
301
|
+
variant: 'dots',
|
|
302
|
+
color: '#ddd',
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
})
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 文件目录结构
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
packages/plugins-canvas/
|
|
312
|
+
├── src/
|
|
313
|
+
│ ├── canvas.tsx # 主要实现文件
|
|
314
|
+
│ ├── transform.ts # 变换计算工具
|
|
315
|
+
│ ├── types.ts # 类型定义
|
|
316
|
+
│ └── index.ts # 导出文件
|
|
317
|
+
├── dist/ # 构建输出目录
|
|
318
|
+
├── package.json # 包配置文件
|
|
319
|
+
├── build.config.ts # 构建配置
|
|
320
|
+
├── tsconfig.json # TypeScript 配置
|
|
321
|
+
├── eslint.config.mjs # ESLint 配置
|
|
322
|
+
└── CHANGELOG.md # 更新日志
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### 核心文件说明
|
|
326
|
+
|
|
327
|
+
- **canvas.tsx**:包含 Canvas 插件的主要实现,包括变换管理、事件处理和工具方法
|
|
328
|
+
- **transform.ts**:变换计算相关的工具函数
|
|
329
|
+
- **types.ts**:TypeScript 类型定义
|
|
330
|
+
- **index.ts**:导出 Canvas 类和相关类型定义
|
|
331
|
+
|
|
332
|
+
## 高级功能
|
|
333
|
+
|
|
334
|
+
### 自定义变换计算
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
// 使用 transform.ts 中的工具函数
|
|
338
|
+
import { calculateTransform } from '@knotx/plugins-canvas/transform'
|
|
339
|
+
|
|
340
|
+
const result = calculateTransform({
|
|
341
|
+
// 变换参数
|
|
342
|
+
})
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 动态内容尺寸
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
// 在插件中动态更新内容尺寸
|
|
349
|
+
class MyPlugin extends BasePlugin {
|
|
350
|
+
@inject.canvas.updateContentSize()
|
|
351
|
+
updateContentSize!: (size: CanvasContentSize) => void
|
|
352
|
+
|
|
353
|
+
updateSize() {
|
|
354
|
+
this.updateContentSize({
|
|
355
|
+
width: 2000,
|
|
356
|
+
height: 1500,
|
|
357
|
+
})
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## 注意事项
|
|
363
|
+
|
|
364
|
+
1. **性能优化**:Canvas 插件会频繁触发重渲染,建议在需要时才监听变换状态
|
|
365
|
+
2. **事件冒泡**:Canvas 事件可能会与其他事件冲突,注意事件处理的优先级
|
|
366
|
+
3. **内存管理**:及时移除不需要的事件监听器,避免内存泄漏
|
|
367
|
+
4. **React 版本**:确保 React 版本与 `react-zoom-pan-pinch` 兼容
|
|
368
|
+
|
|
369
|
+
## 许可证
|
|
370
|
+
|
|
371
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -14,9 +14,7 @@ function calculateTransform({
|
|
|
14
14
|
scale,
|
|
15
15
|
block = "nearest",
|
|
16
16
|
inline = "nearest",
|
|
17
|
-
offset = 0
|
|
18
|
-
contentSize,
|
|
19
|
-
limitToBounds
|
|
17
|
+
offset = 0
|
|
20
18
|
}) {
|
|
21
19
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
22
20
|
const nodeX = (_a = node == null ? void 0 : node.position.x) != null ? _a : 0;
|
|
@@ -75,14 +73,6 @@ function calculateTransform({
|
|
|
75
73
|
break;
|
|
76
74
|
}
|
|
77
75
|
}
|
|
78
|
-
if (limitToBounds && contentSize) {
|
|
79
|
-
if (contentSize.width * scale < viewportWidth) {
|
|
80
|
-
positionX = contentSize.width / 2 * scale - viewportWidth / 2;
|
|
81
|
-
}
|
|
82
|
-
if (contentSize.height * scale < viewportHeight) {
|
|
83
|
-
positionY = contentSize.height / 2 * scale - viewportHeight / 2;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
76
|
return {
|
|
87
77
|
scale,
|
|
88
78
|
positionX,
|
|
@@ -209,6 +199,7 @@ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.registe
|
|
|
209
199
|
__publicField(this, "config");
|
|
210
200
|
__publicField(this, "name", "canvas");
|
|
211
201
|
__publicField(this, "ref", null);
|
|
202
|
+
__publicField(this, "zoomPanPinch");
|
|
212
203
|
__publicField(this, "dataManager", new core.DataManager(this.name));
|
|
213
204
|
__publicField(this, "transform", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
|
|
214
205
|
__publicField(this, "rootElement", __runInitializers(_init, 12, this, null)), __runInitializers(_init, 15, this);
|
|
@@ -339,7 +330,7 @@ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.registe
|
|
|
339
330
|
deltaY = -maxSpeed * factor;
|
|
340
331
|
}
|
|
341
332
|
if (deltaX !== 0 || deltaY !== 0) {
|
|
342
|
-
const currentState = this.
|
|
333
|
+
const currentState = this.zoomPanPinch.transformState;
|
|
343
334
|
const newPositionX = currentState.positionX + deltaX;
|
|
344
335
|
const newPositionY = currentState.positionY + deltaY;
|
|
345
336
|
this.ref.setTransform(newPositionX, newPositionY, currentState.scale, 0);
|
|
@@ -357,12 +348,10 @@ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.registe
|
|
|
357
348
|
node,
|
|
358
349
|
container: this.container,
|
|
359
350
|
transform: this.transform,
|
|
360
|
-
contentSize: this.contentSize,
|
|
361
351
|
scale,
|
|
362
352
|
block,
|
|
363
353
|
inline,
|
|
364
|
-
offset
|
|
365
|
-
limitToBounds: false
|
|
354
|
+
offset
|
|
366
355
|
});
|
|
367
356
|
(_a2 = this.ref) == null ? void 0 : _a2.setTransform(-positionX, -positionY, newScale, animationTime);
|
|
368
357
|
}
|
|
@@ -385,7 +374,9 @@ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.registe
|
|
|
385
374
|
render({ children } = { children: null }) {
|
|
386
375
|
var _a2, _b;
|
|
387
376
|
const contentSize = core.use(() => this.contentSize);
|
|
388
|
-
|
|
377
|
+
if (!this.zoomPanPinch) {
|
|
378
|
+
this.createZoomPanPinch();
|
|
379
|
+
}
|
|
389
380
|
const [transformRef, setTransformRef] = react.useReducer((_, ref) => {
|
|
390
381
|
var _a3;
|
|
391
382
|
const dom = ref.instance.wrapperComponent;
|
|
@@ -442,9 +433,7 @@ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.registe
|
|
|
442
433
|
reactZoomPanPinch.TransformWrapper,
|
|
443
434
|
__spreadProps(__spreadValues({}, this.config), {
|
|
444
435
|
ref: setTransformRef,
|
|
445
|
-
|
|
446
|
-
initialPositionY: defaultTransform.positionY,
|
|
447
|
-
initialScale: defaultTransform.scale,
|
|
436
|
+
initialInstance: this.zoomPanPinch,
|
|
448
437
|
children: [
|
|
449
438
|
/* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: fixedLayers }),
|
|
450
439
|
/* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -511,6 +500,14 @@ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.registe
|
|
|
511
500
|
})
|
|
512
501
|
);
|
|
513
502
|
}
|
|
503
|
+
createZoomPanPinch() {
|
|
504
|
+
const defaultTransform = this.getDefaultTransform();
|
|
505
|
+
this.zoomPanPinch = new reactZoomPanPinch.ZoomPanPinch(this.config);
|
|
506
|
+
if (defaultTransform) {
|
|
507
|
+
this.zoomPanPinch.calcNewPosition(defaultTransform.positionX, defaultTransform.positionY);
|
|
508
|
+
}
|
|
509
|
+
this.transform = __spreadValues({}, this.zoomPanPinch.transformState);
|
|
510
|
+
}
|
|
514
511
|
groupLayers(children) {
|
|
515
512
|
const fixedLayers = [];
|
|
516
513
|
const childrenLayers = [];
|
|
@@ -527,27 +524,31 @@ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.registe
|
|
|
527
524
|
return [fixedLayers, childrenLayers];
|
|
528
525
|
}
|
|
529
526
|
getDefaultTransform() {
|
|
527
|
+
var _a2, _b, _c;
|
|
530
528
|
const defaultLocated = __spreadValues({}, this.config.defaultLocated);
|
|
531
|
-
if (!(defaultLocated == null ? void 0 : defaultLocated.nodeId)
|
|
532
|
-
return
|
|
529
|
+
if (!(defaultLocated == null ? void 0 : defaultLocated.nodeId)) {
|
|
530
|
+
return void 0;
|
|
533
531
|
}
|
|
534
532
|
const node = defaultLocated.nodeId ? this.getNode({ id: defaultLocated.nodeId }) : void 0;
|
|
535
533
|
defaultLocated.inline || (defaultLocated.inline = "center");
|
|
536
534
|
defaultLocated.block || (defaultLocated.block = "center");
|
|
537
|
-
defaultLocated.scale || (defaultLocated.scale = this.
|
|
535
|
+
defaultLocated.scale || (defaultLocated.scale = (_a2 = this.config.initialScale) != null ? _a2 : 1);
|
|
538
536
|
const { positionX, positionY, scale: newScale } = calculateTransform(__spreadValues({
|
|
539
537
|
node,
|
|
540
538
|
container: this.container,
|
|
541
|
-
transform:
|
|
542
|
-
|
|
539
|
+
transform: {
|
|
540
|
+
previousScale: defaultLocated.scale,
|
|
541
|
+
scale: defaultLocated.scale,
|
|
542
|
+
positionX: (_b = this.config.initialPositionX) != null ? _b : 0,
|
|
543
|
+
positionY: (_c = this.config.initialPositionY) != null ? _c : 0
|
|
544
|
+
}
|
|
543
545
|
}, defaultLocated));
|
|
544
546
|
const newTransform = {
|
|
545
|
-
previousScale:
|
|
547
|
+
previousScale: defaultLocated.scale,
|
|
546
548
|
scale: newScale,
|
|
547
549
|
positionX: -positionX,
|
|
548
550
|
positionY: -positionY
|
|
549
551
|
};
|
|
550
|
-
this.transform = newTransform;
|
|
551
552
|
return newTransform;
|
|
552
553
|
}
|
|
553
554
|
isCanvasEvent(e) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Element, BasePlugin, DataManager, DOMElement, Engine, PluginData } from '@knotx/core';
|
|
2
2
|
import { InferParamsFromSchema } from '@knotx/decorators';
|
|
3
|
-
import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef } from '@knotx/react-zoom-pan-pinch';
|
|
3
|
+
import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef, ZoomPanPinch } from '@knotx/react-zoom-pan-pinch';
|
|
4
4
|
import { MouseEvent, ReactNode } from 'react';
|
|
5
5
|
|
|
6
6
|
interface CanvasTransformState {
|
|
@@ -23,7 +23,6 @@ interface ScrollNodeIntoViewOptions {
|
|
|
23
23
|
y: number;
|
|
24
24
|
};
|
|
25
25
|
animationTime?: number;
|
|
26
|
-
limitToBounds?: boolean;
|
|
27
26
|
}
|
|
28
27
|
interface DefaultLocatedOptions extends Omit<ScrollNodeIntoViewOptions, 'nodeId'> {
|
|
29
28
|
nodeId?: string | null;
|
|
@@ -86,6 +85,7 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
|
86
85
|
private config;
|
|
87
86
|
name: "canvas";
|
|
88
87
|
ref: ReactZoomPanPinchContentRef | null;
|
|
88
|
+
zoomPanPinch: ZoomPanPinch;
|
|
89
89
|
dataManager: DataManager<CanvasDataType, "canvas">;
|
|
90
90
|
transform: CanvasTransformState;
|
|
91
91
|
rootElement: DOMElement | null;
|
|
@@ -189,6 +189,7 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
|
189
189
|
children: ReactNode;
|
|
190
190
|
}): JSX.Element;
|
|
191
191
|
init(config: CanvasConfig): void;
|
|
192
|
+
private createZoomPanPinch;
|
|
192
193
|
private groupLayers;
|
|
193
194
|
private getDefaultTransform;
|
|
194
195
|
private onClick;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Element, BasePlugin, DataManager, DOMElement, Engine, PluginData } from '@knotx/core';
|
|
2
2
|
import { InferParamsFromSchema } from '@knotx/decorators';
|
|
3
|
-
import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef } from '@knotx/react-zoom-pan-pinch';
|
|
3
|
+
import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef, ZoomPanPinch } from '@knotx/react-zoom-pan-pinch';
|
|
4
4
|
import { MouseEvent, ReactNode } from 'react';
|
|
5
5
|
|
|
6
6
|
interface CanvasTransformState {
|
|
@@ -23,7 +23,6 @@ interface ScrollNodeIntoViewOptions {
|
|
|
23
23
|
y: number;
|
|
24
24
|
};
|
|
25
25
|
animationTime?: number;
|
|
26
|
-
limitToBounds?: boolean;
|
|
27
26
|
}
|
|
28
27
|
interface DefaultLocatedOptions extends Omit<ScrollNodeIntoViewOptions, 'nodeId'> {
|
|
29
28
|
nodeId?: string | null;
|
|
@@ -86,6 +85,7 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
|
86
85
|
private config;
|
|
87
86
|
name: "canvas";
|
|
88
87
|
ref: ReactZoomPanPinchContentRef | null;
|
|
88
|
+
zoomPanPinch: ZoomPanPinch;
|
|
89
89
|
dataManager: DataManager<CanvasDataType, "canvas">;
|
|
90
90
|
transform: CanvasTransformState;
|
|
91
91
|
rootElement: DOMElement | null;
|
|
@@ -189,6 +189,7 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
|
189
189
|
children: ReactNode;
|
|
190
190
|
}): JSX.Element;
|
|
191
191
|
init(config: CanvasConfig): void;
|
|
192
|
+
private createZoomPanPinch;
|
|
192
193
|
private groupLayers;
|
|
193
194
|
private getDefaultTransform;
|
|
194
195
|
private onClick;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Element, BasePlugin, DataManager, DOMElement, Engine, PluginData } from '@knotx/core';
|
|
2
2
|
import { InferParamsFromSchema } from '@knotx/decorators';
|
|
3
|
-
import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef } from '@knotx/react-zoom-pan-pinch';
|
|
3
|
+
import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef, ZoomPanPinch } from '@knotx/react-zoom-pan-pinch';
|
|
4
4
|
import { MouseEvent, ReactNode } from 'react';
|
|
5
5
|
|
|
6
6
|
interface CanvasTransformState {
|
|
@@ -23,7 +23,6 @@ interface ScrollNodeIntoViewOptions {
|
|
|
23
23
|
y: number;
|
|
24
24
|
};
|
|
25
25
|
animationTime?: number;
|
|
26
|
-
limitToBounds?: boolean;
|
|
27
26
|
}
|
|
28
27
|
interface DefaultLocatedOptions extends Omit<ScrollNodeIntoViewOptions, 'nodeId'> {
|
|
29
28
|
nodeId?: string | null;
|
|
@@ -86,6 +85,7 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
|
86
85
|
private config;
|
|
87
86
|
name: "canvas";
|
|
88
87
|
ref: ReactZoomPanPinchContentRef | null;
|
|
88
|
+
zoomPanPinch: ZoomPanPinch;
|
|
89
89
|
dataManager: DataManager<CanvasDataType, "canvas">;
|
|
90
90
|
transform: CanvasTransformState;
|
|
91
91
|
rootElement: DOMElement | null;
|
|
@@ -189,6 +189,7 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
|
|
|
189
189
|
children: ReactNode;
|
|
190
190
|
}): JSX.Element;
|
|
191
191
|
init(config: CanvasConfig): void;
|
|
192
|
+
private createZoomPanPinch;
|
|
192
193
|
private groupLayers;
|
|
193
194
|
private getDefaultTransform;
|
|
194
195
|
private onClick;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsxs, jsx } from '@knotx/jsx/jsx-runtime';
|
|
2
2
|
import { Layer, DataManager, use, DOMElement, bem, BasePlugin, InteractionPriority } from '@knotx/core';
|
|
3
3
|
import { register, inject, tool, layer, OnInit } from '@knotx/decorators';
|
|
4
|
-
import { TransformWrapper, TransformComponent } from '@knotx/react-zoom-pan-pinch';
|
|
4
|
+
import { TransformWrapper, TransformComponent, ZoomPanPinch } from '@knotx/react-zoom-pan-pinch';
|
|
5
5
|
import { isEqual, merge } from 'lodash-es';
|
|
6
|
-
import {
|
|
6
|
+
import { useReducer, useMemo, useLayoutEffect, Fragment } from 'react';
|
|
7
7
|
|
|
8
8
|
function calculateTransform({
|
|
9
9
|
node,
|
|
@@ -12,9 +12,7 @@ function calculateTransform({
|
|
|
12
12
|
scale,
|
|
13
13
|
block = "nearest",
|
|
14
14
|
inline = "nearest",
|
|
15
|
-
offset = 0
|
|
16
|
-
contentSize,
|
|
17
|
-
limitToBounds
|
|
15
|
+
offset = 0
|
|
18
16
|
}) {
|
|
19
17
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
20
18
|
const nodeX = (_a = node == null ? void 0 : node.position.x) != null ? _a : 0;
|
|
@@ -73,14 +71,6 @@ function calculateTransform({
|
|
|
73
71
|
break;
|
|
74
72
|
}
|
|
75
73
|
}
|
|
76
|
-
if (limitToBounds && contentSize) {
|
|
77
|
-
if (contentSize.width * scale < viewportWidth) {
|
|
78
|
-
positionX = contentSize.width / 2 * scale - viewportWidth / 2;
|
|
79
|
-
}
|
|
80
|
-
if (contentSize.height * scale < viewportHeight) {
|
|
81
|
-
positionY = contentSize.height / 2 * scale - viewportHeight / 2;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
74
|
return {
|
|
85
75
|
scale,
|
|
86
76
|
positionX,
|
|
@@ -207,6 +197,7 @@ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")],
|
|
|
207
197
|
__publicField(this, "config");
|
|
208
198
|
__publicField(this, "name", "canvas");
|
|
209
199
|
__publicField(this, "ref", null);
|
|
200
|
+
__publicField(this, "zoomPanPinch");
|
|
210
201
|
__publicField(this, "dataManager", new DataManager(this.name));
|
|
211
202
|
__publicField(this, "transform", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
|
|
212
203
|
__publicField(this, "rootElement", __runInitializers(_init, 12, this, null)), __runInitializers(_init, 15, this);
|
|
@@ -337,7 +328,7 @@ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")],
|
|
|
337
328
|
deltaY = -maxSpeed * factor;
|
|
338
329
|
}
|
|
339
330
|
if (deltaX !== 0 || deltaY !== 0) {
|
|
340
|
-
const currentState = this.
|
|
331
|
+
const currentState = this.zoomPanPinch.transformState;
|
|
341
332
|
const newPositionX = currentState.positionX + deltaX;
|
|
342
333
|
const newPositionY = currentState.positionY + deltaY;
|
|
343
334
|
this.ref.setTransform(newPositionX, newPositionY, currentState.scale, 0);
|
|
@@ -355,12 +346,10 @@ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")],
|
|
|
355
346
|
node,
|
|
356
347
|
container: this.container,
|
|
357
348
|
transform: this.transform,
|
|
358
|
-
contentSize: this.contentSize,
|
|
359
349
|
scale,
|
|
360
350
|
block,
|
|
361
351
|
inline,
|
|
362
|
-
offset
|
|
363
|
-
limitToBounds: false
|
|
352
|
+
offset
|
|
364
353
|
});
|
|
365
354
|
(_a2 = this.ref) == null ? void 0 : _a2.setTransform(-positionX, -positionY, newScale, animationTime);
|
|
366
355
|
}
|
|
@@ -383,7 +372,9 @@ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")],
|
|
|
383
372
|
render({ children } = { children: null }) {
|
|
384
373
|
var _a2, _b;
|
|
385
374
|
const contentSize = use(() => this.contentSize);
|
|
386
|
-
|
|
375
|
+
if (!this.zoomPanPinch) {
|
|
376
|
+
this.createZoomPanPinch();
|
|
377
|
+
}
|
|
387
378
|
const [transformRef, setTransformRef] = useReducer((_, ref) => {
|
|
388
379
|
var _a3;
|
|
389
380
|
const dom = ref.instance.wrapperComponent;
|
|
@@ -440,9 +431,7 @@ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")],
|
|
|
440
431
|
TransformWrapper,
|
|
441
432
|
__spreadProps(__spreadValues({}, this.config), {
|
|
442
433
|
ref: setTransformRef,
|
|
443
|
-
|
|
444
|
-
initialPositionY: defaultTransform.positionY,
|
|
445
|
-
initialScale: defaultTransform.scale,
|
|
434
|
+
initialInstance: this.zoomPanPinch,
|
|
446
435
|
children: [
|
|
447
436
|
/* @__PURE__ */ jsx(Fragment, { children: fixedLayers }),
|
|
448
437
|
/* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
@@ -509,6 +498,14 @@ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")],
|
|
|
509
498
|
})
|
|
510
499
|
);
|
|
511
500
|
}
|
|
501
|
+
createZoomPanPinch() {
|
|
502
|
+
const defaultTransform = this.getDefaultTransform();
|
|
503
|
+
this.zoomPanPinch = new ZoomPanPinch(this.config);
|
|
504
|
+
if (defaultTransform) {
|
|
505
|
+
this.zoomPanPinch.calcNewPosition(defaultTransform.positionX, defaultTransform.positionY);
|
|
506
|
+
}
|
|
507
|
+
this.transform = __spreadValues({}, this.zoomPanPinch.transformState);
|
|
508
|
+
}
|
|
512
509
|
groupLayers(children) {
|
|
513
510
|
const fixedLayers = [];
|
|
514
511
|
const childrenLayers = [];
|
|
@@ -525,27 +522,31 @@ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")],
|
|
|
525
522
|
return [fixedLayers, childrenLayers];
|
|
526
523
|
}
|
|
527
524
|
getDefaultTransform() {
|
|
525
|
+
var _a2, _b, _c;
|
|
528
526
|
const defaultLocated = __spreadValues({}, this.config.defaultLocated);
|
|
529
|
-
if (!(defaultLocated == null ? void 0 : defaultLocated.nodeId)
|
|
530
|
-
return
|
|
527
|
+
if (!(defaultLocated == null ? void 0 : defaultLocated.nodeId)) {
|
|
528
|
+
return void 0;
|
|
531
529
|
}
|
|
532
530
|
const node = defaultLocated.nodeId ? this.getNode({ id: defaultLocated.nodeId }) : void 0;
|
|
533
531
|
defaultLocated.inline || (defaultLocated.inline = "center");
|
|
534
532
|
defaultLocated.block || (defaultLocated.block = "center");
|
|
535
|
-
defaultLocated.scale || (defaultLocated.scale = this.
|
|
533
|
+
defaultLocated.scale || (defaultLocated.scale = (_a2 = this.config.initialScale) != null ? _a2 : 1);
|
|
536
534
|
const { positionX, positionY, scale: newScale } = calculateTransform(__spreadValues({
|
|
537
535
|
node,
|
|
538
536
|
container: this.container,
|
|
539
|
-
transform:
|
|
540
|
-
|
|
537
|
+
transform: {
|
|
538
|
+
previousScale: defaultLocated.scale,
|
|
539
|
+
scale: defaultLocated.scale,
|
|
540
|
+
positionX: (_b = this.config.initialPositionX) != null ? _b : 0,
|
|
541
|
+
positionY: (_c = this.config.initialPositionY) != null ? _c : 0
|
|
542
|
+
}
|
|
541
543
|
}, defaultLocated));
|
|
542
544
|
const newTransform = {
|
|
543
|
-
previousScale:
|
|
545
|
+
previousScale: defaultLocated.scale,
|
|
544
546
|
scale: newScale,
|
|
545
547
|
positionX: -positionX,
|
|
546
548
|
positionY: -positionY
|
|
547
549
|
};
|
|
548
|
-
this.transform = newTransform;
|
|
549
550
|
return newTransform;
|
|
550
551
|
}
|
|
551
552
|
isCanvasEvent(e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knotx/plugins-canvas",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.13",
|
|
4
4
|
"description": "Canvas Plugin for Knotx",
|
|
5
5
|
"author": "boenfu",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,25 +29,25 @@
|
|
|
29
29
|
],
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"react": ">=17.0.0",
|
|
32
|
-
"@knotx/jsx": "0.4.
|
|
33
|
-
"@knotx/plugins-history": "0.4.
|
|
32
|
+
"@knotx/jsx": "0.4.13",
|
|
33
|
+
"@knotx/plugins-history": "0.4.13"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@knotx/react-zoom-pan-pinch": "^3.9.
|
|
36
|
+
"@knotx/react-zoom-pan-pinch": "^3.9.10",
|
|
37
37
|
"lodash-es": "^4.17.21",
|
|
38
38
|
"rxjs": "^7.8.1",
|
|
39
|
-
"@knotx/core": "0.4.
|
|
40
|
-
"@knotx/decorators": "0.4.
|
|
39
|
+
"@knotx/core": "0.4.13",
|
|
40
|
+
"@knotx/decorators": "0.4.13"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/lodash-es": "^4.17.12",
|
|
44
44
|
"@types/react": "^17.0.0",
|
|
45
45
|
"react": "^17.0.0",
|
|
46
|
-
"@knotx/build-config": "0.4.
|
|
47
|
-
"@knotx/eslint-config": "0.4.
|
|
48
|
-
"@knotx/jsx": "0.4.
|
|
49
|
-
"@knotx/plugins-history": "0.4.
|
|
50
|
-
"@knotx/typescript-config": "0.4.
|
|
46
|
+
"@knotx/build-config": "0.4.13",
|
|
47
|
+
"@knotx/eslint-config": "0.4.13",
|
|
48
|
+
"@knotx/jsx": "0.4.13",
|
|
49
|
+
"@knotx/plugins-history": "0.4.13",
|
|
50
|
+
"@knotx/typescript-config": "0.4.13"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"build": "unbuild",
|