Skip to content

Commit 65cc31c

Browse files
authoredNov 6, 2024
0.25.0. (#170)
1 parent 015d535 commit 65cc31c

31 files changed

+355
-129
lines changed
 

‎CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 0.25.0
2+
3+
This version introduces the pinch-to-zoom feature. Now you can zoom in and out using the pinch gesture on touch devices.
4+
15
# 0.24.8
26

37
This version adds new classes to the start-stop root component.

‎README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ Add the below code to your head section in HTML document.
103103
```html
104104
<head>
105105
...
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>
110110
```
111111

112112
Call the designer by:

‎angular/designer/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sequential-workflow-designer-angular",
33
"description": "Angular wrapper for Sequential Workflow Designer component.",
4-
"version": "0.24.8",
4+
"version": "0.25.0",
55
"author": {
66
"name": "NoCode JS",
77
"url": "https://nocode-js.com/"
@@ -15,7 +15,7 @@
1515
"peerDependencies": {
1616
"@angular/common": "12 - 18",
1717
"@angular/core": "12 - 18",
18-
"sequential-workflow-designer": "^0.24.8"
18+
"sequential-workflow-designer": "^0.25.0"
1919
},
2020
"dependencies": {
2121
"tslib": "^2.3.0"

‎demos/angular-app/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
"@angular/platform-browser-dynamic": "^17.3.9",
2727
"@angular/router": "^17.3.9",
2828
"rxjs": "~7.8.0",
29-
"sequential-workflow-designer": "^0.24.8",
30-
"sequential-workflow-designer-angular": "^0.24.8",
29+
"sequential-workflow-designer": "^0.25.0",
30+
"sequential-workflow-designer-angular": "^0.25.0",
3131
"tslib": "^2.3.0",
3232
"zone.js": "~0.14.6"
3333
},

‎demos/angular-app/yarn.lock

+8-8
Original file line numberDiff line numberDiff line change
@@ -6744,17 +6744,17 @@ send@0.18.0:
67446744
range-parser "~1.2.1"
67456745
statuses "2.0.1"
67466746

6747-
sequential-workflow-designer-angular@^0.24.8:
6748-
version "0.24.8"
6749-
resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.24.8.tgz#9ec487a72e1ea9ce470c30629e43778558074909"
6750-
integrity sha512-62fQrgVb7yOF+vA5RdSEoositp5AQ8iG8gV4KNSLPE3kf8rk8els8kiLDwtlH4H03UnAtamXTbNXMs6Xt7quGQ==
6747+
sequential-workflow-designer-angular@^0.25.0:
6748+
version "0.25.0"
6749+
resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.25.0.tgz#eb65370283a408c10eeb7b71b67dae2af9d6196b"
6750+
integrity sha512-E100P2es8Gn5th0f0ErfjRr9TWWcgocz16kZocWvCHeOn5/iLo+oCuvSSZjewpnYTVA6oDcHH//KJnq5sPN69g==
67516751
dependencies:
67526752
tslib "^2.3.0"
67536753

6754-
sequential-workflow-designer@^0.24.8:
6755-
version "0.24.8"
6756-
resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.24.8.tgz#10deceece8133a8f7781e9ba36ad219b412a2e40"
6757-
integrity sha512-DkLwdtkP2F8AnvrICtrgzTS4TfCpDHRTpN71G3OQSL1zky5T8I5GTm7iqnMmQkwfjRi1Xx8b8e5miW687/6jYw==
6754+
sequential-workflow-designer@^0.25.0:
6755+
version "0.25.0"
6756+
resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.25.0.tgz#db8d35441a68f0b05f169e458f12f5457f9beca9"
6757+
integrity sha512-KNOTA4zx/TkpL0LHQFvNe2S07vejA4YjRcl6UNpLjG4fODQKfiZ8zj5RypcG54O6TArBU8eDEUwtXgnuopGEYQ==
67586758
dependencies:
67596759
sequential-workflow-model "^0.2.0"
67606760

‎demos/react-app/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"dependencies": {
77
"react": "^18.2.0",
88
"react-dom": "^18.2.0",
9-
"sequential-workflow-designer": "^0.24.8",
10-
"sequential-workflow-designer-react": "^0.24.8"
9+
"sequential-workflow-designer": "^0.25.0",
10+
"sequential-workflow-designer-react": "^0.25.0"
1111
},
1212
"devDependencies": {
1313
"@types/jest": "^29.2.5",

‎demos/svelte-app/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
"eslint": "eslint ./src --ext .ts"
1717
},
1818
"dependencies": {
19-
"sequential-workflow-designer": "^0.24.8",
20-
"sequential-workflow-designer-svelte": "^0.24.8"
19+
"sequential-workflow-designer": "^0.25.0",
20+
"sequential-workflow-designer-svelte": "^0.25.0"
2121
},
2222
"devDependencies": {
2323
"@sveltejs/adapter-static": "^2.0.3",

‎designer/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sequential-workflow-designer",
33
"description": "Customizable no-code component for building flow-based programming applications.",
4-
"version": "0.24.8",
4+
"version": "0.25.0",
55
"type": "module",
66
"main": "./lib/esm/index.js",
77
"types": "./lib/index.d.ts",

‎designer/src/api/designer-api.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class DesignerApi {
1313
public static create(context: DesignerContext): DesignerApi {
1414
const workspace = new WorkspaceApi(context.state, context.workspaceController);
1515
const viewportController = context.services.viewportController.create(workspace);
16-
const viewport = new ViewportApi(context.workspaceController, viewportController);
16+
const viewport = new ViewportApi(context.workspaceController, viewportController, workspace);
1717
const toolboxDataProvider = new ToolboxDataProvider(
1818
context.componentContext.iconProvider,
1919
context.i18n,

‎designer/src/api/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export * from './designer-api';
33
export * from './editor-api';
44
export * from './path-bar-api';
55
export * from './toolbox-api';
6+
export * from './viewport-api';
67
export * from './workspace-api';

‎designer/src/api/viewport-api.ts

+29-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
11
import { Vector } from '../core';
22
import { ViewportController } from '../designer-extension';
3+
import { ViewportAnimator } from '../workspace/viewport/viewport-animator';
4+
import { ZoomByWheelCalculator } from '../workspace/viewport/zoom-by-wheel-calculator';
35
import { WorkspaceControllerWrapper } from '../workspace/workspace-controller';
6+
import { WorkspaceApi } from './workspace-api';
47

58
export class ViewportApi {
9+
private readonly animator = new ViewportAnimator(this.api);
10+
611
public constructor(
712
private readonly workspaceController: WorkspaceControllerWrapper,
8-
private readonly viewportController: ViewportController
13+
private readonly viewportController: ViewportController,
14+
private readonly api: WorkspaceApi
915
) {}
1016

17+
public limitScale(scale: number): number {
18+
return this.viewportController.limitScale(scale);
19+
}
20+
1121
public resetViewport() {
12-
this.viewportController.setDefault();
22+
const defaultViewport = this.viewportController.getDefault();
23+
this.api.setViewport(defaultViewport);
1324
}
1425

1526
public zoom(direction: boolean) {
16-
this.viewportController.zoom(direction);
27+
const viewport = this.viewportController.getZoomed(direction);
28+
if (viewport) {
29+
this.api.setViewport(viewport);
30+
}
1731
}
1832

1933
public moveViewportToStep(stepId: string) {
@@ -24,6 +38,17 @@ export class ViewportApi {
2438
const componentPosition = clientPosition.subtract(canvasPosition);
2539

2640
const componentSize = new Vector(component.view.width, component.view.height);
27-
this.viewportController.focusOnComponent(componentPosition, componentSize);
41+
const viewport = this.viewportController.getFocusedOnComponent(componentPosition, componentSize);
42+
this.animator.execute(viewport);
43+
}
44+
45+
public handleWheelEvent(e: WheelEvent) {
46+
const viewport = this.api.getViewport();
47+
const canvasPosition = this.api.getCanvasPosition();
48+
49+
const newViewport = ZoomByWheelCalculator.calculate(this.viewportController, viewport, canvasPosition, e);
50+
if (newViewport) {
51+
this.api.setViewport(newViewport);
52+
}
2853
}
2954
}

‎designer/src/behaviors/behavior-controller.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ const nonPassiveOptions: AddEventListenerOptions & EventListenerOptions = {
99
};
1010

1111
export class BehaviorController {
12+
public static create(shadowRoot: ShadowRoot | undefined) {
13+
return new BehaviorController(shadowRoot ?? document, shadowRoot);
14+
}
15+
1216
private state?: {
1317
startPosition: Vector;
1418
behavior: Behavior;
1519
lastPosition?: Vector;
1620
};
1721

18-
public static create(shadowRoot: ShadowRoot | undefined) {
19-
return new BehaviorController(shadowRoot ?? document, shadowRoot);
20-
}
21-
2222
private constructor(
2323
private readonly dom: Document | ShadowRoot,
2424
private readonly shadowRoot: ShadowRoot | undefined

‎designer/src/core/event-readers.ts

+18
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,21 @@ export function readTouchPosition(e: TouchEvent): Vector {
1919
}
2020
throw new Error('Unknown touch position');
2121
}
22+
23+
export function calculateFingerDistance(e: TouchEvent): number {
24+
if (e.touches.length === 2) {
25+
const t0 = e.touches[0];
26+
const t1 = e.touches[1];
27+
return Math.hypot(t0.clientX - t1.clientX, t0.clientY - t1.clientY);
28+
}
29+
throw new Error('Cannot calculate finger distance');
30+
}
31+
32+
export function readFingerCenterPoint(e: TouchEvent): Vector {
33+
if (e.touches.length === 2) {
34+
const t0 = e.touches[0];
35+
const t1 = e.touches[1];
36+
return new Vector((t0.pageX + t1.pageX) / 2, (t0.pageY + t1.pageY) / 2);
37+
}
38+
throw new Error('Cannot calculate finger center point');
39+
}

‎designer/src/designer-extension.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { WorkspaceApi } from './api';
22
import { DesignerApi } from './api/designer-api';
3+
import { ViewportApi } from './api/viewport-api';
34
import { ComponentContext } from './component-context';
45
import { Vector } from './core';
56
import { CustomActionController } from './custom-action-controller';
@@ -98,7 +99,7 @@ export interface BadgeExtension {
9899
// WheelControllerExtension
99100

100101
export interface WheelControllerExtension {
101-
create(api: WorkspaceApi): WheelController;
102+
create(viewportApi: ViewportApi, workspaceApi: WorkspaceApi): WheelController;
102103
}
103104

104105
export interface WheelController {
@@ -204,9 +205,17 @@ export interface ViewportControllerExtension {
204205
}
205206

206207
export interface ViewportController {
207-
setDefault(): void;
208-
zoom(direction: boolean): void;
209-
focusOnComponent(componentPosition: Vector, componentSize: Vector): void;
208+
smoothDeltaYLimit: number;
209+
getDefault(): Viewport;
210+
getZoomed(direction: boolean): Viewport | null;
211+
getFocusedOnComponent(componentPosition: Vector, componentSize: Vector): Viewport;
212+
getNextScale(scale: number, direction: boolean): NextScale;
213+
limitScale(scale: number): number;
214+
}
215+
216+
export interface NextScale {
217+
current: number;
218+
next: number;
210219
}
211220

212221
export interface Viewport {

‎designer/src/services.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function setDefaults(services: Partial<Services>, configuration: DesignerConfigu
129129
services.regionComponentView = new DefaultRegionComponentViewExtension();
130130
}
131131
if (!services.viewportController) {
132-
services.viewportController = new DefaultViewportControllerExtension();
132+
services.viewportController = DefaultViewportControllerExtension.create();
133133
}
134134
if (!services.grid) {
135135
services.grid = LineGridExtension.create();

‎designer/src/workspace/viewport/centered-viewport-calculator.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ import { Vector } from '../../core';
22
import { Viewport } from '../../designer-extension';
33

44
export class CenteredViewportCalculator {
5-
public static center(margin: number, canvasSize: Vector, rootComponentSize: Vector): Viewport {
5+
public static center(padding: number, canvasSize: Vector, rootComponentSize: Vector): Viewport {
66
if (canvasSize.x === 0 || canvasSize.y === 0) {
77
return {
88
position: new Vector(0, 0),
99
scale: 1
1010
};
1111
}
1212

13-
const canvasSafeWidth = Math.max(canvasSize.x - margin * 2, 0);
14-
const canvasSafeHeight = Math.max(canvasSize.y - margin * 2, 0);
13+
const canvasSafeWidth = Math.max(canvasSize.x - padding * 2, 0);
14+
const canvasSafeHeight = Math.max(canvasSize.y - padding * 2, 0);
1515

1616
const scale = Math.min(Math.min(canvasSafeWidth / rootComponentSize.x, canvasSafeHeight / rootComponentSize.y), 1);
1717
const width = rootComponentSize.x * scale;
@@ -26,7 +26,12 @@ export class CenteredViewportCalculator {
2626
};
2727
}
2828

29-
public static focusOnComponent(canvasSize: Vector, viewport: Viewport, componentPosition: Vector, componentSize: Vector): Viewport {
29+
public static getFocusedOnComponent(
30+
canvasSize: Vector,
31+
viewport: Viewport,
32+
componentPosition: Vector,
33+
componentSize: Vector
34+
): Viewport {
3035
const realPosition = viewport.position.divideByScalar(viewport.scale).subtract(componentPosition.divideByScalar(viewport.scale));
3136
const componentOffset = componentSize.divideByScalar(2);
3237

Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
import { WorkspaceApi } from '../../api/workspace-api';
1+
import { ViewportApi } from '../../api/viewport-api';
22
import { WheelController } from '../../designer-extension';
3-
import { QuantifiedScaleViewportCalculator } from './quantified-scale-viewport-calculator';
43

54
export class ClassicWheelController implements WheelController {
6-
public static create(api: WorkspaceApi) {
5+
public static create(api: ViewportApi) {
76
return new ClassicWheelController(api);
87
}
98

10-
private constructor(private readonly api: WorkspaceApi) {}
9+
private constructor(private readonly api: ViewportApi) {}
1110

1211
public onWheel(e: WheelEvent) {
13-
const viewport = this.api.getViewport();
14-
const canvasPosition = this.api.getCanvasPosition();
15-
const newViewport = QuantifiedScaleViewportCalculator.zoomByWheel(viewport, e, canvasPosition);
16-
if (newViewport) {
17-
this.api.setViewport(newViewport);
18-
}
12+
this.api.handleWheelEvent(e);
1913
}
2014
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface DefaultViewportControllerConfiguration {
2+
scales: number[];
3+
smoothDeltaYLimit: number;
4+
padding: number;
5+
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
import { WorkspaceApi } from '../../api';
12
import { ViewportControllerExtension } from '../../designer-extension';
23
import { DefaultViewportController } from './default-viewport-controller';
4+
import { DefaultViewportControllerConfiguration } from './default-viewport-controller-configuration';
5+
6+
export type DefaultViewportControllerExtensionConfiguration = DefaultViewportControllerConfiguration;
37

48
export class DefaultViewportControllerExtension implements ViewportControllerExtension {
5-
public readonly create = DefaultViewportController.create;
9+
public static create(configuration?: DefaultViewportControllerExtensionConfiguration): DefaultViewportControllerExtension {
10+
return new DefaultViewportControllerExtension(configuration);
11+
}
12+
13+
private constructor(private readonly configuration: DefaultViewportControllerExtensionConfiguration | undefined) {}
14+
15+
public create(api: WorkspaceApi): DefaultViewportController {
16+
return DefaultViewportController.create(api, this.configuration);
17+
}
618
}

0 commit comments

Comments
 (0)