@knotx/plugins-canvas 0.4.1 → 0.4.3

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/index.cjs CHANGED
@@ -14,19 +14,21 @@ function calculateTransform({
14
14
  scale,
15
15
  block = "nearest",
16
16
  inline = "nearest",
17
- offset = 0
17
+ offset = 0,
18
+ contentSize,
19
+ limitToBounds
18
20
  }) {
19
- var _a, _b, _c, _d, _e, _f;
20
- const nodeX = node.position.x;
21
- const nodeY = node.position.y;
22
- const nodeWidth = (_b = (_a = node.measured) == null ? void 0 : _a.width) != null ? _b : 0;
23
- const nodeHeight = (_d = (_c = node.measured) == null ? void 0 : _c.height) != null ? _d : 0;
21
+ var _a, _b, _c, _d, _e, _f, _g, _h;
22
+ const nodeX = (_a = node == null ? void 0 : node.position.x) != null ? _a : 0;
23
+ const nodeY = (_b = node == null ? void 0 : node.position.y) != null ? _b : 0;
24
+ const nodeWidth = (_d = (_c = node == null ? void 0 : node.measured) == null ? void 0 : _c.width) != null ? _d : 0;
25
+ const nodeHeight = (_f = (_e = node == null ? void 0 : node.measured) == null ? void 0 : _e.height) != null ? _f : 0;
24
26
  const viewportWidth = container.width;
25
27
  const viewportHeight = container.height;
26
28
  let positionX = -transform.positionX;
27
29
  let positionY = -transform.positionY;
28
- const offsetX = typeof offset === "number" ? offset : (_e = offset.x) != null ? _e : 0;
29
- const offsetY = typeof offset === "number" ? offset : (_f = offset.y) != null ? _f : 0;
30
+ const offsetX = typeof offset === "number" ? offset : (_g = offset.x) != null ? _g : 0;
31
+ const offsetY = typeof offset === "number" ? offset : (_h = offset.y) != null ? _h : 0;
30
32
  switch (inline) {
31
33
  case "center":
32
34
  positionX = (nodeX + nodeWidth / 2) * scale - viewportWidth / 2;
@@ -73,6 +75,14 @@ function calculateTransform({
73
75
  break;
74
76
  }
75
77
  }
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
+ }
76
86
  return {
77
87
  scale,
78
88
  positionX,
@@ -148,8 +158,8 @@ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use
148
158
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
149
159
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
150
160
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
151
- var _init_dec, _render_dec, _setTransform_dec, _zoomOut_dec, _zoomIn_dec, _scrollNodeIntoView_dec, _removeListener_dec, _addListener_dec, _interaction_dec, _container_dec, _getNode_dec, _edgeScroll_dec, _updateContentSize_dec, _contentSize_dec, _transform_dec, _ref_dec, _a, _init;
152
- class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref")], _transform_dec = [decorators.register("transform")], _contentSize_dec = [decorators.register("contentSize")], _updateContentSize_dec = [decorators.register("updateContentSize")], _edgeScroll_dec = [decorators.register("edgeScroll")], _getNode_dec = [decorators.inject.getNode()], _container_dec = [decorators.inject.container()], _interaction_dec = [decorators.inject.interaction()], _addListener_dec = [decorators.register("addListener")], _removeListener_dec = [decorators.register("removeListener")], _scrollNodeIntoView_dec = [decorators.tool("Scroll node into view", {
161
+ var _init_dec, _render_dec, _resetTransform_dec, _setTransform_dec, _zoomOut_dec, _zoomIn_dec, _scrollNodeIntoView_dec, _removeListener_dec, _addListener_dec, _interaction_dec, _container_dec, _getNode_dec, _edgeScroll_dec, _updateContentSize_dec, _contentSize_dec, _rootElement_dec, _transform_dec, _a, _init;
162
+ class Canvas extends (_a = core.BasePlugin, _transform_dec = [decorators.register("transform")], _rootElement_dec = [decorators.register("rootElement")], _contentSize_dec = [decorators.register("contentSize")], _updateContentSize_dec = [decorators.register("updateContentSize")], _edgeScroll_dec = [decorators.register("edgeScroll")], _getNode_dec = [decorators.inject.getNode()], _container_dec = [decorators.inject.container()], _interaction_dec = [decorators.inject.interaction()], _addListener_dec = [decorators.register("addListener")], _removeListener_dec = [decorators.register("removeListener")], _scrollNodeIntoView_dec = [decorators.tool("Scroll node into view", {
153
163
  type: "object",
154
164
  properties: {
155
165
  nodeId: { type: "string" },
@@ -187,14 +197,20 @@ class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref
187
197
  scale: { type: "number" },
188
198
  animationTime: { type: "number" }
189
199
  }
200
+ })], _resetTransform_dec = [decorators.tool("Reset transform", {
201
+ type: "object",
202
+ properties: {
203
+ animationTime: { type: "number" }
204
+ }
190
205
  })], _render_dec = [decorators.layer(core.Layer.Canvas)], _init_dec = [decorators.OnInit], _a) {
191
206
  constructor() {
192
207
  super(...arguments);
193
208
  __runInitializers(_init, 5, this);
194
209
  __publicField(this, "config");
195
210
  __publicField(this, "name", "canvas");
196
- __publicField(this, "ref", __runInitializers(_init, 8, this, null)), __runInitializers(_init, 11, this);
197
- __publicField(this, "transform", __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);
211
+ __publicField(this, "ref", null);
212
+ __publicField(this, "transform", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
213
+ __publicField(this, "rootElement", __runInitializers(_init, 12, this, null)), __runInitializers(_init, 15, this);
198
214
  __publicField(this, "contentSize", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
199
215
  __publicField(this, "updateContentSize", __runInitializers(_init, 20, this, (contentSize) => {
200
216
  this.contentSize = contentSize;
@@ -280,10 +296,12 @@ class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref
280
296
  node,
281
297
  container: this.container,
282
298
  transform: this.transform,
299
+ contentSize: this.contentSize,
283
300
  scale,
284
301
  block,
285
302
  inline,
286
- offset
303
+ offset,
304
+ limitToBounds: false
287
305
  });
288
306
  (_a2 = this.ref) == null ? void 0 : _a2.setTransform(-positionX, -positionY, newScale, animationTime);
289
307
  }
@@ -299,24 +317,26 @@ class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref
299
317
  var _a2;
300
318
  (_a2 = this.ref) == null ? void 0 : _a2.setTransform(positionX != null ? positionX : this.transform.positionX, positionY != null ? positionY : this.transform.positionY, scale != null ? scale : this.transform.scale, animationTime);
301
319
  }
320
+ resetTransform({ animationTime } = {}) {
321
+ var _a2;
322
+ (_a2 = this.ref) == null ? void 0 : _a2.resetTransform(animationTime);
323
+ }
302
324
  render({ children } = { children: null }) {
303
325
  var _a2, _b, _c, _d;
304
326
  const defaultTransform = react.useMemo(() => {
305
- const defaultLocated = this.config.defaultLocated;
327
+ const defaultLocated = __spreadValues({}, this.config.defaultLocated);
306
328
  if (!(defaultLocated == null ? void 0 : defaultLocated.nodeId)) {
307
329
  return this.transform;
308
330
  }
309
331
  const node = this.getNode({ id: defaultLocated.nodeId });
310
- if (!node) {
311
- return this.transform;
312
- }
313
332
  defaultLocated.inline || (defaultLocated.inline = "center");
314
333
  defaultLocated.block || (defaultLocated.block = "center");
315
334
  defaultLocated.scale || (defaultLocated.scale = this.transform.scale);
316
335
  const { positionX, positionY, scale: newScale } = calculateTransform(__spreadValues({
317
336
  node,
318
337
  container: this.container,
319
- transform: this.transform
338
+ transform: this.transform,
339
+ contentSize: this.contentSize
320
340
  }, defaultLocated));
321
341
  const newTransform = {
322
342
  previousScale: this.transform.scale,
@@ -328,6 +348,11 @@ class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref
328
348
  return newTransform;
329
349
  }, []);
330
350
  const [transformRef, setTransformRef] = react.useReducer((_, ref) => {
351
+ var _a3;
352
+ const dom = ref.instance.wrapperComponent;
353
+ if (dom && ((_a3 = this.rootElement) == null ? void 0 : _a3.dom) !== dom) {
354
+ this.rootElement = core.DOMElement.fromDOM(dom);
355
+ }
331
356
  if (this.ref !== ref) {
332
357
  this.ref = ref;
333
358
  }
@@ -440,7 +465,7 @@ class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref
440
465
  /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: fixedLayers }),
441
466
  /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
442
467
  reactZoomPanPinch.TransformComponent,
443
- {
468
+ __spreadProps(__spreadValues({
444
469
  wrapperClass: core.bem(this.name, "wrapper"),
445
470
  wrapperStyle: {
446
471
  width: "100%",
@@ -459,9 +484,10 @@ class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref
459
484
  position: "relative",
460
485
  width: (_b = (_a2 = this.contentSize) == null ? void 0 : _a2.width) != null ? _b : "100%",
461
486
  height: (_d = (_c = this.contentSize) == null ? void 0 : _c.height) != null ? _d : "100%"
462
- },
487
+ }
488
+ }, { [`data-${this.pluginId}`]: "" }), {
463
489
  children: childrenLayers
464
- }
490
+ })
465
491
  ) })
466
492
  ]
467
493
  })
@@ -485,6 +511,7 @@ class Canvas extends (_a = core.BasePlugin, _ref_dec = [decorators.register("ref
485
511
  cancelAnimationFrame(this.edgeScrollAnimationFrame);
486
512
  this.edgeScrollAnimationFrame = null;
487
513
  }
514
+ this.rootElement = null;
488
515
  });
489
516
  }
490
517
  isCanvasEvent(e) {
@@ -496,10 +523,11 @@ __decorateElement(_init, 1, "scrollNodeIntoView", _scrollNodeIntoView_dec, Canva
496
523
  __decorateElement(_init, 1, "zoomIn", _zoomIn_dec, Canvas);
497
524
  __decorateElement(_init, 1, "zoomOut", _zoomOut_dec, Canvas);
498
525
  __decorateElement(_init, 1, "setTransform", _setTransform_dec, Canvas);
526
+ __decorateElement(_init, 1, "resetTransform", _resetTransform_dec, Canvas);
499
527
  __decorateElement(_init, 1, "render", _render_dec, Canvas);
500
528
  __decorateElement(_init, 1, "init", _init_dec, Canvas);
501
- __decorateElement(_init, 5, "ref", _ref_dec, Canvas);
502
529
  __decorateElement(_init, 5, "transform", _transform_dec, Canvas);
530
+ __decorateElement(_init, 5, "rootElement", _rootElement_dec, Canvas);
503
531
  __decorateElement(_init, 5, "contentSize", _contentSize_dec, Canvas);
504
532
  __decorateElement(_init, 5, "updateContentSize", _updateContentSize_dec, Canvas);
505
533
  __decorateElement(_init, 5, "edgeScroll", _edgeScroll_dec, Canvas);
package/dist/index.d.cts CHANGED
@@ -1,38 +1,45 @@
1
- import { BasePlugin, Engine } from '@knotx/core';
1
+ import { Element, BasePlugin, DOMElement, Engine } from '@knotx/core';
2
2
  import { InferParamsFromSchema } from '@knotx/decorators';
3
3
  import { MouseEvent, ReactNode } from 'react';
4
- import { ReactZoomPanPinchContentRef, ReactZoomPanPinchState, ReactZoomPanPinchProps } from 'react-zoom-pan-pinch';
4
+ import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef } from 'react-zoom-pan-pinch';
5
5
 
6
- type CanvasConfig = ReactZoomPanPinchProps & {
7
- defaultLocated?: {
8
- nodeId: string;
9
- scale?: number;
10
- block?: 'center' | 'end' | 'nearest' | 'start';
11
- inline?: 'center' | 'end' | 'nearest' | 'start';
12
- offset?: number | {
13
- x: number;
14
- y: number;
15
- };
16
- animationTime?: number;
17
- };
18
- };
6
+ interface CanvasTransformState {
7
+ previousScale: number;
8
+ scale: number;
9
+ positionX: number;
10
+ positionY: number;
11
+ }
19
12
  interface CanvasContentSize {
20
13
  width: number;
21
14
  height: number;
22
15
  }
23
- type CanvasTransformState = ReactZoomPanPinchState;
24
- type CanvasRef = ReactZoomPanPinchContentRef;
16
+ interface ScrollNodeIntoViewOptions {
17
+ nodeId: string;
18
+ scale?: number;
19
+ block?: 'center' | 'end' | 'nearest' | 'start';
20
+ inline?: 'center' | 'end' | 'nearest' | 'start';
21
+ offset?: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ animationTime?: number;
26
+ limitToBounds?: boolean;
27
+ }
25
28
  interface EdgeScrollConfig {
26
29
  enabled: boolean;
27
30
  edgeSize: number;
28
31
  maxSpeed: number;
29
32
  cornerSize?: number;
30
33
  }
34
+
35
+ type CanvasConfig = ReactZoomPanPinchProps & {
36
+ defaultLocated?: ScrollNodeIntoViewOptions;
37
+ };
31
38
  declare module '@knotx/core' {
32
39
  interface PluginData {
33
40
  canvas: {
34
- ref: CanvasRef | null;
35
41
  transform: CanvasTransformState;
42
+ rootElement: Element | null;
36
43
  contentSize: CanvasContentSize | undefined;
37
44
  updateContentSize: (contentSize: CanvasContentSize) => void;
38
45
  addListener: (event: CanvasEventType, listener: CanvasEventListener) => void;
@@ -45,17 +52,7 @@ declare module '@knotx/core' {
45
52
  }
46
53
  interface PluginTools {
47
54
  canvas: {
48
- scrollNodeIntoView: (params: {
49
- nodeId: string;
50
- scale?: number;
51
- block?: 'center' | 'end' | 'nearest' | 'start';
52
- inline?: 'center' | 'end' | 'nearest' | 'start';
53
- offset?: {
54
- x: number;
55
- y: number;
56
- };
57
- animationTime?: number;
58
- }) => void;
55
+ scrollNodeIntoView: (params: ScrollNodeIntoViewOptions) => void;
59
56
  zoomIn: (params: {
60
57
  step?: number;
61
58
  animationTime?: number;
@@ -70,6 +67,9 @@ declare module '@knotx/core' {
70
67
  scale: number;
71
68
  animationTime?: number;
72
69
  }) => void;
70
+ resetTransform: (params: {
71
+ animationTime?: number;
72
+ }) => void;
73
73
  };
74
74
  }
75
75
  }
@@ -78,8 +78,9 @@ type CanvasEventListener = (event: MouseEvent<HTMLElement>) => void;
78
78
  declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
79
79
  private config;
80
80
  name: "canvas";
81
- ref: CanvasRef | null;
81
+ ref: ReactZoomPanPinchContentRef | null;
82
82
  transform: CanvasTransformState;
83
+ rootElement: DOMElement | null;
83
84
  contentSize: CanvasContentSize | undefined;
84
85
  updateContentSize: (contentSize: CanvasContentSize) => void;
85
86
  edgeScroll: {
@@ -167,6 +168,14 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
167
168
  };
168
169
  };
169
170
  }>): void;
171
+ resetTransform({ animationTime }?: InferParamsFromSchema<{
172
+ type: 'object';
173
+ properties: {
174
+ animationTime: {
175
+ type: 'number';
176
+ };
177
+ };
178
+ }>): void;
170
179
  private handleEdgeScroll;
171
180
  render({ children }?: {
172
181
  children: ReactNode;
@@ -175,4 +184,4 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
175
184
  private isCanvasEvent;
176
185
  }
177
186
 
178
- export { Canvas, type CanvasConfig, type CanvasContentSize, type CanvasEventListener, type CanvasEventType, type CanvasRef, type CanvasTransformState, type EdgeScrollConfig };
187
+ export { Canvas, type CanvasConfig, type CanvasContentSize, type CanvasEventListener, type CanvasEventType, type CanvasTransformState, type EdgeScrollConfig, type ScrollNodeIntoViewOptions };
package/dist/index.d.mts CHANGED
@@ -1,38 +1,45 @@
1
- import { BasePlugin, Engine } from '@knotx/core';
1
+ import { Element, BasePlugin, DOMElement, Engine } from '@knotx/core';
2
2
  import { InferParamsFromSchema } from '@knotx/decorators';
3
3
  import { MouseEvent, ReactNode } from 'react';
4
- import { ReactZoomPanPinchContentRef, ReactZoomPanPinchState, ReactZoomPanPinchProps } from 'react-zoom-pan-pinch';
4
+ import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef } from 'react-zoom-pan-pinch';
5
5
 
6
- type CanvasConfig = ReactZoomPanPinchProps & {
7
- defaultLocated?: {
8
- nodeId: string;
9
- scale?: number;
10
- block?: 'center' | 'end' | 'nearest' | 'start';
11
- inline?: 'center' | 'end' | 'nearest' | 'start';
12
- offset?: number | {
13
- x: number;
14
- y: number;
15
- };
16
- animationTime?: number;
17
- };
18
- };
6
+ interface CanvasTransformState {
7
+ previousScale: number;
8
+ scale: number;
9
+ positionX: number;
10
+ positionY: number;
11
+ }
19
12
  interface CanvasContentSize {
20
13
  width: number;
21
14
  height: number;
22
15
  }
23
- type CanvasTransformState = ReactZoomPanPinchState;
24
- type CanvasRef = ReactZoomPanPinchContentRef;
16
+ interface ScrollNodeIntoViewOptions {
17
+ nodeId: string;
18
+ scale?: number;
19
+ block?: 'center' | 'end' | 'nearest' | 'start';
20
+ inline?: 'center' | 'end' | 'nearest' | 'start';
21
+ offset?: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ animationTime?: number;
26
+ limitToBounds?: boolean;
27
+ }
25
28
  interface EdgeScrollConfig {
26
29
  enabled: boolean;
27
30
  edgeSize: number;
28
31
  maxSpeed: number;
29
32
  cornerSize?: number;
30
33
  }
34
+
35
+ type CanvasConfig = ReactZoomPanPinchProps & {
36
+ defaultLocated?: ScrollNodeIntoViewOptions;
37
+ };
31
38
  declare module '@knotx/core' {
32
39
  interface PluginData {
33
40
  canvas: {
34
- ref: CanvasRef | null;
35
41
  transform: CanvasTransformState;
42
+ rootElement: Element | null;
36
43
  contentSize: CanvasContentSize | undefined;
37
44
  updateContentSize: (contentSize: CanvasContentSize) => void;
38
45
  addListener: (event: CanvasEventType, listener: CanvasEventListener) => void;
@@ -45,17 +52,7 @@ declare module '@knotx/core' {
45
52
  }
46
53
  interface PluginTools {
47
54
  canvas: {
48
- scrollNodeIntoView: (params: {
49
- nodeId: string;
50
- scale?: number;
51
- block?: 'center' | 'end' | 'nearest' | 'start';
52
- inline?: 'center' | 'end' | 'nearest' | 'start';
53
- offset?: {
54
- x: number;
55
- y: number;
56
- };
57
- animationTime?: number;
58
- }) => void;
55
+ scrollNodeIntoView: (params: ScrollNodeIntoViewOptions) => void;
59
56
  zoomIn: (params: {
60
57
  step?: number;
61
58
  animationTime?: number;
@@ -70,6 +67,9 @@ declare module '@knotx/core' {
70
67
  scale: number;
71
68
  animationTime?: number;
72
69
  }) => void;
70
+ resetTransform: (params: {
71
+ animationTime?: number;
72
+ }) => void;
73
73
  };
74
74
  }
75
75
  }
@@ -78,8 +78,9 @@ type CanvasEventListener = (event: MouseEvent<HTMLElement>) => void;
78
78
  declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
79
79
  private config;
80
80
  name: "canvas";
81
- ref: CanvasRef | null;
81
+ ref: ReactZoomPanPinchContentRef | null;
82
82
  transform: CanvasTransformState;
83
+ rootElement: DOMElement | null;
83
84
  contentSize: CanvasContentSize | undefined;
84
85
  updateContentSize: (contentSize: CanvasContentSize) => void;
85
86
  edgeScroll: {
@@ -167,6 +168,14 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
167
168
  };
168
169
  };
169
170
  }>): void;
171
+ resetTransform({ animationTime }?: InferParamsFromSchema<{
172
+ type: 'object';
173
+ properties: {
174
+ animationTime: {
175
+ type: 'number';
176
+ };
177
+ };
178
+ }>): void;
170
179
  private handleEdgeScroll;
171
180
  render({ children }?: {
172
181
  children: ReactNode;
@@ -175,4 +184,4 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
175
184
  private isCanvasEvent;
176
185
  }
177
186
 
178
- export { Canvas, type CanvasConfig, type CanvasContentSize, type CanvasEventListener, type CanvasEventType, type CanvasRef, type CanvasTransformState, type EdgeScrollConfig };
187
+ export { Canvas, type CanvasConfig, type CanvasContentSize, type CanvasEventListener, type CanvasEventType, type CanvasTransformState, type EdgeScrollConfig, type ScrollNodeIntoViewOptions };
package/dist/index.d.ts CHANGED
@@ -1,38 +1,45 @@
1
- import { BasePlugin, Engine } from '@knotx/core';
1
+ import { Element, BasePlugin, DOMElement, Engine } from '@knotx/core';
2
2
  import { InferParamsFromSchema } from '@knotx/decorators';
3
3
  import { MouseEvent, ReactNode } from 'react';
4
- import { ReactZoomPanPinchContentRef, ReactZoomPanPinchState, ReactZoomPanPinchProps } from 'react-zoom-pan-pinch';
4
+ import { ReactZoomPanPinchProps, ReactZoomPanPinchContentRef } from 'react-zoom-pan-pinch';
5
5
 
6
- type CanvasConfig = ReactZoomPanPinchProps & {
7
- defaultLocated?: {
8
- nodeId: string;
9
- scale?: number;
10
- block?: 'center' | 'end' | 'nearest' | 'start';
11
- inline?: 'center' | 'end' | 'nearest' | 'start';
12
- offset?: number | {
13
- x: number;
14
- y: number;
15
- };
16
- animationTime?: number;
17
- };
18
- };
6
+ interface CanvasTransformState {
7
+ previousScale: number;
8
+ scale: number;
9
+ positionX: number;
10
+ positionY: number;
11
+ }
19
12
  interface CanvasContentSize {
20
13
  width: number;
21
14
  height: number;
22
15
  }
23
- type CanvasTransformState = ReactZoomPanPinchState;
24
- type CanvasRef = ReactZoomPanPinchContentRef;
16
+ interface ScrollNodeIntoViewOptions {
17
+ nodeId: string;
18
+ scale?: number;
19
+ block?: 'center' | 'end' | 'nearest' | 'start';
20
+ inline?: 'center' | 'end' | 'nearest' | 'start';
21
+ offset?: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ animationTime?: number;
26
+ limitToBounds?: boolean;
27
+ }
25
28
  interface EdgeScrollConfig {
26
29
  enabled: boolean;
27
30
  edgeSize: number;
28
31
  maxSpeed: number;
29
32
  cornerSize?: number;
30
33
  }
34
+
35
+ type CanvasConfig = ReactZoomPanPinchProps & {
36
+ defaultLocated?: ScrollNodeIntoViewOptions;
37
+ };
31
38
  declare module '@knotx/core' {
32
39
  interface PluginData {
33
40
  canvas: {
34
- ref: CanvasRef | null;
35
41
  transform: CanvasTransformState;
42
+ rootElement: Element | null;
36
43
  contentSize: CanvasContentSize | undefined;
37
44
  updateContentSize: (contentSize: CanvasContentSize) => void;
38
45
  addListener: (event: CanvasEventType, listener: CanvasEventListener) => void;
@@ -45,17 +52,7 @@ declare module '@knotx/core' {
45
52
  }
46
53
  interface PluginTools {
47
54
  canvas: {
48
- scrollNodeIntoView: (params: {
49
- nodeId: string;
50
- scale?: number;
51
- block?: 'center' | 'end' | 'nearest' | 'start';
52
- inline?: 'center' | 'end' | 'nearest' | 'start';
53
- offset?: {
54
- x: number;
55
- y: number;
56
- };
57
- animationTime?: number;
58
- }) => void;
55
+ scrollNodeIntoView: (params: ScrollNodeIntoViewOptions) => void;
59
56
  zoomIn: (params: {
60
57
  step?: number;
61
58
  animationTime?: number;
@@ -70,6 +67,9 @@ declare module '@knotx/core' {
70
67
  scale: number;
71
68
  animationTime?: number;
72
69
  }) => void;
70
+ resetTransform: (params: {
71
+ animationTime?: number;
72
+ }) => void;
73
73
  };
74
74
  }
75
75
  }
@@ -78,8 +78,9 @@ type CanvasEventListener = (event: MouseEvent<HTMLElement>) => void;
78
78
  declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
79
79
  private config;
80
80
  name: "canvas";
81
- ref: CanvasRef | null;
81
+ ref: ReactZoomPanPinchContentRef | null;
82
82
  transform: CanvasTransformState;
83
+ rootElement: DOMElement | null;
83
84
  contentSize: CanvasContentSize | undefined;
84
85
  updateContentSize: (contentSize: CanvasContentSize) => void;
85
86
  edgeScroll: {
@@ -167,6 +168,14 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
167
168
  };
168
169
  };
169
170
  }>): void;
171
+ resetTransform({ animationTime }?: InferParamsFromSchema<{
172
+ type: 'object';
173
+ properties: {
174
+ animationTime: {
175
+ type: 'number';
176
+ };
177
+ };
178
+ }>): void;
170
179
  private handleEdgeScroll;
171
180
  render({ children }?: {
172
181
  children: ReactNode;
@@ -175,4 +184,4 @@ declare class Canvas extends BasePlugin<'canvas', CanvasConfig> {
175
184
  private isCanvasEvent;
176
185
  }
177
186
 
178
- export { Canvas, type CanvasConfig, type CanvasContentSize, type CanvasEventListener, type CanvasEventType, type CanvasRef, type CanvasTransformState, type EdgeScrollConfig };
187
+ export { Canvas, type CanvasConfig, type CanvasContentSize, type CanvasEventListener, type CanvasEventType, type CanvasTransformState, type EdgeScrollConfig, type ScrollNodeIntoViewOptions };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from '@knotx/jsx/jsx-runtime';
2
- import { Layer, InteractionPriority, bem, BasePlugin } from '@knotx/core';
2
+ import { Layer, DOMElement, InteractionPriority, bem, BasePlugin } from '@knotx/core';
3
3
  import { register, inject, tool, layer, OnInit } from '@knotx/decorators';
4
4
  import { isEqual, merge } from 'lodash-es';
5
5
  import { useMemo, useReducer, useLayoutEffect, useCallback, Fragment } from 'react';
@@ -12,19 +12,21 @@ function calculateTransform({
12
12
  scale,
13
13
  block = "nearest",
14
14
  inline = "nearest",
15
- offset = 0
15
+ offset = 0,
16
+ contentSize,
17
+ limitToBounds
16
18
  }) {
17
- var _a, _b, _c, _d, _e, _f;
18
- const nodeX = node.position.x;
19
- const nodeY = node.position.y;
20
- const nodeWidth = (_b = (_a = node.measured) == null ? void 0 : _a.width) != null ? _b : 0;
21
- const nodeHeight = (_d = (_c = node.measured) == null ? void 0 : _c.height) != null ? _d : 0;
19
+ var _a, _b, _c, _d, _e, _f, _g, _h;
20
+ const nodeX = (_a = node == null ? void 0 : node.position.x) != null ? _a : 0;
21
+ const nodeY = (_b = node == null ? void 0 : node.position.y) != null ? _b : 0;
22
+ const nodeWidth = (_d = (_c = node == null ? void 0 : node.measured) == null ? void 0 : _c.width) != null ? _d : 0;
23
+ const nodeHeight = (_f = (_e = node == null ? void 0 : node.measured) == null ? void 0 : _e.height) != null ? _f : 0;
22
24
  const viewportWidth = container.width;
23
25
  const viewportHeight = container.height;
24
26
  let positionX = -transform.positionX;
25
27
  let positionY = -transform.positionY;
26
- const offsetX = typeof offset === "number" ? offset : (_e = offset.x) != null ? _e : 0;
27
- const offsetY = typeof offset === "number" ? offset : (_f = offset.y) != null ? _f : 0;
28
+ const offsetX = typeof offset === "number" ? offset : (_g = offset.x) != null ? _g : 0;
29
+ const offsetY = typeof offset === "number" ? offset : (_h = offset.y) != null ? _h : 0;
28
30
  switch (inline) {
29
31
  case "center":
30
32
  positionX = (nodeX + nodeWidth / 2) * scale - viewportWidth / 2;
@@ -71,6 +73,14 @@ function calculateTransform({
71
73
  break;
72
74
  }
73
75
  }
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
+ }
74
84
  return {
75
85
  scale,
76
86
  positionX,
@@ -146,8 +156,8 @@ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use
146
156
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
147
157
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
148
158
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
149
- var _init_dec, _render_dec, _setTransform_dec, _zoomOut_dec, _zoomIn_dec, _scrollNodeIntoView_dec, _removeListener_dec, _addListener_dec, _interaction_dec, _container_dec, _getNode_dec, _edgeScroll_dec, _updateContentSize_dec, _contentSize_dec, _transform_dec, _ref_dec, _a, _init;
150
- class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_dec = [register("transform")], _contentSize_dec = [register("contentSize")], _updateContentSize_dec = [register("updateContentSize")], _edgeScroll_dec = [register("edgeScroll")], _getNode_dec = [inject.getNode()], _container_dec = [inject.container()], _interaction_dec = [inject.interaction()], _addListener_dec = [register("addListener")], _removeListener_dec = [register("removeListener")], _scrollNodeIntoView_dec = [tool("Scroll node into view", {
159
+ var _init_dec, _render_dec, _resetTransform_dec, _setTransform_dec, _zoomOut_dec, _zoomIn_dec, _scrollNodeIntoView_dec, _removeListener_dec, _addListener_dec, _interaction_dec, _container_dec, _getNode_dec, _edgeScroll_dec, _updateContentSize_dec, _contentSize_dec, _rootElement_dec, _transform_dec, _a, _init;
160
+ class Canvas extends (_a = BasePlugin, _transform_dec = [register("transform")], _rootElement_dec = [register("rootElement")], _contentSize_dec = [register("contentSize")], _updateContentSize_dec = [register("updateContentSize")], _edgeScroll_dec = [register("edgeScroll")], _getNode_dec = [inject.getNode()], _container_dec = [inject.container()], _interaction_dec = [inject.interaction()], _addListener_dec = [register("addListener")], _removeListener_dec = [register("removeListener")], _scrollNodeIntoView_dec = [tool("Scroll node into view", {
151
161
  type: "object",
152
162
  properties: {
153
163
  nodeId: { type: "string" },
@@ -185,14 +195,20 @@ class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_
185
195
  scale: { type: "number" },
186
196
  animationTime: { type: "number" }
187
197
  }
198
+ })], _resetTransform_dec = [tool("Reset transform", {
199
+ type: "object",
200
+ properties: {
201
+ animationTime: { type: "number" }
202
+ }
188
203
  })], _render_dec = [layer(Layer.Canvas)], _init_dec = [OnInit], _a) {
189
204
  constructor() {
190
205
  super(...arguments);
191
206
  __runInitializers(_init, 5, this);
192
207
  __publicField(this, "config");
193
208
  __publicField(this, "name", "canvas");
194
- __publicField(this, "ref", __runInitializers(_init, 8, this, null)), __runInitializers(_init, 11, this);
195
- __publicField(this, "transform", __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);
209
+ __publicField(this, "ref", null);
210
+ __publicField(this, "transform", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
211
+ __publicField(this, "rootElement", __runInitializers(_init, 12, this, null)), __runInitializers(_init, 15, this);
196
212
  __publicField(this, "contentSize", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
197
213
  __publicField(this, "updateContentSize", __runInitializers(_init, 20, this, (contentSize) => {
198
214
  this.contentSize = contentSize;
@@ -278,10 +294,12 @@ class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_
278
294
  node,
279
295
  container: this.container,
280
296
  transform: this.transform,
297
+ contentSize: this.contentSize,
281
298
  scale,
282
299
  block,
283
300
  inline,
284
- offset
301
+ offset,
302
+ limitToBounds: false
285
303
  });
286
304
  (_a2 = this.ref) == null ? void 0 : _a2.setTransform(-positionX, -positionY, newScale, animationTime);
287
305
  }
@@ -297,24 +315,26 @@ class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_
297
315
  var _a2;
298
316
  (_a2 = this.ref) == null ? void 0 : _a2.setTransform(positionX != null ? positionX : this.transform.positionX, positionY != null ? positionY : this.transform.positionY, scale != null ? scale : this.transform.scale, animationTime);
299
317
  }
318
+ resetTransform({ animationTime } = {}) {
319
+ var _a2;
320
+ (_a2 = this.ref) == null ? void 0 : _a2.resetTransform(animationTime);
321
+ }
300
322
  render({ children } = { children: null }) {
301
323
  var _a2, _b, _c, _d;
302
324
  const defaultTransform = useMemo(() => {
303
- const defaultLocated = this.config.defaultLocated;
325
+ const defaultLocated = __spreadValues({}, this.config.defaultLocated);
304
326
  if (!(defaultLocated == null ? void 0 : defaultLocated.nodeId)) {
305
327
  return this.transform;
306
328
  }
307
329
  const node = this.getNode({ id: defaultLocated.nodeId });
308
- if (!node) {
309
- return this.transform;
310
- }
311
330
  defaultLocated.inline || (defaultLocated.inline = "center");
312
331
  defaultLocated.block || (defaultLocated.block = "center");
313
332
  defaultLocated.scale || (defaultLocated.scale = this.transform.scale);
314
333
  const { positionX, positionY, scale: newScale } = calculateTransform(__spreadValues({
315
334
  node,
316
335
  container: this.container,
317
- transform: this.transform
336
+ transform: this.transform,
337
+ contentSize: this.contentSize
318
338
  }, defaultLocated));
319
339
  const newTransform = {
320
340
  previousScale: this.transform.scale,
@@ -326,6 +346,11 @@ class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_
326
346
  return newTransform;
327
347
  }, []);
328
348
  const [transformRef, setTransformRef] = useReducer((_, ref) => {
349
+ var _a3;
350
+ const dom = ref.instance.wrapperComponent;
351
+ if (dom && ((_a3 = this.rootElement) == null ? void 0 : _a3.dom) !== dom) {
352
+ this.rootElement = DOMElement.fromDOM(dom);
353
+ }
329
354
  if (this.ref !== ref) {
330
355
  this.ref = ref;
331
356
  }
@@ -438,7 +463,7 @@ class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_
438
463
  /* @__PURE__ */ jsx(Fragment, { children: fixedLayers }),
439
464
  /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
440
465
  TransformComponent,
441
- {
466
+ __spreadProps(__spreadValues({
442
467
  wrapperClass: bem(this.name, "wrapper"),
443
468
  wrapperStyle: {
444
469
  width: "100%",
@@ -457,9 +482,10 @@ class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_
457
482
  position: "relative",
458
483
  width: (_b = (_a2 = this.contentSize) == null ? void 0 : _a2.width) != null ? _b : "100%",
459
484
  height: (_d = (_c = this.contentSize) == null ? void 0 : _c.height) != null ? _d : "100%"
460
- },
485
+ }
486
+ }, { [`data-${this.pluginId}`]: "" }), {
461
487
  children: childrenLayers
462
- }
488
+ })
463
489
  ) })
464
490
  ]
465
491
  })
@@ -483,6 +509,7 @@ class Canvas extends (_a = BasePlugin, _ref_dec = [register("ref")], _transform_
483
509
  cancelAnimationFrame(this.edgeScrollAnimationFrame);
484
510
  this.edgeScrollAnimationFrame = null;
485
511
  }
512
+ this.rootElement = null;
486
513
  });
487
514
  }
488
515
  isCanvasEvent(e) {
@@ -494,10 +521,11 @@ __decorateElement(_init, 1, "scrollNodeIntoView", _scrollNodeIntoView_dec, Canva
494
521
  __decorateElement(_init, 1, "zoomIn", _zoomIn_dec, Canvas);
495
522
  __decorateElement(_init, 1, "zoomOut", _zoomOut_dec, Canvas);
496
523
  __decorateElement(_init, 1, "setTransform", _setTransform_dec, Canvas);
524
+ __decorateElement(_init, 1, "resetTransform", _resetTransform_dec, Canvas);
497
525
  __decorateElement(_init, 1, "render", _render_dec, Canvas);
498
526
  __decorateElement(_init, 1, "init", _init_dec, Canvas);
499
- __decorateElement(_init, 5, "ref", _ref_dec, Canvas);
500
527
  __decorateElement(_init, 5, "transform", _transform_dec, Canvas);
528
+ __decorateElement(_init, 5, "rootElement", _rootElement_dec, Canvas);
501
529
  __decorateElement(_init, 5, "contentSize", _contentSize_dec, Canvas);
502
530
  __decorateElement(_init, 5, "updateContentSize", _updateContentSize_dec, Canvas);
503
531
  __decorateElement(_init, 5, "edgeScroll", _edgeScroll_dec, Canvas);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knotx/plugins-canvas",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Canvas Plugin for Knotx",
5
5
  "author": "boenfu",
6
6
  "license": "MIT",
@@ -29,23 +29,23 @@
29
29
  ],
30
30
  "peerDependencies": {
31
31
  "react": ">=17.0.0",
32
- "@knotx/jsx": "0.4.1"
32
+ "@knotx/jsx": "0.4.3"
33
33
  },
34
34
  "dependencies": {
35
35
  "lodash-es": "^4.17.21",
36
36
  "react-zoom-pan-pinch": "^3.7.0",
37
37
  "rxjs": "^7.8.1",
38
- "@knotx/core": "0.4.1",
39
- "@knotx/decorators": "0.4.1"
38
+ "@knotx/core": "0.4.3",
39
+ "@knotx/decorators": "0.4.3"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/lodash-es": "^4.17.12",
43
43
  "@types/react": "^17.0.0",
44
44
  "react": "^17.0.0",
45
- "@knotx/build-config": "0.4.1",
46
- "@knotx/eslint-config": "0.4.1",
47
- "@knotx/jsx": "0.4.1",
48
- "@knotx/typescript-config": "0.4.1"
45
+ "@knotx/build-config": "0.4.3",
46
+ "@knotx/eslint-config": "0.4.3",
47
+ "@knotx/jsx": "0.4.3",
48
+ "@knotx/typescript-config": "0.4.3"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "unbuild",