sequential-workflow-designer 0.24.7 → 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/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;
@@ -1498,13 +1583,13 @@
1498
1583
  const x = view.joinX - cfg.size / 2;
1499
1584
  const endY = cfg.size + view.height;
1500
1585
  const iconSize = parentPlaceIndicator ? cfg.folderIconSize : cfg.defaultIconSize;
1501
- const startCircle = createCircle(parentPlaceIndicator ? cfg.folderIconD : cfg.startIconD, cfg.size, iconSize);
1586
+ const startCircle = createCircle('start', parentPlaceIndicator ? cfg.folderIconD : cfg.startIconD, cfg.size, iconSize);
1502
1587
  Dom.translate(startCircle, x, 0);
1503
1588
  g.appendChild(startCircle);
1504
1589
  Dom.translate(view.g, 0, cfg.size);
1505
- const endCircle = createCircle(parentPlaceIndicator ? cfg.folderIconD : cfg.stopIconD, cfg.size, iconSize);
1506
- Dom.translate(endCircle, x, endY);
1507
- g.appendChild(endCircle);
1590
+ const stopCircle = createCircle('stop', parentPlaceIndicator ? cfg.folderIconD : cfg.stopIconD, cfg.size, iconSize);
1591
+ Dom.translate(stopCircle, x, endY);
1592
+ g.appendChild(stopCircle);
1508
1593
  let startPlaceholder = null;
1509
1594
  let endPlaceholder = null;
1510
1595
  if (parentPlaceIndicator) {
@@ -1532,7 +1617,10 @@
1532
1617
  (_a = this.g.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.g);
1533
1618
  }
1534
1619
  }
1535
- function createCircle(d, size, iconSize) {
1620
+ function createCircle(classSuffix, d, size, iconSize) {
1621
+ const g = Dom.svg('g', {
1622
+ class: 'sqd-root-start-stop-' + classSuffix
1623
+ });
1536
1624
  const r = size / 2;
1537
1625
  const circle = Dom.svg('circle', {
1538
1626
  class: 'sqd-root-start-stop-circle',
@@ -1540,7 +1628,6 @@
1540
1628
  cy: r,
1541
1629
  r: r
1542
1630
  });
1543
- const g = Dom.svg('g');
1544
1631
  g.appendChild(circle);
1545
1632
  const offset = (size - iconSize) / 2;
1546
1633
  const icon = Icons.appendPath(g, 'sqd-root-start-stop-icon', d, iconSize);
@@ -1575,7 +1662,7 @@
1575
1662
  }
1576
1663
  }
1577
1664
 
1578
- const defaultConfiguration$5 = {
1665
+ const defaultConfiguration$6 = {
1579
1666
  view: {
1580
1667
  size: 30,
1581
1668
  defaultIconSize: 22,
@@ -1587,7 +1674,7 @@
1587
1674
  };
1588
1675
  class StartStopRootComponentExtension {
1589
1676
  static create(configuration) {
1590
- return new StartStopRootComponentExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$5);
1677
+ return new StartStopRootComponentExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$6);
1591
1678
  }
1592
1679
  constructor(configuration) {
1593
1680
  this.configuration = configuration;
@@ -1821,15 +1908,15 @@
1821
1908
  };
1822
1909
 
1823
1910
  class CenteredViewportCalculator {
1824
- static center(margin, canvasSize, rootComponentSize) {
1911
+ static center(padding, canvasSize, rootComponentSize) {
1825
1912
  if (canvasSize.x === 0 || canvasSize.y === 0) {
1826
1913
  return {
1827
1914
  position: new Vector(0, 0),
1828
1915
  scale: 1
1829
1916
  };
1830
1917
  }
1831
- const canvasSafeWidth = Math.max(canvasSize.x - margin * 2, 0);
1832
- 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);
1833
1920
  const scale = Math.min(Math.min(canvasSafeWidth / rootComponentSize.x, canvasSafeHeight / rootComponentSize.y), 1);
1834
1921
  const width = rootComponentSize.x * scale;
1835
1922
  const height = rootComponentSize.y * scale;
@@ -1840,7 +1927,7 @@
1840
1927
  scale
1841
1928
  };
1842
1929
  }
1843
- static focusOnComponent(canvasSize, viewport, componentPosition, componentSize) {
1930
+ static getFocusedOnComponent(canvasSize, viewport, componentPosition, componentSize) {
1844
1931
  const realPosition = viewport.position.divideByScalar(viewport.scale).subtract(componentPosition.divideByScalar(viewport.scale));
1845
1932
  const componentOffset = componentSize.divideByScalar(2);
1846
1933
  const position = realPosition.add(canvasSize.divideByScalar(2)).subtract(componentOffset);
@@ -1848,6 +1935,24 @@
1848
1935
  }
1849
1936
  }
1850
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
+
1851
1956
  class NextQuantifiedNumber {
1852
1957
  constructor(values) {
1853
1958
  this.values = values;
@@ -1874,142 +1979,68 @@
1874
1979
  next: this.values[index]
1875
1980
  };
1876
1981
  }
1877
- }
1878
-
1879
- 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];
1880
- const MAX_DELTA_Y$1 = 16;
1881
- const quantifiedScale = new NextQuantifiedNumber(SCALES);
1882
- class QuantifiedScaleViewportCalculator {
1883
- static zoom(current, direction) {
1884
- const nextScale = quantifiedScale.next(current.scale, direction);
1885
- return {
1886
- position: current.position,
1887
- scale: nextScale.next
1888
- };
1889
- }
1890
- static zoomByWheel(current, e, canvasPosition) {
1891
- if (e.deltaY === 0) {
1892
- return null;
1893
- }
1894
- const nextScale = quantifiedScale.next(current.scale, e.deltaY < 0);
1895
- let scale;
1896
- const absDeltaY = Math.abs(e.deltaY);
1897
- if (absDeltaY < MAX_DELTA_Y$1) {
1898
- const fraction = absDeltaY / MAX_DELTA_Y$1;
1899
- const step = nextScale.next - nextScale.current;
1900
- scale = current.scale + step * fraction;
1901
- }
1902
- else {
1903
- scale = nextScale.next;
1904
- }
1905
- const mousePoint = new Vector(e.pageX, e.pageY).subtract(canvasPosition);
1906
- // The real point is point on canvas with no scale.
1907
- const mouseRealPoint = mousePoint.divideByScalar(current.scale).subtract(current.position.divideByScalar(current.scale));
1908
- const position = mouseRealPoint.multiplyByScalar(-scale).add(mousePoint);
1909
- 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);
1910
1986
  }
1911
1987
  }
1912
1988
 
1913
- class ClassicWheelController {
1914
- static create(api) {
1915
- return new ClassicWheelController(api);
1916
- }
1917
- constructor(api) {
1918
- this.api = api;
1919
- }
1920
- onWheel(e) {
1921
- const viewport = this.api.getViewport();
1922
- const canvasPosition = this.api.getCanvasPosition();
1923
- const newViewport = QuantifiedScaleViewportCalculator.zoomByWheel(viewport, e, canvasPosition);
1924
- if (newViewport) {
1925
- this.api.setViewport(newViewport);
1926
- }
1927
- }
1928
- }
1929
-
1930
- class ClassicWheelControllerExtension {
1931
- constructor() {
1932
- this.create = ClassicWheelController.create;
1933
- }
1934
- }
1935
-
1936
- function animate(interval, handler) {
1937
- const iv = setInterval(tick, 15);
1938
- const startTime = Date.now();
1939
- const anim = {
1940
- isAlive: true,
1941
- stop: () => {
1942
- anim.isAlive = false;
1943
- clearInterval(iv);
1944
- }
1945
- };
1946
- function tick() {
1947
- const progress = Math.min((Date.now() - startTime) / interval, 1);
1948
- handler(progress);
1949
- if (progress === 1) {
1950
- anim.stop();
1951
- }
1952
- }
1953
- return anim;
1954
- }
1955
-
1956
- class ViewportAnimator {
1957
- constructor(api) {
1958
- this.api = api;
1959
- }
1960
- execute(target) {
1961
- if (this.animation && this.animation.isAlive) {
1962
- this.animation.stop();
1963
- }
1964
- const viewport = this.api.getViewport();
1965
- const startPosition = viewport.position;
1966
- const startScale = viewport.scale;
1967
- const deltaPosition = startPosition.subtract(target.position);
1968
- const deltaScale = startScale - target.scale;
1969
- this.animation = animate(150, progress => {
1970
- const newScale = startScale - deltaScale * progress;
1971
- this.api.setViewport({
1972
- position: startPosition.subtract(deltaPosition.multiplyByScalar(progress)),
1973
- scale: newScale
1974
- });
1975
- });
1976
- }
1977
- }
1978
-
1979
- 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
+ };
1980
1994
  class DefaultViewportController {
1981
- static create(api) {
1982
- 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);
1983
1999
  }
1984
- constructor(api) {
2000
+ constructor(smoothDeltaYLimit, nqn, api, padding) {
2001
+ this.smoothDeltaYLimit = smoothDeltaYLimit;
2002
+ this.nqn = nqn;
1985
2003
  this.api = api;
1986
- this.animator = new ViewportAnimator(this.api);
2004
+ this.padding = padding;
1987
2005
  }
1988
- setDefault() {
2006
+ getDefault() {
1989
2007
  const rootComponentSize = this.api.getRootComponentSize();
1990
2008
  const canvasSize = this.api.getCanvasSize();
1991
- const target = CenteredViewportCalculator.center(CENTER_MARGIN, canvasSize, rootComponentSize);
1992
- this.api.setViewport(target);
2009
+ return CenteredViewportCalculator.center(this.padding, canvasSize, rootComponentSize);
1993
2010
  }
1994
- zoom(direction) {
1995
- const viewport = this.api.getViewport();
1996
- const target = QuantifiedScaleViewportCalculator.zoom(viewport, direction);
1997
- 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;
1998
2021
  }
1999
- focusOnComponent(componentPosition, componentSize) {
2022
+ getFocusedOnComponent(componentPosition, componentSize) {
2000
2023
  const viewport = this.api.getViewport();
2001
2024
  const canvasSize = this.api.getCanvasSize();
2002
- const target = CenteredViewportCalculator.focusOnComponent(canvasSize, viewport, componentPosition, componentSize);
2003
- this.animateTo(target);
2025
+ return CenteredViewportCalculator.getFocusedOnComponent(canvasSize, viewport, componentPosition, componentSize);
2004
2026
  }
2005
- animateTo(viewport) {
2006
- 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);
2007
2032
  }
2008
2033
  }
2009
2034
 
2010
2035
  class DefaultViewportControllerExtension {
2011
- constructor() {
2012
- 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);
2013
2044
  }
2014
2045
  }
2015
2046
 
@@ -2352,10 +2383,26 @@
2352
2383
  return new Vector(touch.pageX, touch.pageY);
2353
2384
  }
2354
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');
2355
2402
  }
2356
2403
 
2357
- const notInitializedError = 'State is not initialized';
2358
- const nonPassiveOptions = {
2404
+ const notInitializedError$1 = 'State is not initialized';
2405
+ const nonPassiveOptions$1 = {
2359
2406
  passive: false
2360
2407
  };
2361
2408
  class BehaviorController {
@@ -2385,7 +2432,7 @@
2385
2432
  e.preventDefault();
2386
2433
  e.stopPropagation();
2387
2434
  if (!this.state) {
2388
- throw new Error(notInitializedError);
2435
+ throw new Error(notInitializedError$1);
2389
2436
  }
2390
2437
  const position = (_a = this.state.lastPosition) !== null && _a !== void 0 ? _a : this.state.startPosition;
2391
2438
  const element = this.dom.elementFromPoint(position.x, position.y);
@@ -2416,21 +2463,21 @@
2416
2463
  }
2417
2464
  bind(target) {
2418
2465
  target.addEventListener('mousemove', this.onMouseMove, false);
2419
- target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
2466
+ target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions$1);
2420
2467
  target.addEventListener('mouseup', this.onMouseUp, false);
2421
- target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
2422
- target.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
2468
+ target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions$1);
2469
+ target.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions$1);
2423
2470
  }
2424
2471
  unbind(target) {
2425
2472
  target.removeEventListener('mousemove', this.onMouseMove, false);
2426
- target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
2473
+ target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions$1);
2427
2474
  target.removeEventListener('mouseup', this.onMouseUp, false);
2428
- target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
2429
- target.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
2475
+ target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions$1);
2476
+ target.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions$1);
2430
2477
  }
2431
2478
  move(position) {
2432
2479
  if (!this.state) {
2433
- throw new Error(notInitializedError);
2480
+ throw new Error(notInitializedError$1);
2434
2481
  }
2435
2482
  this.state.lastPosition = position;
2436
2483
  const delta = this.state.startPosition.subtract(position);
@@ -2444,7 +2491,7 @@
2444
2491
  }
2445
2492
  stop(interrupt, element) {
2446
2493
  if (!this.state) {
2447
- throw new Error(notInitializedError);
2494
+ throw new Error(notInitializedError$1);
2448
2495
  }
2449
2496
  if (this.shadowRoot) {
2450
2497
  this.unbind(this.shadowRoot);
@@ -3019,20 +3066,26 @@
3019
3066
  getCanvasSize() {
3020
3067
  return new Vector(this.canvas.clientWidth, this.canvas.clientHeight);
3021
3068
  }
3022
- bindClick(handler) {
3069
+ bindMouseDown(handler) {
3023
3070
  this.canvas.addEventListener('mousedown', e => {
3024
3071
  e.preventDefault();
3025
3072
  handler(readMousePosition(e), e.target, e.button, e.altKey);
3026
3073
  }, false);
3074
+ }
3075
+ bindTouchStart(clickHandler, pinchToZoomHandler) {
3027
3076
  this.canvas.addEventListener('touchstart', e => {
3028
3077
  var _a;
3029
3078
  e.preventDefault();
3079
+ if (e.touches.length === 2) {
3080
+ pinchToZoomHandler(calculateFingerDistance(e), readFingerCenterPoint(e));
3081
+ return;
3082
+ }
3030
3083
  const clientPosition = readTouchClientPosition(e);
3031
3084
  const dom = (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : document;
3032
3085
  const element = dom.elementFromPoint(clientPosition.x, clientPosition.y);
3033
3086
  if (element) {
3034
3087
  const position = readTouchPosition(e);
3035
- handler(position, element, 0, false);
3088
+ clickHandler(position, element, 0, false);
3036
3089
  }
3037
3090
  }, listenerOptions$1);
3038
3091
  }
@@ -3409,17 +3462,96 @@
3409
3462
  }
3410
3463
  }
3411
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
+
3412
3543
  class Workspace {
3413
3544
  static create(parent, designerContext, api) {
3414
3545
  var _a;
3415
3546
  const view = WorkspaceView.create(parent, designerContext.componentContext);
3416
3547
  const clickBehaviorResolver = new ClickBehaviorResolver(designerContext);
3417
- 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);
3418
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)
3419
3551
  ? designerContext.services.contextMenu.createItemsProvider(designerContext.customActionController)
3420
3552
  : undefined);
3421
3553
  const contextMenuController = new ContextMenuController(designerContext.theme, designerContext.configuration, contextMenuItemsBuilder);
3422
- 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);
3423
3555
  setTimeout(() => {
3424
3556
  workspace.updateRootComponent();
3425
3557
  api.viewport.resetViewport();
@@ -3429,17 +3561,19 @@
3429
3561
  race(0, designerContext.state.onDefinitionChanged, designerContext.state.onSelectedStepIdChanged, designerContext.state.onFolderPathChanged).subscribe(r => {
3430
3562
  workspace.onStateChanged(r[0], r[1], r[2]);
3431
3563
  });
3432
- view.bindClick(workspace.onClick);
3564
+ view.bindMouseDown(workspace.onClick);
3565
+ view.bindTouchStart(workspace.onClick, workspace.onPinchToZoom);
3433
3566
  view.bindWheel(workspace.onWheel);
3434
3567
  view.bindContextMenu(workspace.onContextMenu);
3435
3568
  return workspace;
3436
3569
  }
3437
- constructor(view, definitionWalker, state, behaviorController, wheelController, contextMenuController, clickBehaviorResolver, viewportApi, services) {
3570
+ constructor(view, definitionWalker, state, behaviorController, wheelController, pinchToZoomController, contextMenuController, clickBehaviorResolver, viewportApi, services) {
3438
3571
  this.view = view;
3439
3572
  this.definitionWalker = definitionWalker;
3440
3573
  this.state = state;
3441
3574
  this.behaviorController = behaviorController;
3442
3575
  this.wheelController = wheelController;
3576
+ this.pinchToZoomController = pinchToZoomController;
3443
3577
  this.contextMenuController = contextMenuController;
3444
3578
  this.clickBehaviorResolver = clickBehaviorResolver;
3445
3579
  this.viewportApi = viewportApi;
@@ -3458,6 +3592,9 @@
3458
3592
  this.behaviorController.start(position, behavior);
3459
3593
  }
3460
3594
  };
3595
+ this.onPinchToZoom = (distance, centerPoint) => {
3596
+ this.pinchToZoomController.start(distance, centerPoint);
3597
+ };
3461
3598
  this.onWheel = (e) => {
3462
3599
  e.preventDefault();
3463
3600
  e.stopPropagation();
@@ -4581,7 +4718,7 @@
4581
4718
  services.regionComponentView = new DefaultRegionComponentViewExtension();
4582
4719
  }
4583
4720
  if (!services.viewportController) {
4584
- services.viewportController = new DefaultViewportControllerExtension();
4721
+ services.viewportController = DefaultViewportControllerExtension.create();
4585
4722
  }
4586
4723
  if (!services.grid) {
4587
4724
  services.grid = LineGridExtension.create();
@@ -4901,7 +5038,6 @@
4901
5038
  exports.ObjectCloner = ObjectCloner;
4902
5039
  exports.OutputView = OutputView;
4903
5040
  exports.PathBarApi = PathBarApi;
4904
- exports.QuantifiedScaleViewportCalculator = QuantifiedScaleViewportCalculator;
4905
5041
  exports.RectPlaceholder = RectPlaceholder;
4906
5042
  exports.RectPlaceholderView = RectPlaceholderView;
4907
5043
  exports.ServicesResolver = ServicesResolver;
@@ -4914,6 +5050,7 @@
4914
5050
  exports.Uid = Uid;
4915
5051
  exports.ValidationErrorBadgeExtension = ValidationErrorBadgeExtension;
4916
5052
  exports.Vector = Vector;
5053
+ exports.ViewportApi = ViewportApi;
4917
5054
  exports.WorkspaceApi = WorkspaceApi;
4918
5055
  exports.createContainerStepComponentViewFactory = createContainerStepComponentViewFactory;
4919
5056
  exports.createSwitchStepComponentViewFactory = createSwitchStepComponentViewFactory;