Skip to content

Commit cb5b883

Browse files
author
shuzarevich
committed
refactor(pinch-to-zoom): rename and reorganize pinch-to-zoom components
- Renamed SingleSelect to SelectByPointer and updated related files - Updated references from SingleSelectRequest to SelectByPointerRequest - Refactored PinchToZoomHandler and PinchToZoomPreparation for clarity - Adjusted imports and exports in multiple files for consistency - Improved handling of selection logic in SelectByPointer
1 parent 3253671 commit cb5b883

23 files changed

Lines changed: 318 additions & 330 deletions
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { FBackgroundBase } from '../../../f-backgroud';
22

33
export class AddBackgroundToStoreRequest {
4-
static readonly fToken = Symbol('AddBackgroundToStoreRequest');
4+
static readonly fToken = Symbol('AddBackgroundToStoreRequest');
55

6-
constructor(
7-
public fBackground: FBackgroundBase,
8-
) {
9-
}
6+
constructor(public fBackground: FBackgroundBase) {}
107
}

projects/f-flow/src/f-draggable/f-draggable.directive.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import {
4747
FExternalItemPreparationRequest,
4848
PreventDefaultIsExternalItemRequest,
4949
} from '../f-external-item';
50-
import { SingleSelectRequest } from './single-select';
50+
import { SelectByPointerRequest } from './select-by-pointer';
5151
import { NodeResizeFinalizeRequest, NodeResizePreparationRequest } from './f-node-resize';
5252
import {
5353
F_AFTER_MAIN_PLUGIN,
@@ -212,7 +212,7 @@ export class FDraggableDirective
212212

213213
this._mediator.execute<void>(new PinchToZoomPreparationRequest(event));
214214

215-
this._mediator.execute<void>(new SingleSelectRequest(event, this.fMultiSelectTrigger));
215+
this._mediator.execute<void>(new SelectByPointerRequest(event, this.fMultiSelectTrigger));
216216

217217
this._mediator.execute<void>(
218218
new ReassignConnectionPreparationRequest(event, this.fReassignConnectionTrigger),

projects/f-flow/src/f-draggable/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export * from './f-node-resize';
1414

1515
export * from './f-node-rotate';
1616

17-
export * from './single-select';
17+
export * from './select-by-pointer';
1818

1919
export * from './pinch-to-zoom';
2020

projects/f-flow/src/f-draggable/infrastructure/drag-handler-injector.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
DragNodeConnectionTargetHandler,
1313
DragNodeHandler,
1414
} from '../drag-node';
15+
import { PinchToZoomHandler } from '../pinch-to-zoom';
1516

1617
type NoArgsCtor<T> = new () => T;
1718

@@ -73,6 +74,10 @@ export class DragHandlerInjector {
7374
provide: DragNodeHandler,
7475
useClass: DragNodeHandler,
7576
},
77+
{
78+
provide: PinchToZoomHandler,
79+
useClass: PinchToZoomHandler,
80+
},
7681
],
7782
parent: this._injector,
7883
});

projects/f-flow/src/f-draggable/pinch-to-zoom/constants/constants.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

projects/f-flow/src/f-draggable/pinch-to-zoom/constants/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

projects/f-flow/src/f-draggable/pinch-to-zoom/finalize/pinch-to-zoom-finalize.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@ import { inject, Injectable } from '@angular/core';
22
import { PinchToZoomFinalizeRequest } from './pinch-to-zoom-finalize-request';
33
import { FExecutionRegister, IExecution } from '@foblex/mediator';
44
import { FDraggableDataContext } from '../../f-draggable-data-context';
5-
import { FNodeRotateDragHandler, FNodeRotateFinalizeRequest } from '../../f-node-rotate';
5+
import { PinchToZoomHandler } from '../handler';
66

77
@Injectable()
88
@FExecutionRegister(PinchToZoomFinalizeRequest)
99
export class PinchToZoomFinalize implements IExecution<PinchToZoomFinalizeRequest, void> {
10-
private readonly _dragContext = inject(FDraggableDataContext);
10+
private readonly _dragSession = inject(FDraggableDataContext);
1111

12-
public handle(_request: FNodeRotateFinalizeRequest): void {
13-
if (!this._isValid()) {
12+
public handle(_: PinchToZoomFinalizeRequest): void {
13+
if (!this._hasPinchZoomHandler()) {
1414
return;
1515
}
16-
this._dragContext.draggableItems.forEach((x) => {
17-
x.onPointerUp?.();
18-
});
16+
17+
for (const item of this._dragSession.draggableItems) {
18+
item.onPointerUp?.();
19+
}
1920
}
2021

21-
private _isValid(): boolean {
22-
return this._dragContext.draggableItems.some((x) => x instanceof FNodeRotateDragHandler);
22+
private _hasPinchZoomHandler(): boolean {
23+
return this._dragSession.draggableItems.some((x) => x instanceof PinchToZoomHandler);
2324
}
2425
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './pinch-to-zoom-handler';
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { inject, Injectable } from '@angular/core';
2+
import { IPoint, Point, PointExtensions } from '@foblex/2d';
3+
import { DragHandlerBase } from '../../infrastructure';
4+
import { FComponentsStore } from '../../../f-storage';
5+
import { FCanvasBase } from '../../../f-canvas';
6+
import { FZoomBase } from '../../../f-zoom';
7+
import { F_ZOOM_TAG } from '../../../domain';
8+
import { IPointerEvent } from '../../../drag-toolkit';
9+
10+
const PINCH_MOVEMENT_THRESHOLD = 0.5;
11+
12+
@Injectable()
13+
export class PinchToZoomHandler extends DragHandlerBase<unknown> {
14+
protected readonly type = 'pinch-to-zoom';
15+
protected readonly kind = 'pinch-to-zoom';
16+
17+
private readonly _store = inject(FComponentsStore);
18+
19+
private get _flowHost(): HTMLElement {
20+
return this._store.flowHost;
21+
}
22+
23+
private get _canvas(): FCanvasBase {
24+
return this._store.fCanvas as FCanvasBase;
25+
}
26+
27+
private get _zoomComponent(): FZoomBase {
28+
return this._store.fComponents[F_ZOOM_TAG] as FZoomBase;
29+
}
30+
31+
private _startDistance: number | null = null;
32+
private _startScale: number | null = null;
33+
private _touches!: TouchList;
34+
35+
public initialize(touches: TouchList): void {
36+
this._touches = touches;
37+
}
38+
39+
public override prepareDragSequence(): void {
40+
const distance = calculateTouchDistance(this._touches);
41+
if (distance == null) return;
42+
43+
this._startDistance = distance;
44+
this._startScale = this._canvas.transform.scale;
45+
}
46+
47+
public override onPointerMove(_: IPoint, event: IPointerEvent): void {
48+
if (event.touches.length !== 2 || this._startDistance == null || this._startScale == null) {
49+
return;
50+
}
51+
52+
const distance = calculateTouchDistance(event.touches);
53+
const center = calculateTouchCenter(event.touches);
54+
if (distance == null || center == null) {
55+
this._reset();
56+
57+
return;
58+
}
59+
60+
if (Math.abs(distance - this._startDistance) < PINCH_MOVEMENT_THRESHOLD) {
61+
return;
62+
}
63+
64+
event.preventDefault();
65+
66+
const ratio = distance / this._startDistance;
67+
const nextScale = this._clamp(this._startScale * ratio);
68+
69+
this._canvas.setScale(nextScale, this._castPositionToFlow(center));
70+
this._canvas.redraw();
71+
}
72+
73+
private _clamp(value: number): number {
74+
return Math.max(this._zoomComponent.minimum, Math.min(value, this._zoomComponent.maximum));
75+
}
76+
77+
private _castPositionToFlow(position: IPoint): IPoint {
78+
return Point.fromPoint(position).elementTransform(this._flowHost);
79+
}
80+
81+
private _reset(): void {
82+
this._startScale = null;
83+
this._startDistance = null;
84+
}
85+
86+
public override onPointerUp(): void {
87+
this._reset();
88+
this._canvas.emitCanvasChangeEvent();
89+
}
90+
}
91+
92+
function calculateTouchCenter(touches: TouchList): IPoint | null {
93+
if (touches.length !== 2) {
94+
return null;
95+
}
96+
97+
const a = touches[0];
98+
const b = touches[1];
99+
100+
return PointExtensions.initialize((a.clientX + b.clientX) / 2, (a.clientY + b.clientY) / 2);
101+
}
102+
103+
function calculateTouchDistance(touches: TouchList): number | null {
104+
if (touches.length !== 2) {
105+
return null;
106+
}
107+
108+
const a = touches[0];
109+
const b = touches[1];
110+
111+
return Math.hypot(b.clientX - a.clientX, b.clientY - a.clientY);
112+
}
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
export * from './constants';
21
export * from './finalize';
2+
export * from './handler';
33
export * from './preparation';
4-
export * from './utils';
5-
export * from './pinch-to-zoom-handler';
64
export * from './providers';

0 commit comments

Comments
 (0)