sequential-workflow-designer 0.24.8 → 0.25.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/README.md CHANGED
@@ -103,10 +103,10 @@ Add the below code to your head section in HTML document.
103
103
  ```html
104
104
  <head>
105
105
  ...
106
- <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.8/css/designer.css" rel="stylesheet">
107
- <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.8/css/designer-light.css" rel="stylesheet">
108
- <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.8/css/designer-dark.css" rel="stylesheet">
109
- <script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.8/dist/index.umd.js"></script>
106
+ <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.25.0/css/designer.css" rel="stylesheet">
107
+ <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.25.0/css/designer-light.css" rel="stylesheet">
108
+ <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.25.0/css/designer-dark.css" rel="stylesheet">
109
+ <script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.25.0/dist/index.umd.js"></script>
110
110
  ```
111
111
 
112
112
  Call the designer by:
package/dist/index.umd.js CHANGED
@@ -672,16 +672,92 @@
672
672
  }
673
673
  }
674
674
 
675
+ function animate(interval, handler) {
676
+ const iv = setInterval(tick, 15);
677
+ const startTime = Date.now();
678
+ const anim = {
679
+ isAlive: true,
680
+ stop: () => {
681
+ anim.isAlive = false;
682
+ clearInterval(iv);
683
+ }
684
+ };
685
+ function tick() {
686
+ const progress = Math.min((Date.now() - startTime) / interval, 1);
687
+ handler(progress);
688
+ if (progress === 1) {
689
+ anim.stop();
690
+ }
691
+ }
692
+ return anim;
693
+ }
694
+
695
+ class ViewportAnimator {
696
+ constructor(api) {
697
+ this.api = api;
698
+ }
699
+ execute(target) {
700
+ if (this.animation && this.animation.isAlive) {
701
+ this.animation.stop();
702
+ }
703
+ const viewport = this.api.getViewport();
704
+ const startPosition = viewport.position;
705
+ const startScale = viewport.scale;
706
+ const deltaPosition = startPosition.subtract(target.position);
707
+ const deltaScale = startScale - target.scale;
708
+ this.animation = animate(150, progress => {
709
+ const newScale = startScale - deltaScale * progress;
710
+ this.api.setViewport({
711
+ position: startPosition.subtract(deltaPosition.multiplyByScalar(progress)),
712
+ scale: newScale
713
+ });
714
+ });
715
+ }
716
+ }
717
+
718
+ class ZoomByWheelCalculator {
719
+ static calculate(controller, current, canvasPosition, e) {
720
+ if (e.deltaY === 0) {
721
+ return null;
722
+ }
723
+ const nextScale = controller.getNextScale(current.scale, e.deltaY < 0);
724
+ let scale;
725
+ const absDeltaY = Math.abs(e.deltaY);
726
+ if (absDeltaY < controller.smoothDeltaYLimit) {
727
+ const fraction = absDeltaY / controller.smoothDeltaYLimit;
728
+ const step = nextScale.next - nextScale.current;
729
+ scale = current.scale + step * fraction;
730
+ }
731
+ else {
732
+ scale = nextScale.next;
733
+ }
734
+ const mousePoint = new Vector(e.pageX, e.pageY).subtract(canvasPosition);
735
+ // The real point is point on canvas with no scale.
736
+ const mouseRealPoint = mousePoint.divideByScalar(current.scale).subtract(current.position.divideByScalar(current.scale));
737
+ const position = mouseRealPoint.multiplyByScalar(-scale).add(mousePoint);
738
+ return { position, scale };
739
+ }
740
+ }
741
+
675
742
  class ViewportApi {
676
- constructor(workspaceController, viewportController) {
743
+ constructor(workspaceController, viewportController, api) {
677
744
  this.workspaceController = workspaceController;
678
745
  this.viewportController = viewportController;
746
+ this.api = api;
747
+ this.animator = new ViewportAnimator(this.api);
748
+ }
749
+ limitScale(scale) {
750
+ return this.viewportController.limitScale(scale);
679
751
  }
680
752
  resetViewport() {
681
- this.viewportController.setDefault();
753
+ const defaultViewport = this.viewportController.getDefault();
754
+ this.api.setViewport(defaultViewport);
682
755
  }
683
756
  zoom(direction) {
684
- this.viewportController.zoom(direction);
757
+ const viewport = this.viewportController.getZoomed(direction);
758
+ if (viewport) {
759
+ this.api.setViewport(viewport);
760
+ }
685
761
  }
686
762
  moveViewportToStep(stepId) {
687
763
  const component = this.workspaceController.getComponentByStepId(stepId);
@@ -689,7 +765,16 @@
689
765
  const clientPosition = component.view.getClientPosition();
690
766
  const componentPosition = clientPosition.subtract(canvasPosition);
691
767
  const componentSize = new Vector(component.view.width, component.view.height);
692
- this.viewportController.focusOnComponent(componentPosition, componentSize);
768
+ const viewport = this.viewportController.getFocusedOnComponent(componentPosition, componentSize);
769
+ this.animator.execute(viewport);
770
+ }
771
+ handleWheelEvent(e) {
772
+ const viewport = this.api.getViewport();
773
+ const canvasPosition = this.api.getCanvasPosition();
774
+ const newViewport = ZoomByWheelCalculator.calculate(this.viewportController, viewport, canvasPosition, e);
775
+ if (newViewport) {
776
+ this.api.setViewport(newViewport);
777
+ }
693
778
  }
694
779
  }
695
780
 
@@ -728,7 +813,7 @@
728
813
  static create(context) {
729
814
  const workspace = new WorkspaceApi(context.state, context.workspaceController);
730
815
  const viewportController = context.services.viewportController.create(workspace);
731
- const viewport = new ViewportApi(context.workspaceController, viewportController);
816
+ const viewport = new ViewportApi(context.workspaceController, viewportController, workspace);
732
817
  const toolboxDataProvider = new ToolboxDataProvider(context.componentContext.iconProvider, context.i18n, context.configuration.toolbox);
733
818
  return new DesignerApi(context.configuration.shadowRoot, ControlBarApi.create(context.state, context.historyController, context.stateModifier, viewport), new ToolboxApi(context.state, context, context.behaviorController, toolboxDataProvider, context.configuration.uidGenerator), new EditorApi(context.state, context.definitionWalker, context.stateModifier), workspace, viewport, new PathBarApi(context.state, context.definitionWalker), context.definitionWalker, context.i18n);
734
819
  }
@@ -1173,7 +1258,7 @@
1173
1258
  }
1174
1259
  }
1175
1260
 
1176
- const defaultConfiguration$6 = {
1261
+ const defaultConfiguration$7 = {
1177
1262
  view: {
1178
1263
  size: 22,
1179
1264
  iconSize: 12
@@ -1181,7 +1266,7 @@
1181
1266
  };
1182
1267
  class ValidationErrorBadgeExtension {
1183
1268
  static create(configuration) {
1184
- return new ValidationErrorBadgeExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$6);
1269
+ return new ValidationErrorBadgeExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$7);
1185
1270
  }
1186
1271
  constructor(configuration) {
1187
1272
  this.configuration = configuration;
@@ -1577,7 +1662,7 @@
1577
1662
  }
1578
1663
  }
1579
1664
 
1580
- const defaultConfiguration$5 = {
1665
+ const defaultConfiguration$6 = {
1581
1666
  view: {
1582
1667
  size: 30,
1583
1668
  defaultIconSize: 22,
@@ -1589,7 +1674,7 @@
1589
1674
  };
1590
1675
  class StartStopRootComponentExtension {
1591
1676
  static create(configuration) {
1592
- return new StartStopRootComponentExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$5);
1677
+ return new StartStopRootComponentExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$6);
1593
1678
  }
1594
1679
  constructor(configuration) {
1595
1680
  this.configuration = configuration;
@@ -1823,15 +1908,15 @@
1823
1908
  };
1824
1909
 
1825
1910
  class CenteredViewportCalculator {
1826
- static center(margin, canvasSize, rootComponentSize) {
1911
+ static center(padding, canvasSize, rootComponentSize) {
1827
1912
  if (canvasSize.x === 0 || canvasSize.y === 0) {
1828
1913
  return {
1829
1914
  position: new Vector(0, 0),
1830
1915
  scale: 1
1831
1916
  };
1832
1917
  }
1833
- const canvasSafeWidth = Math.max(canvasSize.x - margin * 2, 0);
1834
- const canvasSafeHeight = Math.max(canvasSize.y - margin * 2, 0);
1918
+ const canvasSafeWidth = Math.max(canvasSize.x - padding * 2, 0);
1919
+ const canvasSafeHeight = Math.max(canvasSize.y - padding * 2, 0);
1835
1920
  const scale = Math.min(Math.min(canvasSafeWidth / rootComponentSize.x, canvasSafeHeight / rootComponentSize.y), 1);
1836
1921
  const width = rootComponentSize.x * scale;
1837
1922
  const height = rootComponentSize.y * scale;
@@ -1842,7 +1927,7 @@
1842
1927
  scale
1843
1928
  };
1844
1929
  }
1845
- static focusOnComponent(canvasSize, viewport, componentPosition, componentSize) {
1930
+ static getFocusedOnComponent(canvasSize, viewport, componentPosition, componentSize) {
1846
1931
  const realPosition = viewport.position.divideByScalar(viewport.scale).subtract(componentPosition.divideByScalar(viewport.scale));
1847
1932
  const componentOffset = componentSize.divideByScalar(2);
1848
1933
  const position = realPosition.add(canvasSize.divideByScalar(2)).subtract(componentOffset);
@@ -1850,6 +1935,24 @@
1850
1935
  }
1851
1936
  }
1852
1937
 
1938
+ class ClassicWheelController {
1939
+ static create(api) {
1940
+ return new ClassicWheelController(api);
1941
+ }
1942
+ constructor(api) {
1943
+ this.api = api;
1944
+ }
1945
+ onWheel(e) {
1946
+ this.api.handleWheelEvent(e);
1947
+ }
1948
+ }
1949
+
1950
+ class ClassicWheelControllerExtension {
1951
+ constructor() {
1952
+ this.create = ClassicWheelController.create;
1953
+ }
1954
+ }
1955
+
1853
1956
  class NextQuantifiedNumber {
1854
1957
  constructor(values) {
1855
1958
  this.values = values;
@@ -1876,142 +1979,68 @@
1876
1979
  next: this.values[index]
1877
1980
  };
1878
1981
  }
1879
- }
1880
-
1881
- const SCALES = [0.06, 0.08, 0.1, 0.12, 0.16, 0.2, 0.26, 0.32, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1];
1882
- const MAX_DELTA_Y$1 = 16;
1883
- const quantifiedScale = new NextQuantifiedNumber(SCALES);
1884
- class QuantifiedScaleViewportCalculator {
1885
- static zoom(current, direction) {
1886
- const nextScale = quantifiedScale.next(current.scale, direction);
1887
- return {
1888
- position: current.position,
1889
- scale: nextScale.next
1890
- };
1891
- }
1892
- static zoomByWheel(current, e, canvasPosition) {
1893
- if (e.deltaY === 0) {
1894
- return null;
1895
- }
1896
- const nextScale = quantifiedScale.next(current.scale, e.deltaY < 0);
1897
- let scale;
1898
- const absDeltaY = Math.abs(e.deltaY);
1899
- if (absDeltaY < MAX_DELTA_Y$1) {
1900
- const fraction = absDeltaY / MAX_DELTA_Y$1;
1901
- const step = nextScale.next - nextScale.current;
1902
- scale = current.scale + step * fraction;
1903
- }
1904
- else {
1905
- scale = nextScale.next;
1906
- }
1907
- const mousePoint = new Vector(e.pageX, e.pageY).subtract(canvasPosition);
1908
- // The real point is point on canvas with no scale.
1909
- const mouseRealPoint = mousePoint.divideByScalar(current.scale).subtract(current.position.divideByScalar(current.scale));
1910
- const position = mouseRealPoint.multiplyByScalar(-scale).add(mousePoint);
1911
- return { position, scale };
1982
+ limit(scale) {
1983
+ const min = this.values[0];
1984
+ const max = this.values[this.values.length - 1];
1985
+ return Math.min(Math.max(scale, min), max);
1912
1986
  }
1913
1987
  }
1914
1988
 
1915
- class ClassicWheelController {
1916
- static create(api) {
1917
- return new ClassicWheelController(api);
1918
- }
1919
- constructor(api) {
1920
- this.api = api;
1921
- }
1922
- onWheel(e) {
1923
- const viewport = this.api.getViewport();
1924
- const canvasPosition = this.api.getCanvasPosition();
1925
- const newViewport = QuantifiedScaleViewportCalculator.zoomByWheel(viewport, e, canvasPosition);
1926
- if (newViewport) {
1927
- this.api.setViewport(newViewport);
1928
- }
1929
- }
1930
- }
1931
-
1932
- class ClassicWheelControllerExtension {
1933
- constructor() {
1934
- this.create = ClassicWheelController.create;
1935
- }
1936
- }
1937
-
1938
- function animate(interval, handler) {
1939
- const iv = setInterval(tick, 15);
1940
- const startTime = Date.now();
1941
- const anim = {
1942
- isAlive: true,
1943
- stop: () => {
1944
- anim.isAlive = false;
1945
- clearInterval(iv);
1946
- }
1947
- };
1948
- function tick() {
1949
- const progress = Math.min((Date.now() - startTime) / interval, 1);
1950
- handler(progress);
1951
- if (progress === 1) {
1952
- anim.stop();
1953
- }
1954
- }
1955
- return anim;
1956
- }
1957
-
1958
- class ViewportAnimator {
1959
- constructor(api) {
1960
- this.api = api;
1961
- }
1962
- execute(target) {
1963
- if (this.animation && this.animation.isAlive) {
1964
- this.animation.stop();
1965
- }
1966
- const viewport = this.api.getViewport();
1967
- const startPosition = viewport.position;
1968
- const startScale = viewport.scale;
1969
- const deltaPosition = startPosition.subtract(target.position);
1970
- const deltaScale = startScale - target.scale;
1971
- this.animation = animate(150, progress => {
1972
- const newScale = startScale - deltaScale * progress;
1973
- this.api.setViewport({
1974
- position: startPosition.subtract(deltaPosition.multiplyByScalar(progress)),
1975
- scale: newScale
1976
- });
1977
- });
1978
- }
1979
- }
1980
-
1981
- const CENTER_MARGIN = 10;
1989
+ const defaultConfiguration$5 = {
1990
+ scales: [0.06, 0.08, 0.1, 0.12, 0.16, 0.2, 0.26, 0.32, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
1991
+ smoothDeltaYLimit: 16,
1992
+ padding: 10
1993
+ };
1982
1994
  class DefaultViewportController {
1983
- static create(api) {
1984
- return new DefaultViewportController(api);
1995
+ static create(api, configuration) {
1996
+ const config = configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$5;
1997
+ const nqn = new NextQuantifiedNumber(config.scales);
1998
+ return new DefaultViewportController(config.smoothDeltaYLimit, nqn, api, config.padding);
1985
1999
  }
1986
- constructor(api) {
2000
+ constructor(smoothDeltaYLimit, nqn, api, padding) {
2001
+ this.smoothDeltaYLimit = smoothDeltaYLimit;
2002
+ this.nqn = nqn;
1987
2003
  this.api = api;
1988
- this.animator = new ViewportAnimator(this.api);
2004
+ this.padding = padding;
1989
2005
  }
1990
- setDefault() {
2006
+ getDefault() {
1991
2007
  const rootComponentSize = this.api.getRootComponentSize();
1992
2008
  const canvasSize = this.api.getCanvasSize();
1993
- const target = CenteredViewportCalculator.center(CENTER_MARGIN, canvasSize, rootComponentSize);
1994
- this.api.setViewport(target);
2009
+ return CenteredViewportCalculator.center(this.padding, canvasSize, rootComponentSize);
1995
2010
  }
1996
- zoom(direction) {
1997
- const viewport = this.api.getViewport();
1998
- const target = QuantifiedScaleViewportCalculator.zoom(viewport, direction);
1999
- this.api.setViewport(target);
2011
+ getZoomed(direction) {
2012
+ const current = this.api.getViewport();
2013
+ const nextScale = this.nqn.next(current.scale, direction);
2014
+ if (nextScale) {
2015
+ return {
2016
+ position: current.position,
2017
+ scale: nextScale.next
2018
+ };
2019
+ }
2020
+ return null;
2000
2021
  }
2001
- focusOnComponent(componentPosition, componentSize) {
2022
+ getFocusedOnComponent(componentPosition, componentSize) {
2002
2023
  const viewport = this.api.getViewport();
2003
2024
  const canvasSize = this.api.getCanvasSize();
2004
- const target = CenteredViewportCalculator.focusOnComponent(canvasSize, viewport, componentPosition, componentSize);
2005
- this.animateTo(target);
2025
+ return CenteredViewportCalculator.getFocusedOnComponent(canvasSize, viewport, componentPosition, componentSize);
2006
2026
  }
2007
- animateTo(viewport) {
2008
- this.animator.execute(viewport);
2027
+ getNextScale(scale, direction) {
2028
+ return this.nqn.next(scale, direction);
2029
+ }
2030
+ limitScale(scale) {
2031
+ return this.nqn.limit(scale);
2009
2032
  }
2010
2033
  }
2011
2034
 
2012
2035
  class DefaultViewportControllerExtension {
2013
- constructor() {
2014
- this.create = DefaultViewportController.create;
2036
+ static create(configuration) {
2037
+ return new DefaultViewportControllerExtension(configuration);
2038
+ }
2039
+ constructor(configuration) {
2040
+ this.configuration = configuration;
2041
+ }
2042
+ create(api) {
2043
+ return DefaultViewportController.create(api, this.configuration);
2015
2044
  }
2016
2045
  }
2017
2046
 
@@ -2354,10 +2383,26 @@
2354
2383
  return new Vector(touch.pageX, touch.pageY);
2355
2384
  }
2356
2385
  throw new Error('Unknown touch position');
2386
+ }
2387
+ function calculateFingerDistance(e) {
2388
+ if (e.touches.length === 2) {
2389
+ const t0 = e.touches[0];
2390
+ const t1 = e.touches[1];
2391
+ return Math.hypot(t0.clientX - t1.clientX, t0.clientY - t1.clientY);
2392
+ }
2393
+ throw new Error('Cannot calculate finger distance');
2394
+ }
2395
+ function readFingerCenterPoint(e) {
2396
+ if (e.touches.length === 2) {
2397
+ const t0 = e.touches[0];
2398
+ const t1 = e.touches[1];
2399
+ return new Vector((t0.pageX + t1.pageX) / 2, (t0.pageY + t1.pageY) / 2);
2400
+ }
2401
+ throw new Error('Cannot calculate finger center point');
2357
2402
  }
2358
2403
 
2359
- const notInitializedError = 'State is not initialized';
2360
- const nonPassiveOptions = {
2404
+ const notInitializedError$1 = 'State is not initialized';
2405
+ const nonPassiveOptions$1 = {
2361
2406
  passive: false
2362
2407
  };
2363
2408
  class BehaviorController {
@@ -2387,7 +2432,7 @@
2387
2432
  e.preventDefault();
2388
2433
  e.stopPropagation();
2389
2434
  if (!this.state) {
2390
- throw new Error(notInitializedError);
2435
+ throw new Error(notInitializedError$1);
2391
2436
  }
2392
2437
  const position = (_a = this.state.lastPosition) !== null && _a !== void 0 ? _a : this.state.startPosition;
2393
2438
  const element = this.dom.elementFromPoint(position.x, position.y);
@@ -2418,21 +2463,21 @@
2418
2463
  }
2419
2464
  bind(target) {
2420
2465
  target.addEventListener('mousemove', this.onMouseMove, false);
2421
- target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
2466
+ target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions$1);
2422
2467
  target.addEventListener('mouseup', this.onMouseUp, false);
2423
- target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
2424
- target.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
2468
+ target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions$1);
2469
+ target.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions$1);
2425
2470
  }
2426
2471
  unbind(target) {
2427
2472
  target.removeEventListener('mousemove', this.onMouseMove, false);
2428
- target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
2473
+ target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions$1);
2429
2474
  target.removeEventListener('mouseup', this.onMouseUp, false);
2430
- target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
2431
- target.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
2475
+ target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions$1);
2476
+ target.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions$1);
2432
2477
  }
2433
2478
  move(position) {
2434
2479
  if (!this.state) {
2435
- throw new Error(notInitializedError);
2480
+ throw new Error(notInitializedError$1);
2436
2481
  }
2437
2482
  this.state.lastPosition = position;
2438
2483
  const delta = this.state.startPosition.subtract(position);
@@ -2446,7 +2491,7 @@
2446
2491
  }
2447
2492
  stop(interrupt, element) {
2448
2493
  if (!this.state) {
2449
- throw new Error(notInitializedError);
2494
+ throw new Error(notInitializedError$1);
2450
2495
  }
2451
2496
  if (this.shadowRoot) {
2452
2497
  this.unbind(this.shadowRoot);
@@ -3021,20 +3066,26 @@
3021
3066
  getCanvasSize() {
3022
3067
  return new Vector(this.canvas.clientWidth, this.canvas.clientHeight);
3023
3068
  }
3024
- bindClick(handler) {
3069
+ bindMouseDown(handler) {
3025
3070
  this.canvas.addEventListener('mousedown', e => {
3026
3071
  e.preventDefault();
3027
3072
  handler(readMousePosition(e), e.target, e.button, e.altKey);
3028
3073
  }, false);
3074
+ }
3075
+ bindTouchStart(clickHandler, pinchToZoomHandler) {
3029
3076
  this.canvas.addEventListener('touchstart', e => {
3030
3077
  var _a;
3031
3078
  e.preventDefault();
3079
+ if (e.touches.length === 2) {
3080
+ pinchToZoomHandler(calculateFingerDistance(e), readFingerCenterPoint(e));
3081
+ return;
3082
+ }
3032
3083
  const clientPosition = readTouchClientPosition(e);
3033
3084
  const dom = (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : document;
3034
3085
  const element = dom.elementFromPoint(clientPosition.x, clientPosition.y);
3035
3086
  if (element) {
3036
3087
  const position = readTouchPosition(e);
3037
- handler(position, element, 0, false);
3088
+ clickHandler(position, element, 0, false);
3038
3089
  }
3039
3090
  }, listenerOptions$1);
3040
3091
  }
@@ -3411,17 +3462,96 @@
3411
3462
  }
3412
3463
  }
3413
3464
 
3465
+ const nonPassiveOptions = {
3466
+ passive: false
3467
+ };
3468
+ const notInitializedError = 'State is not initialized';
3469
+ class PinchToZoomController {
3470
+ static create(workspaceApi, viewportApi, shadowRoot) {
3471
+ return new PinchToZoomController(workspaceApi, viewportApi, shadowRoot);
3472
+ }
3473
+ constructor(workspaceApi, viewportApi, shadowRoot) {
3474
+ this.workspaceApi = workspaceApi;
3475
+ this.viewportApi = viewportApi;
3476
+ this.shadowRoot = shadowRoot;
3477
+ this.state = null;
3478
+ this.onTouchMove = (e) => {
3479
+ e.preventDefault();
3480
+ if (!this.state) {
3481
+ throw new Error(notInitializedError);
3482
+ }
3483
+ const touchEvent = e;
3484
+ const distance = calculateFingerDistance(touchEvent);
3485
+ const centerPoint = readFingerCenterPoint(touchEvent);
3486
+ const deltaCenterPoint = centerPoint.subtract(this.state.lastCenterPoint);
3487
+ const scale = this.viewportApi.limitScale(this.state.startScale * (distance / this.state.startDistance));
3488
+ const zoomPoint = centerPoint.subtract(this.state.canvasPosition);
3489
+ const zoomRealPoint = zoomPoint
3490
+ .divideByScalar(this.state.lastViewport.scale)
3491
+ .subtract(this.state.lastViewport.position.divideByScalar(this.state.lastViewport.scale));
3492
+ const position = zoomRealPoint
3493
+ .multiplyByScalar(-scale)
3494
+ .add(zoomPoint)
3495
+ .add(deltaCenterPoint.divideByScalar(this.state.lastViewport.scale));
3496
+ const newViewport = {
3497
+ position,
3498
+ scale
3499
+ };
3500
+ this.workspaceApi.setViewport(newViewport);
3501
+ this.state.lastCenterPoint = centerPoint;
3502
+ this.state.lastViewport = newViewport;
3503
+ };
3504
+ this.onTouchEnd = (e) => {
3505
+ e.preventDefault();
3506
+ if (!this.state) {
3507
+ throw new Error(notInitializedError);
3508
+ }
3509
+ if (this.shadowRoot) {
3510
+ this.unbind(this.shadowRoot);
3511
+ }
3512
+ this.unbind(window);
3513
+ this.state = null;
3514
+ };
3515
+ }
3516
+ start(startDistance, centerPoint) {
3517
+ if (this.state) {
3518
+ throw new Error(`State is already initialized`);
3519
+ }
3520
+ if (this.shadowRoot) {
3521
+ this.bind(this.shadowRoot);
3522
+ }
3523
+ this.bind(window);
3524
+ const viewport = this.workspaceApi.getViewport();
3525
+ this.state = {
3526
+ canvasPosition: this.workspaceApi.getCanvasPosition(),
3527
+ startScale: viewport.scale,
3528
+ startDistance,
3529
+ lastViewport: viewport,
3530
+ lastCenterPoint: centerPoint
3531
+ };
3532
+ }
3533
+ bind(target) {
3534
+ target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
3535
+ target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
3536
+ }
3537
+ unbind(target) {
3538
+ target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
3539
+ target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
3540
+ }
3541
+ }
3542
+
3414
3543
  class Workspace {
3415
3544
  static create(parent, designerContext, api) {
3416
3545
  var _a;
3417
3546
  const view = WorkspaceView.create(parent, designerContext.componentContext);
3418
3547
  const clickBehaviorResolver = new ClickBehaviorResolver(designerContext);
3419
- const wheelController = designerContext.services.wheelController.create(api.workspace);
3548
+ const wheelController = designerContext.services.wheelController.create(api.viewport, api.workspace);
3549
+ const pinchToZoomController = PinchToZoomController.create(api.workspace, api.viewport, api.shadowRoot);
3420
3550
  const contextMenuItemsBuilder = new ContextMenuItemsBuilder(api.viewport, api.i18n, designerContext.stateModifier, designerContext.state, ((_a = designerContext.services.contextMenu) === null || _a === void 0 ? void 0 : _a.createItemsProvider)
3421
3551
  ? designerContext.services.contextMenu.createItemsProvider(designerContext.customActionController)
3422
3552
  : undefined);
3423
3553
  const contextMenuController = new ContextMenuController(designerContext.theme, designerContext.configuration, contextMenuItemsBuilder);
3424
- const workspace = new Workspace(view, designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, contextMenuController, clickBehaviorResolver, api.viewport, designerContext.services);
3554
+ const workspace = new Workspace(view, designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, pinchToZoomController, contextMenuController, clickBehaviorResolver, api.viewport, designerContext.services);
3425
3555
  setTimeout(() => {
3426
3556
  workspace.updateRootComponent();
3427
3557
  api.viewport.resetViewport();
@@ -3431,17 +3561,19 @@
3431
3561
  race(0, designerContext.state.onDefinitionChanged, designerContext.state.onSelectedStepIdChanged, designerContext.state.onFolderPathChanged).subscribe(r => {
3432
3562
  workspace.onStateChanged(r[0], r[1], r[2]);
3433
3563
  });
3434
- view.bindClick(workspace.onClick);
3564
+ view.bindMouseDown(workspace.onClick);
3565
+ view.bindTouchStart(workspace.onClick, workspace.onPinchToZoom);
3435
3566
  view.bindWheel(workspace.onWheel);
3436
3567
  view.bindContextMenu(workspace.onContextMenu);
3437
3568
  return workspace;
3438
3569
  }
3439
- constructor(view, definitionWalker, state, behaviorController, wheelController, contextMenuController, clickBehaviorResolver, viewportApi, services) {
3570
+ constructor(view, definitionWalker, state, behaviorController, wheelController, pinchToZoomController, contextMenuController, clickBehaviorResolver, viewportApi, services) {
3440
3571
  this.view = view;
3441
3572
  this.definitionWalker = definitionWalker;
3442
3573
  this.state = state;
3443
3574
  this.behaviorController = behaviorController;
3444
3575
  this.wheelController = wheelController;
3576
+ this.pinchToZoomController = pinchToZoomController;
3445
3577
  this.contextMenuController = contextMenuController;
3446
3578
  this.clickBehaviorResolver = clickBehaviorResolver;
3447
3579
  this.viewportApi = viewportApi;
@@ -3460,6 +3592,9 @@
3460
3592
  this.behaviorController.start(position, behavior);
3461
3593
  }
3462
3594
  };
3595
+ this.onPinchToZoom = (distance, centerPoint) => {
3596
+ this.pinchToZoomController.start(distance, centerPoint);
3597
+ };
3463
3598
  this.onWheel = (e) => {
3464
3599
  e.preventDefault();
3465
3600
  e.stopPropagation();
@@ -4583,7 +4718,7 @@
4583
4718
  services.regionComponentView = new DefaultRegionComponentViewExtension();
4584
4719
  }
4585
4720
  if (!services.viewportController) {
4586
- services.viewportController = new DefaultViewportControllerExtension();
4721
+ services.viewportController = DefaultViewportControllerExtension.create();
4587
4722
  }
4588
4723
  if (!services.grid) {
4589
4724
  services.grid = LineGridExtension.create();
@@ -4903,7 +5038,6 @@
4903
5038
  exports.ObjectCloner = ObjectCloner;
4904
5039
  exports.OutputView = OutputView;
4905
5040
  exports.PathBarApi = PathBarApi;
4906
- exports.QuantifiedScaleViewportCalculator = QuantifiedScaleViewportCalculator;
4907
5041
  exports.RectPlaceholder = RectPlaceholder;
4908
5042
  exports.RectPlaceholderView = RectPlaceholderView;
4909
5043
  exports.ServicesResolver = ServicesResolver;
@@ -4916,6 +5050,7 @@
4916
5050
  exports.Uid = Uid;
4917
5051
  exports.ValidationErrorBadgeExtension = ValidationErrorBadgeExtension;
4918
5052
  exports.Vector = Vector;
5053
+ exports.ViewportApi = ViewportApi;
4919
5054
  exports.WorkspaceApi = WorkspaceApi;
4920
5055
  exports.createContainerStepComponentViewFactory = createContainerStepComponentViewFactory;
4921
5056
  exports.createSwitchStepComponentViewFactory = createSwitchStepComponentViewFactory;