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/lib/cjs/index.cjs CHANGED
@@ -670,16 +670,92 @@ class ToolboxDataProvider {
670
670
  }
671
671
  }
672
672
 
673
+ function animate(interval, handler) {
674
+ const iv = setInterval(tick, 15);
675
+ const startTime = Date.now();
676
+ const anim = {
677
+ isAlive: true,
678
+ stop: () => {
679
+ anim.isAlive = false;
680
+ clearInterval(iv);
681
+ }
682
+ };
683
+ function tick() {
684
+ const progress = Math.min((Date.now() - startTime) / interval, 1);
685
+ handler(progress);
686
+ if (progress === 1) {
687
+ anim.stop();
688
+ }
689
+ }
690
+ return anim;
691
+ }
692
+
693
+ class ViewportAnimator {
694
+ constructor(api) {
695
+ this.api = api;
696
+ }
697
+ execute(target) {
698
+ if (this.animation && this.animation.isAlive) {
699
+ this.animation.stop();
700
+ }
701
+ const viewport = this.api.getViewport();
702
+ const startPosition = viewport.position;
703
+ const startScale = viewport.scale;
704
+ const deltaPosition = startPosition.subtract(target.position);
705
+ const deltaScale = startScale - target.scale;
706
+ this.animation = animate(150, progress => {
707
+ const newScale = startScale - deltaScale * progress;
708
+ this.api.setViewport({
709
+ position: startPosition.subtract(deltaPosition.multiplyByScalar(progress)),
710
+ scale: newScale
711
+ });
712
+ });
713
+ }
714
+ }
715
+
716
+ class ZoomByWheelCalculator {
717
+ static calculate(controller, current, canvasPosition, e) {
718
+ if (e.deltaY === 0) {
719
+ return null;
720
+ }
721
+ const nextScale = controller.getNextScale(current.scale, e.deltaY < 0);
722
+ let scale;
723
+ const absDeltaY = Math.abs(e.deltaY);
724
+ if (absDeltaY < controller.smoothDeltaYLimit) {
725
+ const fraction = absDeltaY / controller.smoothDeltaYLimit;
726
+ const step = nextScale.next - nextScale.current;
727
+ scale = current.scale + step * fraction;
728
+ }
729
+ else {
730
+ scale = nextScale.next;
731
+ }
732
+ const mousePoint = new Vector(e.pageX, e.pageY).subtract(canvasPosition);
733
+ // The real point is point on canvas with no scale.
734
+ const mouseRealPoint = mousePoint.divideByScalar(current.scale).subtract(current.position.divideByScalar(current.scale));
735
+ const position = mouseRealPoint.multiplyByScalar(-scale).add(mousePoint);
736
+ return { position, scale };
737
+ }
738
+ }
739
+
673
740
  class ViewportApi {
674
- constructor(workspaceController, viewportController) {
741
+ constructor(workspaceController, viewportController, api) {
675
742
  this.workspaceController = workspaceController;
676
743
  this.viewportController = viewportController;
744
+ this.api = api;
745
+ this.animator = new ViewportAnimator(this.api);
746
+ }
747
+ limitScale(scale) {
748
+ return this.viewportController.limitScale(scale);
677
749
  }
678
750
  resetViewport() {
679
- this.viewportController.setDefault();
751
+ const defaultViewport = this.viewportController.getDefault();
752
+ this.api.setViewport(defaultViewport);
680
753
  }
681
754
  zoom(direction) {
682
- this.viewportController.zoom(direction);
755
+ const viewport = this.viewportController.getZoomed(direction);
756
+ if (viewport) {
757
+ this.api.setViewport(viewport);
758
+ }
683
759
  }
684
760
  moveViewportToStep(stepId) {
685
761
  const component = this.workspaceController.getComponentByStepId(stepId);
@@ -687,7 +763,16 @@ class ViewportApi {
687
763
  const clientPosition = component.view.getClientPosition();
688
764
  const componentPosition = clientPosition.subtract(canvasPosition);
689
765
  const componentSize = new Vector(component.view.width, component.view.height);
690
- this.viewportController.focusOnComponent(componentPosition, componentSize);
766
+ const viewport = this.viewportController.getFocusedOnComponent(componentPosition, componentSize);
767
+ this.animator.execute(viewport);
768
+ }
769
+ handleWheelEvent(e) {
770
+ const viewport = this.api.getViewport();
771
+ const canvasPosition = this.api.getCanvasPosition();
772
+ const newViewport = ZoomByWheelCalculator.calculate(this.viewportController, viewport, canvasPosition, e);
773
+ if (newViewport) {
774
+ this.api.setViewport(newViewport);
775
+ }
691
776
  }
692
777
  }
693
778
 
@@ -726,7 +811,7 @@ class DesignerApi {
726
811
  static create(context) {
727
812
  const workspace = new WorkspaceApi(context.state, context.workspaceController);
728
813
  const viewportController = context.services.viewportController.create(workspace);
729
- const viewport = new ViewportApi(context.workspaceController, viewportController);
814
+ const viewport = new ViewportApi(context.workspaceController, viewportController, workspace);
730
815
  const toolboxDataProvider = new ToolboxDataProvider(context.componentContext.iconProvider, context.i18n, context.configuration.toolbox);
731
816
  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);
732
817
  }
@@ -1171,7 +1256,7 @@ class ValidationErrorBadge {
1171
1256
  }
1172
1257
  }
1173
1258
 
1174
- const defaultConfiguration$6 = {
1259
+ const defaultConfiguration$7 = {
1175
1260
  view: {
1176
1261
  size: 22,
1177
1262
  iconSize: 12
@@ -1179,7 +1264,7 @@ const defaultConfiguration$6 = {
1179
1264
  };
1180
1265
  class ValidationErrorBadgeExtension {
1181
1266
  static create(configuration) {
1182
- return new ValidationErrorBadgeExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$6);
1267
+ return new ValidationErrorBadgeExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$7);
1183
1268
  }
1184
1269
  constructor(configuration) {
1185
1270
  this.configuration = configuration;
@@ -1575,7 +1660,7 @@ class StartStopRootComponent {
1575
1660
  }
1576
1661
  }
1577
1662
 
1578
- const defaultConfiguration$5 = {
1663
+ const defaultConfiguration$6 = {
1579
1664
  view: {
1580
1665
  size: 30,
1581
1666
  defaultIconSize: 22,
@@ -1587,7 +1672,7 @@ const defaultConfiguration$5 = {
1587
1672
  };
1588
1673
  class StartStopRootComponentExtension {
1589
1674
  static create(configuration) {
1590
- return new StartStopRootComponentExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$5);
1675
+ return new StartStopRootComponentExtension(configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$6);
1591
1676
  }
1592
1677
  constructor(configuration) {
1593
1678
  this.configuration = configuration;
@@ -1821,15 +1906,15 @@ const createTaskStepComponentViewFactory = (isInterrupted, cfg) => (parentElemen
1821
1906
  };
1822
1907
 
1823
1908
  class CenteredViewportCalculator {
1824
- static center(margin, canvasSize, rootComponentSize) {
1909
+ static center(padding, canvasSize, rootComponentSize) {
1825
1910
  if (canvasSize.x === 0 || canvasSize.y === 0) {
1826
1911
  return {
1827
1912
  position: new Vector(0, 0),
1828
1913
  scale: 1
1829
1914
  };
1830
1915
  }
1831
- const canvasSafeWidth = Math.max(canvasSize.x - margin * 2, 0);
1832
- const canvasSafeHeight = Math.max(canvasSize.y - margin * 2, 0);
1916
+ const canvasSafeWidth = Math.max(canvasSize.x - padding * 2, 0);
1917
+ const canvasSafeHeight = Math.max(canvasSize.y - padding * 2, 0);
1833
1918
  const scale = Math.min(Math.min(canvasSafeWidth / rootComponentSize.x, canvasSafeHeight / rootComponentSize.y), 1);
1834
1919
  const width = rootComponentSize.x * scale;
1835
1920
  const height = rootComponentSize.y * scale;
@@ -1840,7 +1925,7 @@ class CenteredViewportCalculator {
1840
1925
  scale
1841
1926
  };
1842
1927
  }
1843
- static focusOnComponent(canvasSize, viewport, componentPosition, componentSize) {
1928
+ static getFocusedOnComponent(canvasSize, viewport, componentPosition, componentSize) {
1844
1929
  const realPosition = viewport.position.divideByScalar(viewport.scale).subtract(componentPosition.divideByScalar(viewport.scale));
1845
1930
  const componentOffset = componentSize.divideByScalar(2);
1846
1931
  const position = realPosition.add(canvasSize.divideByScalar(2)).subtract(componentOffset);
@@ -1848,6 +1933,24 @@ class CenteredViewportCalculator {
1848
1933
  }
1849
1934
  }
1850
1935
 
1936
+ class ClassicWheelController {
1937
+ static create(api) {
1938
+ return new ClassicWheelController(api);
1939
+ }
1940
+ constructor(api) {
1941
+ this.api = api;
1942
+ }
1943
+ onWheel(e) {
1944
+ this.api.handleWheelEvent(e);
1945
+ }
1946
+ }
1947
+
1948
+ class ClassicWheelControllerExtension {
1949
+ constructor() {
1950
+ this.create = ClassicWheelController.create;
1951
+ }
1952
+ }
1953
+
1851
1954
  class NextQuantifiedNumber {
1852
1955
  constructor(values) {
1853
1956
  this.values = values;
@@ -1874,142 +1977,68 @@ class NextQuantifiedNumber {
1874
1977
  next: this.values[index]
1875
1978
  };
1876
1979
  }
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 };
1980
+ limit(scale) {
1981
+ const min = this.values[0];
1982
+ const max = this.values[this.values.length - 1];
1983
+ return Math.min(Math.max(scale, min), max);
1910
1984
  }
1911
1985
  }
1912
1986
 
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;
1987
+ const defaultConfiguration$5 = {
1988
+ 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],
1989
+ smoothDeltaYLimit: 16,
1990
+ padding: 10
1991
+ };
1980
1992
  class DefaultViewportController {
1981
- static create(api) {
1982
- return new DefaultViewportController(api);
1993
+ static create(api, configuration) {
1994
+ const config = configuration !== null && configuration !== void 0 ? configuration : defaultConfiguration$5;
1995
+ const nqn = new NextQuantifiedNumber(config.scales);
1996
+ return new DefaultViewportController(config.smoothDeltaYLimit, nqn, api, config.padding);
1983
1997
  }
1984
- constructor(api) {
1998
+ constructor(smoothDeltaYLimit, nqn, api, padding) {
1999
+ this.smoothDeltaYLimit = smoothDeltaYLimit;
2000
+ this.nqn = nqn;
1985
2001
  this.api = api;
1986
- this.animator = new ViewportAnimator(this.api);
2002
+ this.padding = padding;
1987
2003
  }
1988
- setDefault() {
2004
+ getDefault() {
1989
2005
  const rootComponentSize = this.api.getRootComponentSize();
1990
2006
  const canvasSize = this.api.getCanvasSize();
1991
- const target = CenteredViewportCalculator.center(CENTER_MARGIN, canvasSize, rootComponentSize);
1992
- this.api.setViewport(target);
2007
+ return CenteredViewportCalculator.center(this.padding, canvasSize, rootComponentSize);
1993
2008
  }
1994
- zoom(direction) {
1995
- const viewport = this.api.getViewport();
1996
- const target = QuantifiedScaleViewportCalculator.zoom(viewport, direction);
1997
- this.api.setViewport(target);
2009
+ getZoomed(direction) {
2010
+ const current = this.api.getViewport();
2011
+ const nextScale = this.nqn.next(current.scale, direction);
2012
+ if (nextScale) {
2013
+ return {
2014
+ position: current.position,
2015
+ scale: nextScale.next
2016
+ };
2017
+ }
2018
+ return null;
1998
2019
  }
1999
- focusOnComponent(componentPosition, componentSize) {
2020
+ getFocusedOnComponent(componentPosition, componentSize) {
2000
2021
  const viewport = this.api.getViewport();
2001
2022
  const canvasSize = this.api.getCanvasSize();
2002
- const target = CenteredViewportCalculator.focusOnComponent(canvasSize, viewport, componentPosition, componentSize);
2003
- this.animateTo(target);
2023
+ return CenteredViewportCalculator.getFocusedOnComponent(canvasSize, viewport, componentPosition, componentSize);
2004
2024
  }
2005
- animateTo(viewport) {
2006
- this.animator.execute(viewport);
2025
+ getNextScale(scale, direction) {
2026
+ return this.nqn.next(scale, direction);
2027
+ }
2028
+ limitScale(scale) {
2029
+ return this.nqn.limit(scale);
2007
2030
  }
2008
2031
  }
2009
2032
 
2010
2033
  class DefaultViewportControllerExtension {
2011
- constructor() {
2012
- this.create = DefaultViewportController.create;
2034
+ static create(configuration) {
2035
+ return new DefaultViewportControllerExtension(configuration);
2036
+ }
2037
+ constructor(configuration) {
2038
+ this.configuration = configuration;
2039
+ }
2040
+ create(api) {
2041
+ return DefaultViewportController.create(api, this.configuration);
2013
2042
  }
2014
2043
  }
2015
2044
 
@@ -2169,10 +2198,26 @@ function readTouchPosition(e) {
2169
2198
  return new Vector(touch.pageX, touch.pageY);
2170
2199
  }
2171
2200
  throw new Error('Unknown touch position');
2201
+ }
2202
+ function calculateFingerDistance(e) {
2203
+ if (e.touches.length === 2) {
2204
+ const t0 = e.touches[0];
2205
+ const t1 = e.touches[1];
2206
+ return Math.hypot(t0.clientX - t1.clientX, t0.clientY - t1.clientY);
2207
+ }
2208
+ throw new Error('Cannot calculate finger distance');
2209
+ }
2210
+ function readFingerCenterPoint(e) {
2211
+ if (e.touches.length === 2) {
2212
+ const t0 = e.touches[0];
2213
+ const t1 = e.touches[1];
2214
+ return new Vector((t0.pageX + t1.pageX) / 2, (t0.pageY + t1.pageY) / 2);
2215
+ }
2216
+ throw new Error('Cannot calculate finger center point');
2172
2217
  }
2173
2218
 
2174
- const notInitializedError = 'State is not initialized';
2175
- const nonPassiveOptions = {
2219
+ const notInitializedError$1 = 'State is not initialized';
2220
+ const nonPassiveOptions$1 = {
2176
2221
  passive: false
2177
2222
  };
2178
2223
  class BehaviorController {
@@ -2202,7 +2247,7 @@ class BehaviorController {
2202
2247
  e.preventDefault();
2203
2248
  e.stopPropagation();
2204
2249
  if (!this.state) {
2205
- throw new Error(notInitializedError);
2250
+ throw new Error(notInitializedError$1);
2206
2251
  }
2207
2252
  const position = (_a = this.state.lastPosition) !== null && _a !== void 0 ? _a : this.state.startPosition;
2208
2253
  const element = this.dom.elementFromPoint(position.x, position.y);
@@ -2233,21 +2278,21 @@ class BehaviorController {
2233
2278
  }
2234
2279
  bind(target) {
2235
2280
  target.addEventListener('mousemove', this.onMouseMove, false);
2236
- target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
2281
+ target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions$1);
2237
2282
  target.addEventListener('mouseup', this.onMouseUp, false);
2238
- target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
2239
- target.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
2283
+ target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions$1);
2284
+ target.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions$1);
2240
2285
  }
2241
2286
  unbind(target) {
2242
2287
  target.removeEventListener('mousemove', this.onMouseMove, false);
2243
- target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
2288
+ target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions$1);
2244
2289
  target.removeEventListener('mouseup', this.onMouseUp, false);
2245
- target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
2246
- target.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
2290
+ target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions$1);
2291
+ target.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions$1);
2247
2292
  }
2248
2293
  move(position) {
2249
2294
  if (!this.state) {
2250
- throw new Error(notInitializedError);
2295
+ throw new Error(notInitializedError$1);
2251
2296
  }
2252
2297
  this.state.lastPosition = position;
2253
2298
  const delta = this.state.startPosition.subtract(position);
@@ -2261,7 +2306,7 @@ class BehaviorController {
2261
2306
  }
2262
2307
  stop(interrupt, element) {
2263
2308
  if (!this.state) {
2264
- throw new Error(notInitializedError);
2309
+ throw new Error(notInitializedError$1);
2265
2310
  }
2266
2311
  if (this.shadowRoot) {
2267
2312
  this.unbind(this.shadowRoot);
@@ -2836,20 +2881,26 @@ class WorkspaceView {
2836
2881
  getCanvasSize() {
2837
2882
  return new Vector(this.canvas.clientWidth, this.canvas.clientHeight);
2838
2883
  }
2839
- bindClick(handler) {
2884
+ bindMouseDown(handler) {
2840
2885
  this.canvas.addEventListener('mousedown', e => {
2841
2886
  e.preventDefault();
2842
2887
  handler(readMousePosition(e), e.target, e.button, e.altKey);
2843
2888
  }, false);
2889
+ }
2890
+ bindTouchStart(clickHandler, pinchToZoomHandler) {
2844
2891
  this.canvas.addEventListener('touchstart', e => {
2845
2892
  var _a;
2846
2893
  e.preventDefault();
2894
+ if (e.touches.length === 2) {
2895
+ pinchToZoomHandler(calculateFingerDistance(e), readFingerCenterPoint(e));
2896
+ return;
2897
+ }
2847
2898
  const clientPosition = readTouchClientPosition(e);
2848
2899
  const dom = (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : document;
2849
2900
  const element = dom.elementFromPoint(clientPosition.x, clientPosition.y);
2850
2901
  if (element) {
2851
2902
  const position = readTouchPosition(e);
2852
- handler(position, element, 0, false);
2903
+ clickHandler(position, element, 0, false);
2853
2904
  }
2854
2905
  }, listenerOptions$1);
2855
2906
  }
@@ -3226,17 +3277,96 @@ class ContextMenuItemsBuilder {
3226
3277
  }
3227
3278
  }
3228
3279
 
3280
+ const nonPassiveOptions = {
3281
+ passive: false
3282
+ };
3283
+ const notInitializedError = 'State is not initialized';
3284
+ class PinchToZoomController {
3285
+ static create(workspaceApi, viewportApi, shadowRoot) {
3286
+ return new PinchToZoomController(workspaceApi, viewportApi, shadowRoot);
3287
+ }
3288
+ constructor(workspaceApi, viewportApi, shadowRoot) {
3289
+ this.workspaceApi = workspaceApi;
3290
+ this.viewportApi = viewportApi;
3291
+ this.shadowRoot = shadowRoot;
3292
+ this.state = null;
3293
+ this.onTouchMove = (e) => {
3294
+ e.preventDefault();
3295
+ if (!this.state) {
3296
+ throw new Error(notInitializedError);
3297
+ }
3298
+ const touchEvent = e;
3299
+ const distance = calculateFingerDistance(touchEvent);
3300
+ const centerPoint = readFingerCenterPoint(touchEvent);
3301
+ const deltaCenterPoint = centerPoint.subtract(this.state.lastCenterPoint);
3302
+ const scale = this.viewportApi.limitScale(this.state.startScale * (distance / this.state.startDistance));
3303
+ const zoomPoint = centerPoint.subtract(this.state.canvasPosition);
3304
+ const zoomRealPoint = zoomPoint
3305
+ .divideByScalar(this.state.lastViewport.scale)
3306
+ .subtract(this.state.lastViewport.position.divideByScalar(this.state.lastViewport.scale));
3307
+ const position = zoomRealPoint
3308
+ .multiplyByScalar(-scale)
3309
+ .add(zoomPoint)
3310
+ .add(deltaCenterPoint.divideByScalar(this.state.lastViewport.scale));
3311
+ const newViewport = {
3312
+ position,
3313
+ scale
3314
+ };
3315
+ this.workspaceApi.setViewport(newViewport);
3316
+ this.state.lastCenterPoint = centerPoint;
3317
+ this.state.lastViewport = newViewport;
3318
+ };
3319
+ this.onTouchEnd = (e) => {
3320
+ e.preventDefault();
3321
+ if (!this.state) {
3322
+ throw new Error(notInitializedError);
3323
+ }
3324
+ if (this.shadowRoot) {
3325
+ this.unbind(this.shadowRoot);
3326
+ }
3327
+ this.unbind(window);
3328
+ this.state = null;
3329
+ };
3330
+ }
3331
+ start(startDistance, centerPoint) {
3332
+ if (this.state) {
3333
+ throw new Error(`State is already initialized`);
3334
+ }
3335
+ if (this.shadowRoot) {
3336
+ this.bind(this.shadowRoot);
3337
+ }
3338
+ this.bind(window);
3339
+ const viewport = this.workspaceApi.getViewport();
3340
+ this.state = {
3341
+ canvasPosition: this.workspaceApi.getCanvasPosition(),
3342
+ startScale: viewport.scale,
3343
+ startDistance,
3344
+ lastViewport: viewport,
3345
+ lastCenterPoint: centerPoint
3346
+ };
3347
+ }
3348
+ bind(target) {
3349
+ target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
3350
+ target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
3351
+ }
3352
+ unbind(target) {
3353
+ target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
3354
+ target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
3355
+ }
3356
+ }
3357
+
3229
3358
  class Workspace {
3230
3359
  static create(parent, designerContext, api) {
3231
3360
  var _a;
3232
3361
  const view = WorkspaceView.create(parent, designerContext.componentContext);
3233
3362
  const clickBehaviorResolver = new ClickBehaviorResolver(designerContext);
3234
- const wheelController = designerContext.services.wheelController.create(api.workspace);
3363
+ const wheelController = designerContext.services.wheelController.create(api.viewport, api.workspace);
3364
+ const pinchToZoomController = PinchToZoomController.create(api.workspace, api.viewport, api.shadowRoot);
3235
3365
  const contextMenuItemsBuilder = new ContextMenuItemsBuilder(api.viewport, api.i18n, designerContext.stateModifier, designerContext.state, ((_a = designerContext.services.contextMenu) === null || _a === void 0 ? void 0 : _a.createItemsProvider)
3236
3366
  ? designerContext.services.contextMenu.createItemsProvider(designerContext.customActionController)
3237
3367
  : undefined);
3238
3368
  const contextMenuController = new ContextMenuController(designerContext.theme, designerContext.configuration, contextMenuItemsBuilder);
3239
- const workspace = new Workspace(view, designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, contextMenuController, clickBehaviorResolver, api.viewport, designerContext.services);
3369
+ const workspace = new Workspace(view, designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, pinchToZoomController, contextMenuController, clickBehaviorResolver, api.viewport, designerContext.services);
3240
3370
  setTimeout(() => {
3241
3371
  workspace.updateRootComponent();
3242
3372
  api.viewport.resetViewport();
@@ -3246,17 +3376,19 @@ class Workspace {
3246
3376
  race(0, designerContext.state.onDefinitionChanged, designerContext.state.onSelectedStepIdChanged, designerContext.state.onFolderPathChanged).subscribe(r => {
3247
3377
  workspace.onStateChanged(r[0], r[1], r[2]);
3248
3378
  });
3249
- view.bindClick(workspace.onClick);
3379
+ view.bindMouseDown(workspace.onClick);
3380
+ view.bindTouchStart(workspace.onClick, workspace.onPinchToZoom);
3250
3381
  view.bindWheel(workspace.onWheel);
3251
3382
  view.bindContextMenu(workspace.onContextMenu);
3252
3383
  return workspace;
3253
3384
  }
3254
- constructor(view, definitionWalker, state, behaviorController, wheelController, contextMenuController, clickBehaviorResolver, viewportApi, services) {
3385
+ constructor(view, definitionWalker, state, behaviorController, wheelController, pinchToZoomController, contextMenuController, clickBehaviorResolver, viewportApi, services) {
3255
3386
  this.view = view;
3256
3387
  this.definitionWalker = definitionWalker;
3257
3388
  this.state = state;
3258
3389
  this.behaviorController = behaviorController;
3259
3390
  this.wheelController = wheelController;
3391
+ this.pinchToZoomController = pinchToZoomController;
3260
3392
  this.contextMenuController = contextMenuController;
3261
3393
  this.clickBehaviorResolver = clickBehaviorResolver;
3262
3394
  this.viewportApi = viewportApi;
@@ -3275,6 +3407,9 @@ class Workspace {
3275
3407
  this.behaviorController.start(position, behavior);
3276
3408
  }
3277
3409
  };
3410
+ this.onPinchToZoom = (distance, centerPoint) => {
3411
+ this.pinchToZoomController.start(distance, centerPoint);
3412
+ };
3278
3413
  this.onWheel = (e) => {
3279
3414
  e.preventDefault();
3280
3415
  e.stopPropagation();
@@ -4398,7 +4533,7 @@ function setDefaults(services, configuration) {
4398
4533
  services.regionComponentView = new DefaultRegionComponentViewExtension();
4399
4534
  }
4400
4535
  if (!services.viewportController) {
4401
- services.viewportController = new DefaultViewportControllerExtension();
4536
+ services.viewportController = DefaultViewportControllerExtension.create();
4402
4537
  }
4403
4538
  if (!services.grid) {
4404
4539
  services.grid = LineGridExtension.create();
@@ -4717,7 +4852,6 @@ exports.LineGridDesignerExtension = LineGridDesignerExtension;
4717
4852
  exports.ObjectCloner = ObjectCloner;
4718
4853
  exports.OutputView = OutputView;
4719
4854
  exports.PathBarApi = PathBarApi;
4720
- exports.QuantifiedScaleViewportCalculator = QuantifiedScaleViewportCalculator;
4721
4855
  exports.RectPlaceholder = RectPlaceholder;
4722
4856
  exports.RectPlaceholderView = RectPlaceholderView;
4723
4857
  exports.ServicesResolver = ServicesResolver;
@@ -4730,6 +4864,7 @@ exports.ToolboxApi = ToolboxApi;
4730
4864
  exports.Uid = Uid;
4731
4865
  exports.ValidationErrorBadgeExtension = ValidationErrorBadgeExtension;
4732
4866
  exports.Vector = Vector;
4867
+ exports.ViewportApi = ViewportApi;
4733
4868
  exports.WorkspaceApi = WorkspaceApi;
4734
4869
  exports.createContainerStepComponentViewFactory = createContainerStepComponentViewFactory;
4735
4870
  exports.createSwitchStepComponentViewFactory = createSwitchStepComponentViewFactory;