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