-
-
Notifications
You must be signed in to change notification settings - Fork 422
/
ZoomHandler.ts
154 lines (143 loc) · 4.58 KB
/
ZoomHandler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { fabric } from 'fabric';
import { VideoObject } from '../objects/Video';
import { FabricObject } from '../utils';
import Handler from './Handler';
class ZoomHandler {
handler?: Handler;
private _zoomStep?: number;
constructor(handler: Handler, zoomStep: number = 0.05) {
this.handler = handler;
this._zoomStep = zoomStep;
}
/**
* Zoom to point
*
* @param {fabric.Point} point
* @param {number} zoom ex) 0 ~ 1. Not percentage value.
*/
public zoomToPoint = (point: fabric.Point, zoom: number) => {
const { minZoom, maxZoom } = this.handler;
let zoomRatio = zoom;
if (zoom <= minZoom / 100) {
zoomRatio = minZoom / 100;
} else if (zoom >= maxZoom / 100) {
zoomRatio = maxZoom / 100;
}
this.handler.canvas.zoomToPoint(point, zoomRatio);
this.handler.getObjects().forEach(obj => {
if (obj.superType === 'element') {
const { id, width, height, player } = obj as VideoObject;
const el = this.handler.elementHandler.findById(id);
// update the element
this.handler.elementHandler.setScaleOrAngle(el, obj);
this.handler.elementHandler.setSize(el, obj);
this.handler.elementHandler.setPosition(el, obj);
if (player) {
player.setPlayerSize(width, height);
}
}
});
if (this.handler.onZoom) {
this.handler.onZoom(zoomRatio);
}
this.handler.canvas.requestRenderAll();
};
/**
* Zoom one to one
*
*/
public zoomOneToOne = () => {
const center = this.handler.canvas.getCenter();
this.handler.canvas.setViewportTransform([1, 0, 0, 1, 0, 0]);
this.zoomToPoint(new fabric.Point(center.left, center.top), 1);
};
/**
* Zoom to fit
*
*/
public zoomToFit = () => {
let scaleX = this.handler.canvas.getWidth() / this.handler.workarea.width;
const scaleY = this.handler.canvas.getHeight() / this.handler.workarea.height;
if (this.handler.workarea.height >= this.handler.workarea.width) {
scaleX = scaleY;
if (this.handler.canvas.getWidth() < this.handler.workarea.width * scaleX) {
scaleX = scaleX * (this.handler.canvas.getWidth() / (this.handler.workarea.width * scaleX));
}
} else {
if (this.handler.canvas.getHeight() < this.handler.workarea.height * scaleX) {
scaleX = scaleX * (this.handler.canvas.getHeight() / (this.handler.workarea.height * scaleX));
}
}
const center = this.handler.canvas.getCenter();
this.handler.canvas.setViewportTransform([1, 0, 0, 1, 0, 0]);
this.zoomToPoint(new fabric.Point(center.left, center.top), scaleX);
};
/**
* Zoom in
*
*/
public zoomIn = () => {
let zoomRatio = this.handler.canvas.getZoom();
zoomRatio += this._zoomStep;
const center = this.handler.canvas.getCenter();
this.zoomToPoint(new fabric.Point(center.left, center.top), zoomRatio);
};
/**
* Zoom out
*
*/
public zoomOut = () => {
let zoomRatio = this.handler.canvas.getZoom();
zoomRatio -= this._zoomStep;
const center = this.handler.canvas.getCenter();
this.zoomToPoint(new fabric.Point(center.left, center.top), zoomRatio);
};
/**
* Zoom to center with object
*
* @param {FabricObject} target If zoomFit true, rescaled canvas zoom.
*/
public zoomToCenterWithObject = (target: FabricObject, zoomFit?: boolean) => {
const { left: canvasLeft, top: canvasTop } = this.handler.canvas.getCenter();
const { left, top, width, height } = target;
const diffTop = canvasTop - (top + height / 2);
const diffLeft = canvasLeft - (left + width / 2);
if (zoomFit) {
let scaleX;
let scaleY;
scaleX = this.handler.canvas.getWidth() / width;
scaleY = this.handler.canvas.getHeight() / height;
if (height > width) {
scaleX = scaleY;
if (this.handler.canvas.getWidth() < width * scaleX) {
scaleX = scaleX * (this.handler.canvas.getWidth() / (width * scaleX));
}
} else {
scaleY = scaleX;
if (this.handler.canvas.getHeight() < height * scaleX) {
scaleX = scaleX * (this.handler.canvas.getHeight() / (height * scaleX));
}
}
this.handler.canvas.setViewportTransform([1, 0, 0, 1, diffLeft, diffTop]);
this.zoomToPoint(new fabric.Point(canvasLeft, canvasTop), scaleX);
} else {
const zoom = this.handler.canvas.getZoom();
this.handler.canvas.setViewportTransform([1, 0, 0, 1, diffLeft, diffTop]);
this.zoomToPoint(new fabric.Point(canvasLeft, canvasTop), zoom);
}
};
/**
* Zoom to center with objects
*
* @param {boolean} [zoomFit] If zoomFit true, rescaled canvas zoom.
* @returns
*/
public zoomToCenter = (zoomFit?: boolean) => {
const activeObject = this.handler.canvas.getActiveObject();
if (!activeObject) {
return;
}
this.zoomToCenterWithObject(activeObject, zoomFit);
};
}
export default ZoomHandler;