@leafer-in/viewport 1.1.1
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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/viewport.cjs +353 -0
- package/dist/viewport.esm.js +346 -0
- package/dist/viewport.esm.min.js +1 -0
- package/dist/viewport.js +357 -0
- package/dist/viewport.min.cjs +1 -0
- package/dist/viewport.min.js +1 -0
- package/package.json +41 -0
- package/src/Leafer.ts +46 -0
- package/src/LeaferTypeCreator.ts +34 -0
- package/src/index.ts +9 -0
- package/src/interaction/Dragger.ts +73 -0
- package/src/interaction/Interaction.ts +63 -0
- package/src/interaction/MultiTouchHelper.ts +23 -0
- package/src/interaction/Transformer.ts +98 -0
- package/src/interaction/WheelEventHelper.ts +48 -0
- package/src/type/custom.ts +8 -0
- package/src/type/design.ts +17 -0
- package/src/type/document.ts +11 -0
- package/src/type/viewport.ts +32 -0
- package/types/index.d.ts +40 -0
package/dist/viewport.js
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
this.LeaferIN = this.LeaferIN || {};
|
|
2
|
+
this.LeaferIN.viewport = (function (exports, core) {
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
function addViewport(leafer, mergeConfig, custom) {
|
|
6
|
+
addViewportConfig(leafer.parentApp ? leafer.parentApp : leafer, mergeConfig);
|
|
7
|
+
if (leafer.isApp || custom)
|
|
8
|
+
return;
|
|
9
|
+
leafer.__eventIds.push(leafer.on_(core.MoveEvent.BEFORE_MOVE, (e) => {
|
|
10
|
+
leafer.zoomLayer.move(leafer.getValidMove(e.moveX, e.moveY));
|
|
11
|
+
}), leafer.on_(core.ZoomEvent.BEFORE_ZOOM, (e) => {
|
|
12
|
+
const { zoomLayer } = leafer;
|
|
13
|
+
const changeScale = leafer.getValidScale(e.scale);
|
|
14
|
+
if (changeScale !== 1) {
|
|
15
|
+
core.PointHelper.scaleOf(zoomLayer, e, changeScale);
|
|
16
|
+
zoomLayer.scale = zoomLayer.__.scaleX * changeScale;
|
|
17
|
+
}
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function addViewportConfig(leafer, mergeConfig) {
|
|
21
|
+
if (mergeConfig)
|
|
22
|
+
core.DataHelper.assign(leafer.config, mergeConfig);
|
|
23
|
+
core.DataHelper.assign(leafer.config, {
|
|
24
|
+
wheel: { preventDefault: true },
|
|
25
|
+
touch: { preventDefault: true },
|
|
26
|
+
pointer: { preventDefaultMenu: true }
|
|
27
|
+
}, leafer.userConfig);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function custom(leafer) {
|
|
31
|
+
addViewport(leafer, null, true);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function design(leafer) {
|
|
35
|
+
addViewport(leafer, {
|
|
36
|
+
zoom: {
|
|
37
|
+
min: 0.01,
|
|
38
|
+
max: 256
|
|
39
|
+
},
|
|
40
|
+
move: {
|
|
41
|
+
holdSpaceKey: true,
|
|
42
|
+
holdMiddleKey: true,
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function document(leafer) {
|
|
48
|
+
addViewport(leafer, {
|
|
49
|
+
zoom: { min: 1 },
|
|
50
|
+
move: { scroll: 'limit' }
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const debug = core.Debug.get('LeaferTypeCreator');
|
|
55
|
+
const LeaferTypeCreator = {
|
|
56
|
+
list: {},
|
|
57
|
+
register(name, fn) {
|
|
58
|
+
list[name] && debug.repeat(name);
|
|
59
|
+
list[name] = fn;
|
|
60
|
+
},
|
|
61
|
+
run(name, leafer) {
|
|
62
|
+
const fn = list[name];
|
|
63
|
+
fn && fn(leafer);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const { list, register } = LeaferTypeCreator;
|
|
67
|
+
register('viewport', addViewport);
|
|
68
|
+
register('custom', custom);
|
|
69
|
+
register('design', design);
|
|
70
|
+
register('document', document);
|
|
71
|
+
|
|
72
|
+
const MultiTouchHelper = {
|
|
73
|
+
getData(list) {
|
|
74
|
+
const a = list[0], b = list[1];
|
|
75
|
+
const lastCenter = core.PointHelper.getCenter(a.from, b.from);
|
|
76
|
+
const center = core.PointHelper.getCenter(a.to, b.to);
|
|
77
|
+
const move = { x: center.x - lastCenter.x, y: center.y - lastCenter.y };
|
|
78
|
+
const lastDistance = core.PointHelper.getDistance(a.from, b.from);
|
|
79
|
+
const distance = core.PointHelper.getDistance(a.to, b.to);
|
|
80
|
+
const scale = distance / lastDistance;
|
|
81
|
+
const rotation = core.PointHelper.getRotation(a.from, b.from, a.to, b.to);
|
|
82
|
+
return { move, scale, rotation, center };
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const WheelEventHelper = {
|
|
87
|
+
getMove(event, config) {
|
|
88
|
+
let { moveSpeed } = config;
|
|
89
|
+
let { deltaX, deltaY } = event;
|
|
90
|
+
if (event.shiftKey && !deltaX) {
|
|
91
|
+
deltaX = deltaY;
|
|
92
|
+
deltaY = 0;
|
|
93
|
+
}
|
|
94
|
+
if (deltaX > 50)
|
|
95
|
+
deltaX = Math.max(50, deltaX / 3);
|
|
96
|
+
if (deltaY > 50)
|
|
97
|
+
deltaY = Math.max(50, deltaY / 3);
|
|
98
|
+
return { x: -deltaX * moveSpeed * 2, y: -deltaY * moveSpeed * 2 };
|
|
99
|
+
},
|
|
100
|
+
getScale(event, config) {
|
|
101
|
+
let zoom;
|
|
102
|
+
let scale = 1;
|
|
103
|
+
let { zoomMode, zoomSpeed } = config;
|
|
104
|
+
const delta = event.deltaY || event.deltaX;
|
|
105
|
+
if (zoomMode) {
|
|
106
|
+
zoom = (zoomMode === 'mouse') ? true : (!event.deltaX && (core.Platform.intWheelDeltaY ? Math.abs(delta) > 17 : Math.ceil(delta) !== delta));
|
|
107
|
+
if (event.shiftKey || event.metaKey || event.ctrlKey)
|
|
108
|
+
zoom = true;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
zoom = !event.shiftKey && (event.metaKey || event.ctrlKey);
|
|
112
|
+
}
|
|
113
|
+
if (zoom) {
|
|
114
|
+
zoomSpeed = core.MathHelper.within(zoomSpeed, 0, 1);
|
|
115
|
+
const min = event.deltaY ? config.delta.y : config.delta.x;
|
|
116
|
+
scale = 1 - delta / (min * 4) * zoomSpeed;
|
|
117
|
+
if (scale < 0.5)
|
|
118
|
+
scale = 0.5;
|
|
119
|
+
if (scale >= 1.5)
|
|
120
|
+
scale = 1.5;
|
|
121
|
+
}
|
|
122
|
+
return scale;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
class Transformer {
|
|
127
|
+
get transforming() { return !!(this.moveData || this.zoomData || this.rotateData); }
|
|
128
|
+
constructor(interaction) {
|
|
129
|
+
this.interaction = interaction;
|
|
130
|
+
}
|
|
131
|
+
move(data) {
|
|
132
|
+
const { interaction } = this;
|
|
133
|
+
if (!data.moveType)
|
|
134
|
+
data.moveType = 'move';
|
|
135
|
+
if (!this.moveData) {
|
|
136
|
+
this.setPath(data);
|
|
137
|
+
this.moveData = Object.assign(Object.assign({}, data), { moveX: 0, moveY: 0 });
|
|
138
|
+
interaction.emit(core.MoveEvent.START, this.moveData);
|
|
139
|
+
}
|
|
140
|
+
data.path = this.moveData.path;
|
|
141
|
+
interaction.emit(core.MoveEvent.BEFORE_MOVE, data);
|
|
142
|
+
interaction.emit(core.MoveEvent.MOVE, data);
|
|
143
|
+
this.transformEndWait();
|
|
144
|
+
}
|
|
145
|
+
zoom(data) {
|
|
146
|
+
const { interaction } = this;
|
|
147
|
+
if (!this.zoomData) {
|
|
148
|
+
this.setPath(data);
|
|
149
|
+
this.zoomData = Object.assign(Object.assign({}, data), { scale: 1 });
|
|
150
|
+
interaction.emit(core.ZoomEvent.START, this.zoomData);
|
|
151
|
+
}
|
|
152
|
+
data.path = this.zoomData.path;
|
|
153
|
+
interaction.emit(core.ZoomEvent.BEFORE_ZOOM, data);
|
|
154
|
+
interaction.emit(core.ZoomEvent.ZOOM, data);
|
|
155
|
+
this.transformEndWait();
|
|
156
|
+
}
|
|
157
|
+
rotate(data) {
|
|
158
|
+
const { interaction } = this;
|
|
159
|
+
if (!this.rotateData) {
|
|
160
|
+
this.setPath(data);
|
|
161
|
+
this.rotateData = Object.assign(Object.assign({}, data), { rotation: 0 });
|
|
162
|
+
interaction.emit(core.RotateEvent.START, this.rotateData);
|
|
163
|
+
}
|
|
164
|
+
data.path = this.rotateData.path;
|
|
165
|
+
interaction.emit(core.RotateEvent.BEFORE_ROTATE, data);
|
|
166
|
+
interaction.emit(core.RotateEvent.ROTATE, data);
|
|
167
|
+
this.transformEndWait();
|
|
168
|
+
}
|
|
169
|
+
setPath(data) {
|
|
170
|
+
const { interaction } = this;
|
|
171
|
+
const { path } = interaction.selector.getByPoint(data, interaction.hitRadius);
|
|
172
|
+
data.path = path;
|
|
173
|
+
interaction.cancelHover();
|
|
174
|
+
}
|
|
175
|
+
transformEndWait() {
|
|
176
|
+
clearTimeout(this.transformTimer);
|
|
177
|
+
this.transformTimer = setTimeout(() => {
|
|
178
|
+
this.transformEnd();
|
|
179
|
+
}, this.interaction.p.transformTime);
|
|
180
|
+
}
|
|
181
|
+
transformEnd() {
|
|
182
|
+
const { interaction, moveData, zoomData, rotateData } = this;
|
|
183
|
+
if (moveData)
|
|
184
|
+
interaction.emit(core.MoveEvent.END, moveData);
|
|
185
|
+
if (zoomData)
|
|
186
|
+
interaction.emit(core.ZoomEvent.END, zoomData);
|
|
187
|
+
if (rotateData)
|
|
188
|
+
interaction.emit(core.RotateEvent.END, rotateData);
|
|
189
|
+
this.reset();
|
|
190
|
+
}
|
|
191
|
+
reset() {
|
|
192
|
+
this.zoomData = this.moveData = this.rotateData = null;
|
|
193
|
+
}
|
|
194
|
+
destroy() {
|
|
195
|
+
this.reset();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const leafer = core.Leafer.prototype;
|
|
200
|
+
const bounds = new core.Bounds();
|
|
201
|
+
leafer.initType = function (type) {
|
|
202
|
+
LeaferTypeCreator.run(type, this);
|
|
203
|
+
};
|
|
204
|
+
leafer.getValidMove = function (moveX, moveY) {
|
|
205
|
+
const { scroll, disabled } = this.app.config.move;
|
|
206
|
+
if (scroll) {
|
|
207
|
+
const type = scroll === true ? '' : scroll;
|
|
208
|
+
if (type.includes('x'))
|
|
209
|
+
moveX = moveX || moveY, moveY = 0;
|
|
210
|
+
else if (type.includes('y'))
|
|
211
|
+
moveY = moveY || moveX, moveX = 0;
|
|
212
|
+
else
|
|
213
|
+
Math.abs(moveX) > Math.abs(moveY) ? moveY = 0 : moveX = 0;
|
|
214
|
+
if (type.includes('limit')) {
|
|
215
|
+
const { x, y, width, height } = bounds.set(this.__world).addPoint(this.zoomLayer);
|
|
216
|
+
const right = x + width - this.width, bottom = y + height - this.height;
|
|
217
|
+
if (x >= 0 && right <= 0)
|
|
218
|
+
moveX = 0;
|
|
219
|
+
else if (moveX > 0) {
|
|
220
|
+
if (x + moveX > 0)
|
|
221
|
+
moveX = -x;
|
|
222
|
+
}
|
|
223
|
+
else if (moveX < 0 && right + moveX < 0)
|
|
224
|
+
moveX = -right;
|
|
225
|
+
if (y >= 0 && bottom <= 0)
|
|
226
|
+
moveY = 0;
|
|
227
|
+
else if (moveY > 0) {
|
|
228
|
+
if (y + moveY > 0)
|
|
229
|
+
moveY = -y;
|
|
230
|
+
}
|
|
231
|
+
else if (moveY < 0 && bottom + moveY < 0)
|
|
232
|
+
moveY = -bottom;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return { x: disabled ? 0 : moveX, y: disabled ? 0 : moveY };
|
|
236
|
+
};
|
|
237
|
+
leafer.getValidScale = function (changeScale) {
|
|
238
|
+
const { scaleX } = this.zoomLayer.__, { min, max, disabled } = this.app.config.zoom, absScale = Math.abs(scaleX * changeScale);
|
|
239
|
+
if (min && absScale < min)
|
|
240
|
+
changeScale = min / scaleX;
|
|
241
|
+
else if (max && absScale > max)
|
|
242
|
+
changeScale = max / scaleX;
|
|
243
|
+
return disabled ? 1 : core.MathHelper.float(changeScale);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
function getMoveEventData(move, event) {
|
|
247
|
+
return Object.assign(Object.assign({}, event), { moveX: move.x, moveY: move.y });
|
|
248
|
+
}
|
|
249
|
+
function getRotateEventData(rotation, event) {
|
|
250
|
+
return Object.assign(Object.assign({}, event), { rotation });
|
|
251
|
+
}
|
|
252
|
+
function getZoomEventData(scale, event) {
|
|
253
|
+
return Object.assign(Object.assign({}, event), { scale });
|
|
254
|
+
}
|
|
255
|
+
const interaction = core.InteractionBase.prototype;
|
|
256
|
+
interaction.createTransformer = function () {
|
|
257
|
+
this.transformer = new Transformer(this);
|
|
258
|
+
};
|
|
259
|
+
interaction.move = function (data) {
|
|
260
|
+
this.transformer.move(data);
|
|
261
|
+
};
|
|
262
|
+
interaction.zoom = function (data) {
|
|
263
|
+
this.transformer.zoom(data);
|
|
264
|
+
};
|
|
265
|
+
interaction.rotate = function (data) {
|
|
266
|
+
this.transformer.rotate(data);
|
|
267
|
+
};
|
|
268
|
+
interaction.transformEnd = function () {
|
|
269
|
+
this.transformer.transformEnd();
|
|
270
|
+
};
|
|
271
|
+
interaction.wheel = function (data) {
|
|
272
|
+
const { wheel } = this.config;
|
|
273
|
+
if (wheel.disabled)
|
|
274
|
+
return;
|
|
275
|
+
const scale = wheel.getScale ? wheel.getScale(data, wheel) : WheelEventHelper.getScale(data, wheel);
|
|
276
|
+
scale !== 1 ? this.zoom(getZoomEventData(scale, data)) : this.move(getMoveEventData(wheel.getMove ? wheel.getMove(data, wheel) : WheelEventHelper.getMove(data, wheel), data));
|
|
277
|
+
};
|
|
278
|
+
interaction.multiTouch = function (data, list) {
|
|
279
|
+
if (this.config.multiTouch.disabled)
|
|
280
|
+
return;
|
|
281
|
+
const { move, rotation, scale, center } = MultiTouchHelper.getData(list);
|
|
282
|
+
Object.assign(data, center);
|
|
283
|
+
this.rotate(getRotateEventData(rotation, data));
|
|
284
|
+
this.zoom(getZoomEventData(scale, data));
|
|
285
|
+
this.move(getMoveEventData(move, data));
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const dragger = core.Dragger.prototype;
|
|
289
|
+
const { abs } = Math;
|
|
290
|
+
dragger.checkDragEndAnimate = function (data, speed) {
|
|
291
|
+
const { moveX, moveY } = this.dragData;
|
|
292
|
+
const absMoveX = abs(moveX), absMoveY = abs(moveY), minMove = speed ? 1 : 0.1;
|
|
293
|
+
const dragAnimate = this.interaction.m.dragAnimate && this.canAnimate && this.moving && (absMoveX > minMove || absMoveY > minMove);
|
|
294
|
+
if (dragAnimate) {
|
|
295
|
+
const inertia = data.pointerType === 'touch' ? 3 : 1, maxMove = 70;
|
|
296
|
+
speed = speed ? 0.95 : inertia;
|
|
297
|
+
if (absMoveX * speed > maxMove)
|
|
298
|
+
speed = maxMove / absMoveX;
|
|
299
|
+
else if (absMoveY * speed > maxMove)
|
|
300
|
+
speed = maxMove / absMoveY;
|
|
301
|
+
data = Object.assign({}, data);
|
|
302
|
+
core.PointHelper.move(data, moveX * speed, moveY * speed);
|
|
303
|
+
this.drag(data);
|
|
304
|
+
this.animate(() => { this.dragEnd(data, 1); });
|
|
305
|
+
}
|
|
306
|
+
return dragAnimate;
|
|
307
|
+
};
|
|
308
|
+
dragger.animate = function (func, off) {
|
|
309
|
+
const animateWait = func || this.animateWait;
|
|
310
|
+
if (animateWait)
|
|
311
|
+
this.interaction.target.nextRender(animateWait, null, off);
|
|
312
|
+
this.animateWait = func;
|
|
313
|
+
};
|
|
314
|
+
dragger.checkDragOut = function (data) {
|
|
315
|
+
const { interaction } = this;
|
|
316
|
+
this.autoMoveCancel();
|
|
317
|
+
if (this.dragging && !interaction.shrinkCanvasBounds.hitPoint(data))
|
|
318
|
+
this.autoMoveOnDragOut(data);
|
|
319
|
+
};
|
|
320
|
+
dragger.autoMoveOnDragOut = function (data) {
|
|
321
|
+
const { interaction, downData, canDragOut } = this;
|
|
322
|
+
const { autoDistance, dragOut } = interaction.m;
|
|
323
|
+
if (!dragOut || !canDragOut || !autoDistance)
|
|
324
|
+
return;
|
|
325
|
+
const bounds = interaction.shrinkCanvasBounds;
|
|
326
|
+
const { x, y } = bounds;
|
|
327
|
+
const right = core.BoundsHelper.maxX(bounds);
|
|
328
|
+
const bottom = core.BoundsHelper.maxY(bounds);
|
|
329
|
+
const moveX = data.x < x ? autoDistance : (right < data.x ? -autoDistance : 0);
|
|
330
|
+
const moveY = data.y < y ? autoDistance : (bottom < data.y ? -autoDistance : 0);
|
|
331
|
+
let totalX = 0, totalY = 0;
|
|
332
|
+
this.autoMoveTimer = setInterval(() => {
|
|
333
|
+
totalX += moveX;
|
|
334
|
+
totalY += moveY;
|
|
335
|
+
core.PointHelper.move(downData, moveX, moveY);
|
|
336
|
+
core.PointHelper.move(this.dragData, moveX, moveY);
|
|
337
|
+
interaction.move(Object.assign(Object.assign({}, data), { moveX, moveY, totalX, totalY, moveType: 'drag' }));
|
|
338
|
+
interaction.pointerMoveReal(data);
|
|
339
|
+
}, 10);
|
|
340
|
+
};
|
|
341
|
+
dragger.autoMoveCancel = function () {
|
|
342
|
+
if (this.autoMoveTimer) {
|
|
343
|
+
clearInterval(this.autoMoveTimer);
|
|
344
|
+
this.autoMoveTimer = 0;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
exports.LeaferTypeCreator = LeaferTypeCreator;
|
|
349
|
+
exports.MultiTouchHelper = MultiTouchHelper;
|
|
350
|
+
exports.Transformer = Transformer;
|
|
351
|
+
exports.WheelEventHelper = WheelEventHelper;
|
|
352
|
+
exports.addViewport = addViewport;
|
|
353
|
+
exports.addViewportConfig = addViewportConfig;
|
|
354
|
+
|
|
355
|
+
return exports;
|
|
356
|
+
|
|
357
|
+
})({}, LeaferUI);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var t=require("@leafer-ui/core");function e(e,a,i){o(e.parentApp?e.parentApp:e,a),e.isApp||i||e.__eventIds.push(e.on_(t.MoveEvent.BEFORE_MOVE,(t=>{e.zoomLayer.move(e.getValidMove(t.moveX,t.moveY))})),e.on_(t.ZoomEvent.BEFORE_ZOOM,(o=>{const{zoomLayer:a}=e,i=e.getValidScale(o.scale);1!==i&&(t.PointHelper.scaleOf(a,o,i),a.scale=a.__.scaleX*i)})))}function o(e,o){o&&t.DataHelper.assign(e.config,o),t.DataHelper.assign(e.config,{wheel:{preventDefault:!0},touch:{preventDefault:!0},pointer:{preventDefaultMenu:!0}},e.userConfig)}const a=t.Debug.get("LeaferTypeCreator"),i={list:{},register(t,e){n[t]&&a.repeat(t),n[t]=e},run(t,e){const o=n[t];o&&o(e)}},{list:n,register:s}=i;s("viewport",e),s("custom",(function(t){e(t,null,!0)})),s("design",(function(t){e(t,{zoom:{min:.01,max:256},move:{holdSpaceKey:!0,holdMiddleKey:!0}})})),s("document",(function(t){e(t,{zoom:{min:1},move:{scroll:"limit"}})}));const r={getData(e){const o=e[0],a=e[1],i=t.PointHelper.getCenter(o.from,a.from),n=t.PointHelper.getCenter(o.to,a.to),s={x:n.x-i.x,y:n.y-i.y},r=t.PointHelper.getDistance(o.from,a.from);return{move:s,scale:t.PointHelper.getDistance(o.to,a.to)/r,rotation:t.PointHelper.getRotation(o.from,a.from,o.to,a.to),center:n}}},c={getMove(t,e){let{moveSpeed:o}=e,{deltaX:a,deltaY:i}=t;return t.shiftKey&&!a&&(a=i,i=0),a>50&&(a=Math.max(50,a/3)),i>50&&(i=Math.max(50,i/3)),{x:-a*o*2,y:-i*o*2}},getScale(e,o){let a,i=1,{zoomMode:n,zoomSpeed:s}=o;const r=e.deltaY||e.deltaX;if(n?(a="mouse"===n||!e.deltaX&&(t.Platform.intWheelDeltaY?Math.abs(r)>17:Math.ceil(r)!==r),(e.shiftKey||e.metaKey||e.ctrlKey)&&(a=!0)):a=!e.shiftKey&&(e.metaKey||e.ctrlKey),a){s=t.MathHelper.within(s,0,1);i=1-r/(4*(e.deltaY?o.delta.y:o.delta.x))*s,i<.5&&(i=.5),i>=1.5&&(i=1.5)}return i}};class m{get transforming(){return!!(this.moveData||this.zoomData||this.rotateData)}constructor(t){this.interaction=t}move(e){const{interaction:o}=this;e.moveType||(e.moveType="move"),this.moveData||(this.setPath(e),this.moveData=Object.assign(Object.assign({},e),{moveX:0,moveY:0}),o.emit(t.MoveEvent.START,this.moveData)),e.path=this.moveData.path,o.emit(t.MoveEvent.BEFORE_MOVE,e),o.emit(t.MoveEvent.MOVE,e),this.transformEndWait()}zoom(e){const{interaction:o}=this;this.zoomData||(this.setPath(e),this.zoomData=Object.assign(Object.assign({},e),{scale:1}),o.emit(t.ZoomEvent.START,this.zoomData)),e.path=this.zoomData.path,o.emit(t.ZoomEvent.BEFORE_ZOOM,e),o.emit(t.ZoomEvent.ZOOM,e),this.transformEndWait()}rotate(e){const{interaction:o}=this;this.rotateData||(this.setPath(e),this.rotateData=Object.assign(Object.assign({},e),{rotation:0}),o.emit(t.RotateEvent.START,this.rotateData)),e.path=this.rotateData.path,o.emit(t.RotateEvent.BEFORE_ROTATE,e),o.emit(t.RotateEvent.ROTATE,e),this.transformEndWait()}setPath(t){const{interaction:e}=this,{path:o}=e.selector.getByPoint(t,e.hitRadius);t.path=o,e.cancelHover()}transformEndWait(){clearTimeout(this.transformTimer),this.transformTimer=setTimeout((()=>{this.transformEnd()}),this.interaction.p.transformTime)}transformEnd(){const{interaction:e,moveData:o,zoomData:a,rotateData:i}=this;o&&e.emit(t.MoveEvent.END,o),a&&e.emit(t.ZoomEvent.END,a),i&&e.emit(t.RotateEvent.END,i),this.reset()}reset(){this.zoomData=this.moveData=this.rotateData=null}destroy(){this.reset()}}const h=t.Leafer.prototype,l=new t.Bounds;function u(t,e){return Object.assign(Object.assign({},e),{moveX:t.x,moveY:t.y})}function v(t,e){return Object.assign(Object.assign({},e),{scale:t})}h.initType=function(t){i.run(t,this)},h.getValidMove=function(t,e){const{scroll:o,disabled:a}=this.app.config.move;if(o){const a=!0===o?"":o;if(a.includes("x")?(t=t||e,e=0):a.includes("y")?(e=e||t,t=0):Math.abs(t)>Math.abs(e)?e=0:t=0,a.includes("limit")){const{x:o,y:a,width:i,height:n}=l.set(this.__world).addPoint(this.zoomLayer),s=o+i-this.width,r=a+n-this.height;o>=0&&s<=0?t=0:t>0?o+t>0&&(t=-o):t<0&&s+t<0&&(t=-s),a>=0&&r<=0?e=0:e>0?a+e>0&&(e=-a):e<0&&r+e<0&&(e=-r)}}return{x:a?0:t,y:a?0:e}},h.getValidScale=function(e){const{scaleX:o}=this.zoomLayer.__,{min:a,max:i,disabled:n}=this.app.config.zoom,s=Math.abs(o*e);return a&&s<a?e=a/o:i&&s>i&&(e=i/o),n?1:t.MathHelper.float(e)};const f=t.InteractionBase.prototype;f.createTransformer=function(){this.transformer=new m(this)},f.move=function(t){this.transformer.move(t)},f.zoom=function(t){this.transformer.zoom(t)},f.rotate=function(t){this.transformer.rotate(t)},f.transformEnd=function(){this.transformer.transformEnd()},f.wheel=function(t){const{wheel:e}=this.config;if(e.disabled)return;const o=e.getScale?e.getScale(t,e):c.getScale(t,e);1!==o?this.zoom(v(o,t)):this.move(u(e.getMove?e.getMove(t,e):c.getMove(t,e),t))},f.multiTouch=function(t,e){if(this.config.multiTouch.disabled)return;const{move:o,rotation:a,scale:i,center:n}=r.getData(e);Object.assign(t,n),this.rotate(function(t,e){return Object.assign(Object.assign({},e),{rotation:t})}(a,t)),this.zoom(v(i,t)),this.move(u(o,t))};const g=t.Dragger.prototype,{abs:p}=Math;g.checkDragEndAnimate=function(e,o){const{moveX:a,moveY:i}=this.dragData,n=p(a),s=p(i),r=o?1:.1,c=this.interaction.m.dragAnimate&&this.canAnimate&&this.moving&&(n>r||s>r);if(c){const r="touch"===e.pointerType?3:1,c=70;n*(o=o?.95:r)>c?o=c/n:s*o>c&&(o=c/s),e=Object.assign({},e),t.PointHelper.move(e,a*o,i*o),this.drag(e),this.animate((()=>{this.dragEnd(e,1)}))}return c},g.animate=function(t,e){const o=t||this.animateWait;o&&this.interaction.target.nextRender(o,null,e),this.animateWait=t},g.checkDragOut=function(t){const{interaction:e}=this;this.autoMoveCancel(),this.dragging&&!e.shrinkCanvasBounds.hitPoint(t)&&this.autoMoveOnDragOut(t)},g.autoMoveOnDragOut=function(e){const{interaction:o,downData:a,canDragOut:i}=this,{autoDistance:n,dragOut:s}=o.m;if(!s||!i||!n)return;const r=o.shrinkCanvasBounds,{x:c,y:m}=r,h=t.BoundsHelper.maxX(r),l=t.BoundsHelper.maxY(r),u=e.x<c?n:h<e.x?-n:0,v=e.y<m?n:l<e.y?-n:0;let f=0,g=0;this.autoMoveTimer=setInterval((()=>{f+=u,g+=v,t.PointHelper.move(a,u,v),t.PointHelper.move(this.dragData,u,v),o.move(Object.assign(Object.assign({},e),{moveX:u,moveY:v,totalX:f,totalY:g,moveType:"drag"})),o.pointerMoveReal(e)}),10)},g.autoMoveCancel=function(){this.autoMoveTimer&&(clearInterval(this.autoMoveTimer),this.autoMoveTimer=0)},exports.LeaferTypeCreator=i,exports.MultiTouchHelper=r,exports.Transformer=m,exports.WheelEventHelper=c,exports.addViewport=e,exports.addViewportConfig=o;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
this.LeaferIN=this.LeaferIN||{},this.LeaferIN.viewport=function(t,e){"use strict";function o(t,o,i){a(t.parentApp?t.parentApp:t,o),t.isApp||i||t.__eventIds.push(t.on_(e.MoveEvent.BEFORE_MOVE,(e=>{t.zoomLayer.move(t.getValidMove(e.moveX,e.moveY))})),t.on_(e.ZoomEvent.BEFORE_ZOOM,(o=>{const{zoomLayer:a}=t,i=t.getValidScale(o.scale);1!==i&&(e.PointHelper.scaleOf(a,o,i),a.scale=a.__.scaleX*i)})))}function a(t,o){o&&e.DataHelper.assign(t.config,o),e.DataHelper.assign(t.config,{wheel:{preventDefault:!0},touch:{preventDefault:!0},pointer:{preventDefaultMenu:!0}},t.userConfig)}const i=e.Debug.get("LeaferTypeCreator"),n={list:{},register(t,e){s[t]&&i.repeat(t),s[t]=e},run(t,e){const o=s[t];o&&o(e)}},{list:s,register:r}=n;r("viewport",o),r("custom",(function(t){o(t,null,!0)})),r("design",(function(t){o(t,{zoom:{min:.01,max:256},move:{holdSpaceKey:!0,holdMiddleKey:!0}})})),r("document",(function(t){o(t,{zoom:{min:1},move:{scroll:"limit"}})}));const c={getData(t){const o=t[0],a=t[1],i=e.PointHelper.getCenter(o.from,a.from),n=e.PointHelper.getCenter(o.to,a.to),s={x:n.x-i.x,y:n.y-i.y},r=e.PointHelper.getDistance(o.from,a.from);return{move:s,scale:e.PointHelper.getDistance(o.to,a.to)/r,rotation:e.PointHelper.getRotation(o.from,a.from,o.to,a.to),center:n}}},m={getMove(t,e){let{moveSpeed:o}=e,{deltaX:a,deltaY:i}=t;return t.shiftKey&&!a&&(a=i,i=0),a>50&&(a=Math.max(50,a/3)),i>50&&(i=Math.max(50,i/3)),{x:-a*o*2,y:-i*o*2}},getScale(t,o){let a,i=1,{zoomMode:n,zoomSpeed:s}=o;const r=t.deltaY||t.deltaX;if(n?(a="mouse"===n||!t.deltaX&&(e.Platform.intWheelDeltaY?Math.abs(r)>17:Math.ceil(r)!==r),(t.shiftKey||t.metaKey||t.ctrlKey)&&(a=!0)):a=!t.shiftKey&&(t.metaKey||t.ctrlKey),a){s=e.MathHelper.within(s,0,1);i=1-r/(4*(t.deltaY?o.delta.y:o.delta.x))*s,i<.5&&(i=.5),i>=1.5&&(i=1.5)}return i}};class h{get transforming(){return!!(this.moveData||this.zoomData||this.rotateData)}constructor(t){this.interaction=t}move(t){const{interaction:o}=this;t.moveType||(t.moveType="move"),this.moveData||(this.setPath(t),this.moveData=Object.assign(Object.assign({},t),{moveX:0,moveY:0}),o.emit(e.MoveEvent.START,this.moveData)),t.path=this.moveData.path,o.emit(e.MoveEvent.BEFORE_MOVE,t),o.emit(e.MoveEvent.MOVE,t),this.transformEndWait()}zoom(t){const{interaction:o}=this;this.zoomData||(this.setPath(t),this.zoomData=Object.assign(Object.assign({},t),{scale:1}),o.emit(e.ZoomEvent.START,this.zoomData)),t.path=this.zoomData.path,o.emit(e.ZoomEvent.BEFORE_ZOOM,t),o.emit(e.ZoomEvent.ZOOM,t),this.transformEndWait()}rotate(t){const{interaction:o}=this;this.rotateData||(this.setPath(t),this.rotateData=Object.assign(Object.assign({},t),{rotation:0}),o.emit(e.RotateEvent.START,this.rotateData)),t.path=this.rotateData.path,o.emit(e.RotateEvent.BEFORE_ROTATE,t),o.emit(e.RotateEvent.ROTATE,t),this.transformEndWait()}setPath(t){const{interaction:e}=this,{path:o}=e.selector.getByPoint(t,e.hitRadius);t.path=o,e.cancelHover()}transformEndWait(){clearTimeout(this.transformTimer),this.transformTimer=setTimeout((()=>{this.transformEnd()}),this.interaction.p.transformTime)}transformEnd(){const{interaction:t,moveData:o,zoomData:a,rotateData:i}=this;o&&t.emit(e.MoveEvent.END,o),a&&t.emit(e.ZoomEvent.END,a),i&&t.emit(e.RotateEvent.END,i),this.reset()}reset(){this.zoomData=this.moveData=this.rotateData=null}destroy(){this.reset()}}const l=e.Leafer.prototype,u=new e.Bounds;function v(t,e){return Object.assign(Object.assign({},e),{moveX:t.x,moveY:t.y})}function f(t,e){return Object.assign(Object.assign({},e),{scale:t})}l.initType=function(t){n.run(t,this)},l.getValidMove=function(t,e){const{scroll:o,disabled:a}=this.app.config.move;if(o){const a=!0===o?"":o;if(a.includes("x")?(t=t||e,e=0):a.includes("y")?(e=e||t,t=0):Math.abs(t)>Math.abs(e)?e=0:t=0,a.includes("limit")){const{x:o,y:a,width:i,height:n}=u.set(this.__world).addPoint(this.zoomLayer),s=o+i-this.width,r=a+n-this.height;o>=0&&s<=0?t=0:t>0?o+t>0&&(t=-o):t<0&&s+t<0&&(t=-s),a>=0&&r<=0?e=0:e>0?a+e>0&&(e=-a):e<0&&r+e<0&&(e=-r)}}return{x:a?0:t,y:a?0:e}},l.getValidScale=function(t){const{scaleX:o}=this.zoomLayer.__,{min:a,max:i,disabled:n}=this.app.config.zoom,s=Math.abs(o*t);return a&&s<a?t=a/o:i&&s>i&&(t=i/o),n?1:e.MathHelper.float(t)};const g=e.InteractionBase.prototype;g.createTransformer=function(){this.transformer=new h(this)},g.move=function(t){this.transformer.move(t)},g.zoom=function(t){this.transformer.zoom(t)},g.rotate=function(t){this.transformer.rotate(t)},g.transformEnd=function(){this.transformer.transformEnd()},g.wheel=function(t){const{wheel:e}=this.config;if(e.disabled)return;const o=e.getScale?e.getScale(t,e):m.getScale(t,e);1!==o?this.zoom(f(o,t)):this.move(v(e.getMove?e.getMove(t,e):m.getMove(t,e),t))},g.multiTouch=function(t,e){if(this.config.multiTouch.disabled)return;const{move:o,rotation:a,scale:i,center:n}=c.getData(e);Object.assign(t,n),this.rotate(function(t,e){return Object.assign(Object.assign({},e),{rotation:t})}(a,t)),this.zoom(f(i,t)),this.move(v(o,t))};const d=e.Dragger.prototype,{abs:p}=Math;return d.checkDragEndAnimate=function(t,o){const{moveX:a,moveY:i}=this.dragData,n=p(a),s=p(i),r=o?1:.1,c=this.interaction.m.dragAnimate&&this.canAnimate&&this.moving&&(n>r||s>r);if(c){const r="touch"===t.pointerType?3:1,c=70;n*(o=o?.95:r)>c?o=c/n:s*o>c&&(o=c/s),t=Object.assign({},t),e.PointHelper.move(t,a*o,i*o),this.drag(t),this.animate((()=>{this.dragEnd(t,1)}))}return c},d.animate=function(t,e){const o=t||this.animateWait;o&&this.interaction.target.nextRender(o,null,e),this.animateWait=t},d.checkDragOut=function(t){const{interaction:e}=this;this.autoMoveCancel(),this.dragging&&!e.shrinkCanvasBounds.hitPoint(t)&&this.autoMoveOnDragOut(t)},d.autoMoveOnDragOut=function(t){const{interaction:o,downData:a,canDragOut:i}=this,{autoDistance:n,dragOut:s}=o.m;if(!s||!i||!n)return;const r=o.shrinkCanvasBounds,{x:c,y:m}=r,h=e.BoundsHelper.maxX(r),l=e.BoundsHelper.maxY(r),u=t.x<c?n:h<t.x?-n:0,v=t.y<m?n:l<t.y?-n:0;let f=0,g=0;this.autoMoveTimer=setInterval((()=>{f+=u,g+=v,e.PointHelper.move(a,u,v),e.PointHelper.move(this.dragData,u,v),o.move(Object.assign(Object.assign({},t),{moveX:u,moveY:v,totalX:f,totalY:g,moveType:"drag"})),o.pointerMoveReal(t)}),10)},d.autoMoveCancel=function(){this.autoMoveTimer&&(clearInterval(this.autoMoveTimer),this.autoMoveTimer=0)},t.LeaferTypeCreator=n,t.MultiTouchHelper=c,t.Transformer=h,t.WheelEventHelper=m,t.addViewport=o,t.addViewportConfig=a,t}({},LeaferUI);
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@leafer-in/viewport",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "@leafer-in/viewport",
|
|
5
|
+
"author": "Chao (Leafer) Wan",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/viewport.esm.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
"import": "./dist/viewport.esm.js",
|
|
11
|
+
"require": "./dist/viewport.cjs",
|
|
12
|
+
"types": "./types/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"types": "types/index.d.ts",
|
|
15
|
+
"unpkg": "dist/viewport.js",
|
|
16
|
+
"jsdelivr": "dist/viewport.js",
|
|
17
|
+
"files": [
|
|
18
|
+
"src",
|
|
19
|
+
"types",
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/leaferjs/leafer-in.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/leaferjs/leafer-in/tree/main/packages/viewport",
|
|
27
|
+
"bugs": "https://github.com/leaferjs/leafer-in/issues",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"leafer viewport",
|
|
30
|
+
"leafer-viewport",
|
|
31
|
+
"leafer-in",
|
|
32
|
+
"viewport",
|
|
33
|
+
"leafer-ui",
|
|
34
|
+
"leaferjs"
|
|
35
|
+
],
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@leafer-ui/core": "^1.1.1",
|
|
38
|
+
"@leafer-ui/interface": "^1.1.1",
|
|
39
|
+
"@leafer-in/interface": "^1.1.1"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/Leafer.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ILeaferType, IPointData } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { Leafer, Bounds, MathHelper } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
import { LeaferTypeCreator } from './LeaferTypeCreator'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const leafer = Leafer.prototype
|
|
9
|
+
const bounds = new Bounds()
|
|
10
|
+
|
|
11
|
+
leafer.initType = function (type: ILeaferType) {
|
|
12
|
+
LeaferTypeCreator.run(type, this)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
leafer.getValidMove = function (moveX: number, moveY: number): IPointData {
|
|
16
|
+
const { scroll, disabled } = this.app.config.move
|
|
17
|
+
|
|
18
|
+
if (scroll) {
|
|
19
|
+
const type = scroll === true ? '' : scroll
|
|
20
|
+
|
|
21
|
+
if (type.includes('x')) moveX = moveX || moveY, moveY = 0
|
|
22
|
+
else if (type.includes('y')) moveY = moveY || moveX, moveX = 0
|
|
23
|
+
else Math.abs(moveX) > Math.abs(moveY) ? moveY = 0 : moveX = 0
|
|
24
|
+
|
|
25
|
+
if (type.includes('limit')) {
|
|
26
|
+
const { x, y, width, height } = bounds.set(this.__world).addPoint(this.zoomLayer as IPointData)
|
|
27
|
+
const right = x + width - this.width, bottom = y + height - this.height
|
|
28
|
+
|
|
29
|
+
if (x >= 0 && right <= 0) moveX = 0 // includeX
|
|
30
|
+
else if (moveX > 0) { if (x + moveX > 0) moveX = -x }
|
|
31
|
+
else if (moveX < 0 && right + moveX < 0) moveX = -right
|
|
32
|
+
|
|
33
|
+
if (y >= 0 && bottom <= 0) moveY = 0 // includeY
|
|
34
|
+
else if (moveY > 0) { if (y + moveY > 0) moveY = -y }
|
|
35
|
+
else if (moveY < 0 && bottom + moveY < 0) moveY = -bottom
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { x: disabled ? 0 : moveX, y: disabled ? 0 : moveY }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
leafer.getValidScale = function (changeScale: number): number {
|
|
42
|
+
const { scaleX } = this.zoomLayer.__, { min, max, disabled } = this.app.config.zoom, absScale = Math.abs(scaleX * changeScale)
|
|
43
|
+
if (min && absScale < min) changeScale = min / scaleX
|
|
44
|
+
else if (max && absScale > max) changeScale = max / scaleX
|
|
45
|
+
return disabled ? 1 : MathHelper.float(changeScale)
|
|
46
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ILeaferBase, ILeaferTypeList, ILeaferTypeFunction } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { Debug } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
import { addViewport } from './type/viewport'
|
|
6
|
+
import { custom } from './type/custom'
|
|
7
|
+
import { design } from './type/design'
|
|
8
|
+
import { document } from './type/document'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const debug = Debug.get('LeaferTypeCreator')
|
|
12
|
+
|
|
13
|
+
export const LeaferTypeCreator = {
|
|
14
|
+
|
|
15
|
+
list: {} as ILeaferTypeList,
|
|
16
|
+
|
|
17
|
+
register(name: string, fn: ILeaferTypeFunction): void {
|
|
18
|
+
list[name] && debug.repeat(name)
|
|
19
|
+
list[name] = fn
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
run(name: string, leafer: ILeaferBase): void {
|
|
23
|
+
const fn = list[name]
|
|
24
|
+
fn && fn(leafer)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { list, register } = LeaferTypeCreator
|
|
30
|
+
|
|
31
|
+
register('viewport', addViewport)
|
|
32
|
+
register('custom', custom)
|
|
33
|
+
register('design', design)
|
|
34
|
+
register('document', document)
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { LeaferTypeCreator } from './LeaferTypeCreator'
|
|
2
|
+
export { addViewport, addViewportConfig } from './type/viewport'
|
|
3
|
+
export { MultiTouchHelper } from './interaction/MultiTouchHelper'
|
|
4
|
+
export { WheelEventHelper } from './interaction/WheelEventHelper'
|
|
5
|
+
export { Transformer } from './interaction/Transformer'
|
|
6
|
+
|
|
7
|
+
import './Leafer'
|
|
8
|
+
import './interaction/Interaction'
|
|
9
|
+
import './interaction/Dragger'
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { IPointerEvent, IFunction } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { Dragger, BoundsHelper, PointHelper } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const dragger = Dragger.prototype
|
|
7
|
+
const { abs } = Math
|
|
8
|
+
|
|
9
|
+
dragger.checkDragEndAnimate = function (data: IPointerEvent, speed?: number): boolean {
|
|
10
|
+
const { moveX, moveY } = this.dragData
|
|
11
|
+
const absMoveX = abs(moveX), absMoveY = abs(moveY), minMove = speed ? 1 : 0.1
|
|
12
|
+
const dragAnimate = this.interaction.m.dragAnimate && this.canAnimate && this.moving && (absMoveX > minMove || absMoveY > minMove)
|
|
13
|
+
|
|
14
|
+
if (dragAnimate) {
|
|
15
|
+
const inertia = data.pointerType === 'touch' ? 3 : 1, maxMove = 70
|
|
16
|
+
speed = speed ? 0.95 : inertia
|
|
17
|
+
if (absMoveX * speed > maxMove) speed = maxMove / absMoveX
|
|
18
|
+
else if (absMoveY * speed > maxMove) speed = maxMove / absMoveY
|
|
19
|
+
|
|
20
|
+
data = { ...data }
|
|
21
|
+
PointHelper.move(data, moveX * speed, moveY * speed)
|
|
22
|
+
|
|
23
|
+
this.drag(data)
|
|
24
|
+
this.animate(() => { this.dragEnd(data, 1) })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return dragAnimate
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
dragger.animate = function (func?: IFunction, off?: 'off'): void { // dragEnd animation
|
|
31
|
+
const animateWait = func || this.animateWait
|
|
32
|
+
if (animateWait) this.interaction.target.nextRender(animateWait, null, off)
|
|
33
|
+
this.animateWait = func
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
dragger.checkDragOut = function (data: IPointerEvent): void {
|
|
37
|
+
const { interaction } = this
|
|
38
|
+
this.autoMoveCancel()
|
|
39
|
+
if (this.dragging && !interaction.shrinkCanvasBounds.hitPoint(data)) this.autoMoveOnDragOut(data)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
dragger.autoMoveOnDragOut = function (data: IPointerEvent): void {
|
|
43
|
+
const { interaction, downData, canDragOut } = this
|
|
44
|
+
const { autoDistance, dragOut } = interaction.m
|
|
45
|
+
if (!dragOut || !canDragOut || !autoDistance) return
|
|
46
|
+
|
|
47
|
+
const bounds = interaction.shrinkCanvasBounds
|
|
48
|
+
const { x, y } = bounds
|
|
49
|
+
const right = BoundsHelper.maxX(bounds)
|
|
50
|
+
const bottom = BoundsHelper.maxY(bounds)
|
|
51
|
+
|
|
52
|
+
const moveX = data.x < x ? autoDistance : (right < data.x ? -autoDistance : 0)
|
|
53
|
+
const moveY = data.y < y ? autoDistance : (bottom < data.y ? -autoDistance : 0)
|
|
54
|
+
let totalX = 0, totalY = 0
|
|
55
|
+
|
|
56
|
+
this.autoMoveTimer = setInterval(() => {
|
|
57
|
+
totalX += moveX
|
|
58
|
+
totalY += moveY
|
|
59
|
+
|
|
60
|
+
PointHelper.move(downData, moveX, moveY)
|
|
61
|
+
PointHelper.move(this.dragData, moveX, moveY)
|
|
62
|
+
|
|
63
|
+
interaction.move({ ...data, moveX, moveY, totalX, totalY, moveType: 'drag' })
|
|
64
|
+
interaction.pointerMoveReal(data)
|
|
65
|
+
}, 10)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
dragger.autoMoveCancel = function (): void {
|
|
69
|
+
if (this.autoMoveTimer) {
|
|
70
|
+
clearInterval(this.autoMoveTimer)
|
|
71
|
+
this.autoMoveTimer = 0
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { IMoveEvent, IZoomEvent, IRotateEvent, IWheelEvent, IUIEvent, IKeepTouchData, IPointData, IEvent } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { InteractionBase } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
import { WheelEventHelper } from './WheelEventHelper'
|
|
6
|
+
import { Transformer } from './Transformer'
|
|
7
|
+
import { MultiTouchHelper } from './MultiTouchHelper'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
function getMoveEventData(move: IPointData, event: IEvent): IMoveEvent {
|
|
11
|
+
return { ...event, moveX: move.x, moveY: move.y } as IMoveEvent
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getRotateEventData(rotation: number, event: IEvent): IRotateEvent {
|
|
15
|
+
return { ...event, rotation } as IRotateEvent
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getZoomEventData(scale: number, event: IEvent): IZoomEvent {
|
|
19
|
+
return { ...event, scale, } as IZoomEvent
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const interaction = InteractionBase.prototype
|
|
24
|
+
|
|
25
|
+
interaction.createTransformer = function (): void {
|
|
26
|
+
this.transformer = new Transformer(this)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interaction.move = function (data: IMoveEvent): void {
|
|
30
|
+
this.transformer.move(data)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interaction.zoom = function (data: IZoomEvent): void {
|
|
34
|
+
this.transformer.zoom(data)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interaction.rotate = function (data: IRotateEvent): void {
|
|
38
|
+
this.transformer.rotate(data)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interaction.transformEnd = function (): void {
|
|
42
|
+
this.transformer.transformEnd()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
interaction.wheel = function (data: IWheelEvent): void {
|
|
47
|
+
const { wheel } = this.config
|
|
48
|
+
if (wheel.disabled) return
|
|
49
|
+
|
|
50
|
+
const scale = wheel.getScale ? wheel.getScale(data, wheel) : WheelEventHelper.getScale(data, wheel)
|
|
51
|
+
scale !== 1 ? this.zoom(getZoomEventData(scale, data)) : this.move(getMoveEventData(wheel.getMove ? wheel.getMove(data, wheel) : WheelEventHelper.getMove(data, wheel), data))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
interaction.multiTouch = function (data: IUIEvent, list: IKeepTouchData[]): void {
|
|
56
|
+
if (this.config.multiTouch.disabled) return
|
|
57
|
+
const { move, rotation, scale, center } = MultiTouchHelper.getData(list)
|
|
58
|
+
Object.assign(data, center)
|
|
59
|
+
|
|
60
|
+
this.rotate(getRotateEventData(rotation, data))
|
|
61
|
+
this.zoom(getZoomEventData(scale, data))
|
|
62
|
+
this.move(getMoveEventData(move, data))
|
|
63
|
+
}
|