@leafer-in/editor 1.0.0-beta.15

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 ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023-present, Chao (Leafer) Wan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @leafer-in/editor
2
+
3
+ 图形编辑器插件
@@ -0,0 +1,510 @@
1
+ import { MatrixHelper, Bounds, Matrix, Event, Group, Rect, Polygon, DataHelper, RotateEvent, PointHelper, MathHelper, DragEvent, PointerEvent, RenderEvent, KeyEvent } from '@leafer-ui/core';
2
+
3
+ var IDirection8;
4
+ (function (IDirection8) {
5
+ IDirection8[IDirection8["topLeft"] = 0] = "topLeft";
6
+ IDirection8[IDirection8["top"] = 1] = "top";
7
+ IDirection8[IDirection8["topRight"] = 2] = "topRight";
8
+ IDirection8[IDirection8["right"] = 3] = "right";
9
+ IDirection8[IDirection8["bottomRight"] = 4] = "bottomRight";
10
+ IDirection8[IDirection8["bottom"] = 5] = "bottom";
11
+ IDirection8[IDirection8["bottomLeft"] = 6] = "bottomLeft";
12
+ IDirection8[IDirection8["left"] = 7] = "left";
13
+ })(IDirection8 || (IDirection8 = {}));
14
+
15
+ const { scaleOfOuter, reset } = MatrixHelper;
16
+ const { topLeft: topLeft$1, top: top$1, topRight: topRight$1, right: right$2, bottomRight: bottomRight$1, bottom: bottom$1, bottomLeft: bottomLeft$1, left: left$2 } = IDirection8;
17
+ const matrix = {};
18
+ function getResizeData(old, direction, move, lockRatio, around) {
19
+ if (around) {
20
+ move.x *= 2;
21
+ move.y *= 2;
22
+ }
23
+ let origin, scaleX = 1, scaleY = 1;
24
+ const { x, y, width, height } = old;
25
+ const topScale = (-move.y + height) / height;
26
+ const rightScale = (move.x + width) / width;
27
+ const bottomScale = (move.y + height) / height;
28
+ const leftScale = (-move.x + width) / width;
29
+ switch (direction) {
30
+ case top$1:
31
+ scaleY = topScale;
32
+ if (lockRatio)
33
+ scaleX = scaleY;
34
+ origin = { x: x + width / 2, y: y + height };
35
+ break;
36
+ case right$2:
37
+ scaleX = rightScale;
38
+ if (lockRatio)
39
+ scaleY = scaleX;
40
+ origin = { x, y: y + height / 2 };
41
+ break;
42
+ case bottom$1:
43
+ scaleY = bottomScale;
44
+ if (lockRatio)
45
+ scaleX = scaleY;
46
+ origin = { x: x + width / 2, y };
47
+ break;
48
+ case left$2:
49
+ scaleX = leftScale;
50
+ if (lockRatio)
51
+ scaleY = scaleX;
52
+ origin = { x: x + width, y: y + height / 2 };
53
+ break;
54
+ case topLeft$1:
55
+ scaleY = topScale;
56
+ scaleX = leftScale;
57
+ if (lockRatio)
58
+ scaleX = scaleY;
59
+ origin = { x: x + width, y: y + height };
60
+ break;
61
+ case topRight$1:
62
+ scaleY = topScale;
63
+ scaleX = rightScale;
64
+ if (lockRatio)
65
+ scaleX = scaleY;
66
+ origin = { x, y: y + height };
67
+ break;
68
+ case bottomRight$1:
69
+ scaleY = bottomScale;
70
+ scaleX = rightScale;
71
+ if (lockRatio)
72
+ scaleX = scaleY;
73
+ origin = { x, y };
74
+ break;
75
+ case bottomLeft$1:
76
+ scaleY = bottomScale;
77
+ scaleX = leftScale;
78
+ if (lockRatio)
79
+ scaleX = scaleY;
80
+ origin = { x: x + width, y };
81
+ break;
82
+ }
83
+ if (around) {
84
+ if (typeof around === 'object') {
85
+ origin = { x: x + width / around.x, y: y + height / around.y };
86
+ }
87
+ else {
88
+ origin = { x: x + width / 2, y: y + height / 2 };
89
+ }
90
+ }
91
+ reset(matrix);
92
+ scaleOfOuter(matrix, origin, scaleX, scaleY);
93
+ const bounds = { x: old.x + matrix.e, y: old.y + matrix.f, width: width * scaleX, height: height * scaleY };
94
+ return { bounds, old, origin, scaleX, scaleY, direction, lockRatio, around, };
95
+ }
96
+
97
+ const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = IDirection8;
98
+ function updateCursor(editor, e) {
99
+ const point = editor.enterPoint;
100
+ if (!point || !editor.target || !editor.visible)
101
+ return;
102
+ let { rotation } = editor;
103
+ let { resizeCursor, rotateCursor, resizeable } = editor.config;
104
+ const mirror = editor.tool.getMirrorData(editor);
105
+ const { __direction, __isResizePoint } = point.__;
106
+ editor.enterPoint = point;
107
+ if (__isResizePoint && (e.metaKey || e.ctrlKey || !resizeable))
108
+ resizeCursor = rotateCursor;
109
+ if (mirror.x || mirror.y) {
110
+ mirrorCursors(resizeCursor = [...resizeCursor], mirror.x, mirror.y);
111
+ mirrorCursors(rotateCursor = [...rotateCursor], mirror.y, mirror.x);
112
+ if (mirror.x + mirror.y === 1)
113
+ rotation = -rotation;
114
+ }
115
+ let index = (__direction + Math.round(rotation / 45)) % 8;
116
+ if (index < 0)
117
+ index += 8;
118
+ point.cursor = __isResizePoint ? resizeCursor[index] : rotateCursor[index];
119
+ }
120
+ function mirrorCursors(mirror, mirrorX, mirrorY) {
121
+ if (mirrorX) {
122
+ const topCursor = mirror[top], topLeftCursor = mirror[topLeft], topRightCursor = mirror[topRight];
123
+ mirror[top] = mirror[bottom];
124
+ mirror[topLeft] = mirror[bottomLeft];
125
+ mirror[topRight] = mirror[bottomRight];
126
+ mirror[bottom] = topCursor;
127
+ mirror[bottomLeft] = topLeftCursor;
128
+ mirror[bottomRight] = topRightCursor;
129
+ }
130
+ if (mirrorY) {
131
+ const leftCursor = mirror[left$1], topLeftCursor = mirror[topLeft], bottomLeftCursor = mirror[bottomLeft];
132
+ mirror[left$1] = mirror[right$1];
133
+ mirror[topLeft] = mirror[topRight];
134
+ mirror[bottomLeft] = mirror[bottomRight];
135
+ mirror[right$1] = leftCursor;
136
+ mirror[topRight] = topLeftCursor;
137
+ mirror[bottomRight] = bottomLeftCursor;
138
+ }
139
+ }
140
+
141
+ const RectTool = {
142
+ name: 'RectTool',
143
+ getMirrorData(editor) {
144
+ const { scaleX, scaleY } = editor.target;
145
+ return {
146
+ x: scaleX < 0 ? 1 : 0,
147
+ y: scaleY < 0 ? 1 : 0
148
+ };
149
+ },
150
+ resize(e) {
151
+ const { target, bounds, resizeType, old } = e;
152
+ const { x, y, width, height } = bounds;
153
+ const point = { x: x - old.x, y: y - old.y };
154
+ target.innerToWorld(point, null, true, target.parent);
155
+ target.x += point.x;
156
+ target.y += point.y;
157
+ if (resizeType === 'scale') {
158
+ target.scaleX *= width / old.width;
159
+ target.scaleY *= height / old.height;
160
+ }
161
+ else {
162
+ if (width < 0) {
163
+ target.width = -width;
164
+ target.scaleX *= -1;
165
+ }
166
+ else {
167
+ if (target.width !== width)
168
+ target.width = width;
169
+ }
170
+ if (height < 0) {
171
+ target.height = -height;
172
+ target.scaleY *= -1;
173
+ }
174
+ else {
175
+ if (target.height !== height)
176
+ target.height = height;
177
+ }
178
+ }
179
+ },
180
+ rotate(e) {
181
+ const { target, rotation, origin } = e;
182
+ target.rotateOf(origin, rotation);
183
+ },
184
+ update(editor) {
185
+ const { target, config, rotatePoints, targetRect, rect, circle, resizeLines, resizePoints } = editor;
186
+ const { type, resizeable, rotateable, stroke, pointFill, pointSize, pointRadius } = config;
187
+ const defaultStyle = { fill: pointFill, stroke, width: pointSize, height: pointSize, cornerRadius: pointRadius };
188
+ const pointStyles = config.point instanceof Array ? config.point : [config.point || defaultStyle];
189
+ const box = new Bounds(target.boxBounds);
190
+ const w = target.worldTransform, pw = editor.parent.worldTransform;
191
+ const matrix = new Matrix(w);
192
+ matrix.divide(pw);
193
+ const worldX = matrix.e, worldY = matrix.f;
194
+ let { scaleX, scaleY, rotation, skewX, skewY } = w;
195
+ scaleX /= pw.scaleX, scaleY /= pw.scaleY, rotation -= pw.rotation, skewX -= pw.skewX, skewY -= pw.skewY;
196
+ const { x, y, width, height } = box.scale(scaleX, scaleY);
197
+ editor.set({ x: worldX, y: worldY, rotation, skewX, skewY });
198
+ targetRect.set({ x, y, width: box.width / scaleX, height: box.height / scaleY, scaleX, scaleY, visible: true });
199
+ const points = [
200
+ { x, y },
201
+ { x: x + width / 2, y },
202
+ { x: x + width, y },
203
+ { x: x + width, y: y + height / 2 },
204
+ { x: x + width, y: y + height },
205
+ { x: x + width / 2, y: y + height },
206
+ { x, y: y + height },
207
+ { x, y: y + height / 2 }
208
+ ];
209
+ const rectPoints = [];
210
+ let point, style, rotateP, resizeP, resizeL;
211
+ for (let i = 0; i < 8; i++) {
212
+ point = points[i];
213
+ style = pointStyles[i % pointStyles.length];
214
+ resizeP = resizePoints[i];
215
+ resizeL = resizeLines[Math.floor(i / 2)];
216
+ rotateP = rotatePoints[i];
217
+ resizeP.set(style);
218
+ resizeP.x = rotateP.x = resizeL.x = point.x;
219
+ resizeP.y = rotateP.y = resizeL.y = point.y;
220
+ resizeP.visible = resizeL.visible = resizeable || rotateable;
221
+ rotateP.visible = rotateable && resizeable;
222
+ if (i % 2) {
223
+ if (((i + 1) / 2) % 2) {
224
+ resizeL.width = Math.abs(width);
225
+ rotateP.width = Math.max(10, Math.abs(width) - 30);
226
+ }
227
+ else {
228
+ resizeL.height = Math.abs(height);
229
+ rotateP.height = Math.max(10, Math.abs(height) - 30);
230
+ }
231
+ resizeP.rotation = 90;
232
+ resizeP.visible = type === 'mobile';
233
+ }
234
+ else {
235
+ rectPoints.push(point.x, point.y);
236
+ }
237
+ }
238
+ style = config.rotatePoint || style;
239
+ circle.set(style);
240
+ circle.x = x + width / 2;
241
+ if (!style.y)
242
+ circle.y = y - (10 + (resizeP.height + circle.height) / 2) * (this.getMirrorData(editor).y ? -1 : 1);
243
+ circle.visible = rotateable && type === 'mobile';
244
+ rect.set(config.rect || { stroke });
245
+ rect.points = rectPoints;
246
+ rect.visible = true;
247
+ }
248
+ };
249
+
250
+ const { left, right } = IDirection8;
251
+ const LineTool = {
252
+ name: 'LineTool',
253
+ getMirrorData(_editor) {
254
+ return {
255
+ x: 0,
256
+ y: 0
257
+ };
258
+ },
259
+ resize(e) {
260
+ const { direction, dragEvent, lockRatio, around } = e;
261
+ const target = e.target;
262
+ const fromPoint = { x: 0, y: 0 };
263
+ const { toPoint } = target;
264
+ target.rotation = 0;
265
+ let { x, y } = dragEvent.getInnerMove(target);
266
+ if (lockRatio) {
267
+ if (Math.abs(x) > Math.abs(y)) {
268
+ y = 0;
269
+ }
270
+ else {
271
+ x = 0;
272
+ }
273
+ }
274
+ if (direction === left) {
275
+ fromPoint.x += x;
276
+ fromPoint.y += y;
277
+ if (around) {
278
+ toPoint.x -= x;
279
+ toPoint.y -= y;
280
+ }
281
+ }
282
+ else {
283
+ if (around) {
284
+ fromPoint.x -= x;
285
+ fromPoint.y -= y;
286
+ }
287
+ toPoint.x += x;
288
+ toPoint.y += y;
289
+ }
290
+ target.getLocalPointByInner(fromPoint, null, null, true);
291
+ target.getLocalPointByInner(toPoint, null, null, true);
292
+ target.x = fromPoint.x;
293
+ target.y = fromPoint.y;
294
+ target.getInnerPointByLocal(toPoint, null, null, true);
295
+ target.toPoint = toPoint;
296
+ },
297
+ rotate(e) {
298
+ RectTool.rotate(e);
299
+ },
300
+ update(editor) {
301
+ const { rotatePoints, circle, resizeLines, resizePoints } = editor;
302
+ RectTool.update(editor);
303
+ for (let i = 0; i < 8; i++) {
304
+ if (i < 4)
305
+ resizeLines[i].visible = false;
306
+ resizePoints[i].visible = rotatePoints[i].visible = i === left || i === right;
307
+ }
308
+ circle.visible = false;
309
+ }
310
+ };
311
+
312
+ class EditorResizeEvent extends Event {
313
+ constructor(type, data) {
314
+ super(type);
315
+ if (data)
316
+ Object.assign(this, data);
317
+ }
318
+ }
319
+ EditorResizeEvent.RESIZE = 'editor.resize';
320
+
321
+ class EditorRotateEvent extends Event {
322
+ constructor(type, data) {
323
+ super(type);
324
+ if (data)
325
+ Object.assign(this, data);
326
+ }
327
+ }
328
+ EditorRotateEvent.ROTATE = 'editor.rotate';
329
+
330
+ class Editor extends Group {
331
+ get target() { return this._target; }
332
+ set target(value) {
333
+ this.__removeTargetEvents();
334
+ this.visible = !!value;
335
+ this._target = value;
336
+ if (value)
337
+ this.onTarget();
338
+ }
339
+ constructor(userConfig, data) {
340
+ super(data);
341
+ this.config = {
342
+ type: 'pc',
343
+ stroke: '#836DFF',
344
+ pointFill: '#FFFFFF',
345
+ pointSize: 10,
346
+ pointRadius: 10,
347
+ rotateGap: 90,
348
+ hideOnMove: false,
349
+ moveCursor: 'move',
350
+ resizeType: 'auto',
351
+ resizeCursor: ['nwse-resize', 'ns-resize', 'nesw-resize', 'ew-resize', 'nwse-resize', 'ns-resize', 'nesw-resize', 'ew-resize'],
352
+ rotateCursor: ['ne-resize', 'e-resize', 'se-resize', 's-resize', 'sw-resize', 'w-resize', 'nw-resize', 'n-resize'],
353
+ resizeable: true,
354
+ rotateable: true
355
+ };
356
+ this.resizePoints = [];
357
+ this.rotatePoints = [];
358
+ this.resizeLines = [];
359
+ this.targetRect = new Rect({ hitFill: 'all', hitRadius: 5 });
360
+ this.rect = new Polygon({ hittable: false, strokeAlign: 'center' });
361
+ this.circle = new Rect({ around: 'center', hitRadius: 10 });
362
+ this.__eventIds = [];
363
+ this.__targetEventIds = [];
364
+ if (userConfig)
365
+ this.config = DataHelper.default(userConfig, this.config);
366
+ this.init();
367
+ }
368
+ init() {
369
+ let rotatePoint, resizeLine, resizePoint;
370
+ const { resizePoints, rotatePoints, resizeLines } = this;
371
+ for (let i = 0; i < 8; i++) {
372
+ rotatePoint = new Rect({ around: 'center', width: 30, height: 30, hitRadius: 10, hitFill: "all" });
373
+ rotatePoints.push(rotatePoint);
374
+ this.__listenPointEvents(rotatePoint, 'rotate', i);
375
+ if (i % 2) {
376
+ resizeLine = new Rect({ around: 'center', width: 10, height: 10, hitFill: "all" });
377
+ resizeLines.push(resizeLine);
378
+ this.__listenPointEvents(resizeLine, 'resize', i);
379
+ }
380
+ resizePoint = new Rect({ around: 'center', hitRadius: 5 });
381
+ resizePoints.push(resizePoint);
382
+ this.__listenPointEvents(resizePoint, 'resize', i);
383
+ }
384
+ this.__listenPointEvents(this.circle, 'rotate', 1);
385
+ this.addMany(...rotatePoints, this.targetRect, this.rect, this.circle, ...resizeLines, ...resizePoints);
386
+ this.__listenEvents();
387
+ }
388
+ onTarget() {
389
+ this.tool = this.getTool(this.target);
390
+ this.waitLeafer(() => {
391
+ this.update();
392
+ this.updateMoveCursor();
393
+ this.__listenTargetEvents();
394
+ });
395
+ }
396
+ getTool(value) {
397
+ return (value.tag === 'Line' && value.resizeable) ? LineTool : RectTool;
398
+ }
399
+ update() {
400
+ if (!this.target)
401
+ return;
402
+ this.tool.update(this);
403
+ }
404
+ onDrag(e) {
405
+ const { resizeable, rotateable } = this.config;
406
+ if (e.metaKey || e.ctrlKey || !resizeable) {
407
+ if (rotateable)
408
+ this.onRotate(e);
409
+ }
410
+ else {
411
+ this.onResize(e);
412
+ }
413
+ }
414
+ onMove(e) {
415
+ const { target } = this;
416
+ const { x, y } = e.getLocalMove(target);
417
+ if (e.shiftKey) {
418
+ if (Math.abs(x) > Math.abs(y)) {
419
+ target.x += x;
420
+ }
421
+ else {
422
+ target.y += y;
423
+ }
424
+ }
425
+ else {
426
+ target.x += x;
427
+ target.y += y;
428
+ }
429
+ }
430
+ onRotate(e) {
431
+ const { target } = this;
432
+ const { rotateGap } = this.config;
433
+ const { x, y, width, height } = target.boxBounds;
434
+ const origin = { x: x + width / 2, y: y + height / 2 };
435
+ let rotation;
436
+ if (e instanceof RotateEvent) {
437
+ rotation = e.rotation;
438
+ }
439
+ else {
440
+ const point = e;
441
+ const last = { x: point.x - e.moveX, y: point.y - e.moveY };
442
+ rotation = PointHelper.getChangeAngle(last, target.getWorldPoint(origin), point);
443
+ }
444
+ rotation = MathHelper.getGapRotation(target.rotation + rotation, rotateGap) - target.rotation;
445
+ const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { editor: this, target, origin, rotation });
446
+ this.tool.rotate(event);
447
+ target.emitEvent(event);
448
+ }
449
+ onResize(e) {
450
+ const { target } = this;
451
+ const { __direction } = e.current.__;
452
+ let { resizeType, around, lockRatio } = this.config;
453
+ if (e.shiftKey)
454
+ lockRatio = true;
455
+ if (e.altKey && !around)
456
+ around = 'center';
457
+ if (resizeType === 'auto')
458
+ resizeType = target.resizeable ? 'size' : 'scale';
459
+ const data = getResizeData(target.boxBounds, __direction, e.getInnerMove(this.targetRect), lockRatio, around);
460
+ const event = new EditorResizeEvent(EditorResizeEvent.RESIZE, Object.assign(Object.assign({}, data), { target, editor: this, dragEvent: e, resizeType }));
461
+ this.tool.resize(event);
462
+ target.emitEvent(event);
463
+ }
464
+ updateMoveCursor() {
465
+ this.targetRect.cursor = this.config.moveCursor;
466
+ }
467
+ __listenEvents() {
468
+ this.__eventIds = [
469
+ this.targetRect.on_(DragEvent.START, () => { this.opacity = this.config.hideOnMove ? 0 : 1; }),
470
+ this.targetRect.on_(DragEvent.DRAG, this.onMove, this),
471
+ this.targetRect.on_(DragEvent.END, () => { this.opacity = 1; }),
472
+ this.targetRect.on_(PointerEvent.ENTER, this.updateMoveCursor, this)
473
+ ];
474
+ }
475
+ __removeListenEvents() {
476
+ this.targetRect.off_(this.__eventIds);
477
+ this.__eventIds.length = 0;
478
+ }
479
+ __listenPointEvents(point, type, direction) {
480
+ point.__.__direction = direction;
481
+ const resize = point.__.__isResizePoint = type === 'resize';
482
+ point.on_(DragEvent.DRAG, resize ? this.onDrag : this.onRotate, this);
483
+ point.on_(PointerEvent.LEAVE, () => this.enterPoint = null);
484
+ point.on_(PointerEvent.ENTER, (e) => { this.enterPoint = point; updateCursor(this, e); });
485
+ }
486
+ __listenTargetEvents() {
487
+ if (this.target) {
488
+ const { leafer } = this.target;
489
+ this.__targetEventIds = [
490
+ leafer.on_(RenderEvent.START, this.update, this),
491
+ leafer.on_([KeyEvent.HOLD, KeyEvent.UP], (e) => { updateCursor(this, e); })
492
+ ];
493
+ }
494
+ }
495
+ __removeTargetEvents() {
496
+ if (this.__targetEventIds.length) {
497
+ const { leafer } = this.target;
498
+ if (leafer)
499
+ leafer.off_(this.__targetEventIds);
500
+ this.__targetEventIds.length = 0;
501
+ }
502
+ }
503
+ destroy() {
504
+ this.__removeListenEvents();
505
+ this._target = null;
506
+ super.destroy();
507
+ }
508
+ }
509
+
510
+ export { Editor, EditorResizeEvent, EditorRotateEvent, LineTool, RectTool };
@@ -0,0 +1 @@
1
+ import{MatrixHelper as t,Bounds as e,Matrix as i,Event as s,Group as o,Rect as r,Polygon as n,DataHelper as a,RotateEvent as h,PointHelper as l,MathHelper as c,DragEvent as g,PointerEvent as y,RenderEvent as d,KeyEvent as u}from"@leafer-ui/core";var _;!function(t){t[t.topLeft=0]="topLeft",t[t.top=1]="top",t[t.topRight=2]="topRight",t[t.right=3]="right",t[t.bottomRight=4]="bottomRight",t[t.bottom=5]="bottom",t[t.bottomLeft=6]="bottomLeft",t[t.left=7]="left"}(_||(_={}));const{scaleOfOuter:x,reset:b}=t,{topLeft:v,top:f,topRight:p,right:z,bottomRight:R,bottom:w,bottomLeft:m,left:E}=_,M={};const{topLeft:P,top:T,topRight:L,right:k,bottomRight:I,bottom:F,bottomLeft:O,left:D}=_;function X(t,e){const i=t.enterPoint;if(!i||!t.target||!t.visible)return;let{rotation:s}=t,{resizeCursor:o,rotateCursor:r,resizeable:n}=t.config;const a=t.tool.getMirrorData(t),{__direction:h,__isResizePoint:l}=i.__;t.enterPoint=i,l&&(e.metaKey||e.ctrlKey||!n)&&(o=r),(a.x||a.y)&&(Y(o=[...o],a.x,a.y),Y(r=[...r],a.y,a.x),a.x+a.y===1&&(s=-s));let c=(h+Math.round(s/45))%8;c<0&&(c+=8),i.cursor=l?o[c]:r[c]}function Y(t,e,i){if(e){const e=t[T],i=t[P],s=t[L];t[T]=t[F],t[P]=t[O],t[L]=t[I],t[F]=e,t[O]=i,t[I]=s}if(i){const e=t[D],i=t[P],s=t[O];t[D]=t[k],t[P]=t[L],t[O]=t[I],t[k]=e,t[L]=i,t[I]=s}}const A={name:"RectTool",getMirrorData(t){const{scaleX:e,scaleY:i}=t.target;return{x:e<0?1:0,y:i<0?1:0}},resize(t){const{target:e,bounds:i,resizeType:s,old:o}=t,{x:r,y:n,width:a,height:h}=i,l={x:r-o.x,y:n-o.y};e.innerToWorld(l,null,!0,e.parent),e.x+=l.x,e.y+=l.y,"scale"===s?(e.scaleX*=a/o.width,e.scaleY*=h/o.height):(a<0?(e.width=-a,e.scaleX*=-1):e.width!==a&&(e.width=a),h<0?(e.height=-h,e.scaleY*=-1):e.height!==h&&(e.height=h))},rotate(t){const{target:e,rotation:i,origin:s}=t;e.rotateOf(s,i)},update(t){const{target:s,config:o,rotatePoints:r,targetRect:n,rect:a,circle:h,resizeLines:l,resizePoints:c}=t,{type:g,resizeable:y,rotateable:d,stroke:u,pointFill:_,pointSize:x,pointRadius:b}=o,v={fill:_,stroke:u,width:x,height:x,cornerRadius:b},f=o.point instanceof Array?o.point:[o.point||v],p=new e(s.boxBounds),z=s.worldTransform,R=t.parent.worldTransform,w=new i(z);w.divide(R);const m=w.e,E=w.f;let{scaleX:M,scaleY:P,rotation:T,skewX:L,skewY:k}=z;M/=R.scaleX,P/=R.scaleY,T-=R.rotation,L-=R.skewX,k-=R.skewY;const{x:I,y:F,width:O,height:D}=p.scale(M,P);t.set({x:m,y:E,rotation:T,skewX:L,skewY:k}),n.set({x:I,y:F,width:p.width/M,height:p.height/P,scaleX:M,scaleY:P,visible:!0});const X=[{x:I,y:F},{x:I+O/2,y:F},{x:I+O,y:F},{x:I+O,y:F+D/2},{x:I+O,y:F+D},{x:I+O/2,y:F+D},{x:I,y:F+D},{x:I,y:F+D/2}],Y=[];let A,C,K,B,S;for(let t=0;t<8;t++)A=X[t],C=f[t%f.length],B=c[t],S=l[Math.floor(t/2)],K=r[t],B.set(C),B.x=K.x=S.x=A.x,B.y=K.y=S.y=A.y,B.visible=S.visible=y||d,K.visible=d&&y,t%2?((t+1)/2%2?(S.width=Math.abs(O),K.width=Math.max(10,Math.abs(O)-30)):(S.height=Math.abs(D),K.height=Math.max(10,Math.abs(D)-30)),B.rotation=90,B.visible="mobile"===g):Y.push(A.x,A.y);C=o.rotatePoint||C,h.set(C),h.x=I+O/2,C.y||(h.y=F-(10+(B.height+h.height)/2)*(this.getMirrorData(t).y?-1:1)),h.visible=d&&"mobile"===g,a.set(o.rect||{stroke:u}),a.points=Y,a.visible=!0}},{left:C,right:K}=_,B={name:"LineTool",getMirrorData:t=>({x:0,y:0}),resize(t){const{direction:e,dragEvent:i,lockRatio:s,around:o}=t,r=t.target,n={x:0,y:0},{toPoint:a}=r;r.rotation=0;let{x:h,y:l}=i.getInnerMove(r);s&&(Math.abs(h)>Math.abs(l)?l=0:h=0),e===C?(n.x+=h,n.y+=l,o&&(a.x-=h,a.y-=l)):(o&&(n.x-=h,n.y-=l),a.x+=h,a.y+=l),r.getLocalPointByInner(n,null,null,!0),r.getLocalPointByInner(a,null,null,!0),r.x=n.x,r.y=n.y,r.getInnerPointByLocal(a,null,null,!0),r.toPoint=a},rotate(t){A.rotate(t)},update(t){const{rotatePoints:e,circle:i,resizeLines:s,resizePoints:o}=t;A.update(t);for(let t=0;t<8;t++)t<4&&(s[t].visible=!1),o[t].visible=e[t].visible=t===C||t===K;i.visible=!1}};class S extends s{constructor(t,e){super(t),e&&Object.assign(this,e)}}S.RESIZE="editor.resize";class j extends s{constructor(t,e){super(t),e&&Object.assign(this,e)}}j.ROTATE="editor.rotate";class G extends o{get target(){return this._target}set target(t){this.__removeTargetEvents(),this.visible=!!t,this._target=t,t&&this.onTarget()}constructor(t,e){super(e),this.config={type:"pc",stroke:"#836DFF",pointFill:"#FFFFFF",pointSize:10,pointRadius:10,rotateGap:90,hideOnMove:!1,moveCursor:"move",resizeType:"auto",resizeCursor:["nwse-resize","ns-resize","nesw-resize","ew-resize","nwse-resize","ns-resize","nesw-resize","ew-resize"],rotateCursor:["ne-resize","e-resize","se-resize","s-resize","sw-resize","w-resize","nw-resize","n-resize"],resizeable:!0,rotateable:!0},this.resizePoints=[],this.rotatePoints=[],this.resizeLines=[],this.targetRect=new r({hitFill:"all",hitRadius:5}),this.rect=new n({hittable:!1,strokeAlign:"center"}),this.circle=new r({around:"center",hitRadius:10}),this.__eventIds=[],this.__targetEventIds=[],t&&(this.config=a.default(t,this.config)),this.init()}init(){let t,e,i;const{resizePoints:s,rotatePoints:o,resizeLines:n}=this;for(let a=0;a<8;a++)t=new r({around:"center",width:30,height:30,hitRadius:10,hitFill:"all"}),o.push(t),this.__listenPointEvents(t,"rotate",a),a%2&&(e=new r({around:"center",width:10,height:10,hitFill:"all"}),n.push(e),this.__listenPointEvents(e,"resize",a)),i=new r({around:"center",hitRadius:5}),s.push(i),this.__listenPointEvents(i,"resize",a);this.__listenPointEvents(this.circle,"rotate",1),this.addMany(...o,this.targetRect,this.rect,this.circle,...n,...s),this.__listenEvents()}onTarget(){this.tool=this.getTool(this.target),this.waitLeafer((()=>{this.update(),this.updateMoveCursor(),this.__listenTargetEvents()}))}getTool(t){return"Line"===t.tag&&t.resizeable?B:A}update(){this.target&&this.tool.update(this)}onDrag(t){const{resizeable:e,rotateable:i}=this.config;t.metaKey||t.ctrlKey||!e?i&&this.onRotate(t):this.onResize(t)}onMove(t){const{target:e}=this,{x:i,y:s}=t.getLocalMove(e);t.shiftKey?Math.abs(i)>Math.abs(s)?e.x+=i:e.y+=s:(e.x+=i,e.y+=s)}onRotate(t){const{target:e}=this,{rotateGap:i}=this.config,{x:s,y:o,width:r,height:n}=e.boxBounds,a={x:s+r/2,y:o+n/2};let g;if(t instanceof h)g=t.rotation;else{const i=t,s={x:i.x-t.moveX,y:i.y-t.moveY};g=l.getChangeAngle(s,e.getWorldPoint(a),i)}g=c.getGapRotation(e.rotation+g,i)-e.rotation;const y=new j(j.ROTATE,{editor:this,target:e,origin:a,rotation:g});this.tool.rotate(y),e.emitEvent(y)}onResize(t){const{target:e}=this,{__direction:i}=t.current.__;let{resizeType:s,around:o,lockRatio:r}=this.config;t.shiftKey&&(r=!0),t.altKey&&!o&&(o="center"),"auto"===s&&(s=e.resizeable?"size":"scale");const n=function(t,e,i,s,o){o&&(i.x*=2,i.y*=2);let r,n=1,a=1;const{x:h,y:l,width:c,height:g}=t,y=(-i.y+g)/g,d=(i.x+c)/c,u=(i.y+g)/g,_=(-i.x+c)/c;switch(e){case f:a=y,s&&(n=a),r={x:h+c/2,y:l+g};break;case z:n=d,s&&(a=n),r={x:h,y:l+g/2};break;case w:a=u,s&&(n=a),r={x:h+c/2,y:l};break;case E:n=_,s&&(a=n),r={x:h+c,y:l+g/2};break;case v:a=y,n=_,s&&(n=a),r={x:h+c,y:l+g};break;case p:a=y,n=d,s&&(n=a),r={x:h,y:l+g};break;case R:a=u,n=d,s&&(n=a),r={x:h,y:l};break;case m:a=u,n=_,s&&(n=a),r={x:h+c,y:l}}return o&&(r="object"==typeof o?{x:h+c/o.x,y:l+g/o.y}:{x:h+c/2,y:l+g/2}),b(M),x(M,r,n,a),{bounds:{x:t.x+M.e,y:t.y+M.f,width:c*n,height:g*a},old:t,origin:r,scaleX:n,scaleY:a,direction:e,lockRatio:s,around:o}}(e.boxBounds,i,t.getInnerMove(this.targetRect),r,o),a=new S(S.RESIZE,Object.assign(Object.assign({},n),{target:e,editor:this,dragEvent:t,resizeType:s}));this.tool.resize(a),e.emitEvent(a)}updateMoveCursor(){this.targetRect.cursor=this.config.moveCursor}__listenEvents(){this.__eventIds=[this.targetRect.on_(g.START,(()=>{this.opacity=this.config.hideOnMove?0:1})),this.targetRect.on_(g.DRAG,this.onMove,this),this.targetRect.on_(g.END,(()=>{this.opacity=1})),this.targetRect.on_(y.ENTER,this.updateMoveCursor,this)]}__removeListenEvents(){this.targetRect.off_(this.__eventIds),this.__eventIds.length=0}__listenPointEvents(t,e,i){t.__.__direction=i;const s=t.__.__isResizePoint="resize"===e;t.on_(g.DRAG,s?this.onDrag:this.onRotate,this),t.on_(y.LEAVE,(()=>this.enterPoint=null)),t.on_(y.ENTER,(e=>{this.enterPoint=t,X(this,e)}))}__listenTargetEvents(){if(this.target){const{leafer:t}=this.target;this.__targetEventIds=[t.on_(d.START,this.update,this),t.on_([u.HOLD,u.UP],(t=>{X(this,t)}))]}}__removeTargetEvents(){if(this.__targetEventIds.length){const{leafer:t}=this.target;t&&t.off_(this.__targetEventIds),this.__targetEventIds.length=0}}destroy(){this.__removeListenEvents(),this._target=null,super.destroy()}}export{G as Editor,S as EditorResizeEvent,j as EditorRotateEvent,B as LineTool,A as RectTool};