@anu3ev/fabric-image-editor 0.1.46 → 0.1.47
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/dist/main.js +1004 -1092
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -1,62 +1,63 @@
|
|
|
1
|
-
var
|
|
1
|
+
var be = Object.defineProperty;
|
|
2
2
|
var _ = Object.getOwnPropertySymbols;
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var de = Object.prototype.hasOwnProperty, le = Object.prototype.propertyIsEnumerable;
|
|
4
|
+
var ce = (r, e, t) => e in r ? be(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t, E = (r, e) => {
|
|
5
5
|
for (var t in e || (e = {}))
|
|
6
|
-
|
|
6
|
+
de.call(e, t) && ce(r, t, e[t]);
|
|
7
7
|
if (_)
|
|
8
8
|
for (var t of _(e))
|
|
9
|
-
|
|
9
|
+
le.call(e, t) && ce(r, t, e[t]);
|
|
10
10
|
return r;
|
|
11
11
|
};
|
|
12
12
|
var Y = (r, e) => {
|
|
13
13
|
var t = {};
|
|
14
|
-
for (var
|
|
15
|
-
|
|
14
|
+
for (var s in r)
|
|
15
|
+
de.call(r, s) && e.indexOf(s) < 0 && (t[s] = r[s]);
|
|
16
16
|
if (r != null && _)
|
|
17
|
-
for (var
|
|
18
|
-
e.indexOf(
|
|
17
|
+
for (var s of _(r))
|
|
18
|
+
e.indexOf(s) < 0 && le.call(r, s) && (t[s] = r[s]);
|
|
19
19
|
return t;
|
|
20
20
|
};
|
|
21
|
-
var
|
|
22
|
-
var i = (
|
|
21
|
+
var y = (r, e, t) => new Promise((s, n) => {
|
|
22
|
+
var i = (d) => {
|
|
23
23
|
try {
|
|
24
|
-
o(t.next(
|
|
25
|
-
} catch (
|
|
26
|
-
|
|
24
|
+
o(t.next(d));
|
|
25
|
+
} catch (c) {
|
|
26
|
+
n(c);
|
|
27
27
|
}
|
|
28
|
-
},
|
|
28
|
+
}, a = (d) => {
|
|
29
29
|
try {
|
|
30
|
-
o(t.throw(
|
|
31
|
-
} catch (
|
|
32
|
-
|
|
30
|
+
o(t.throw(d));
|
|
31
|
+
} catch (c) {
|
|
32
|
+
n(c);
|
|
33
33
|
}
|
|
34
|
-
}, o = (
|
|
34
|
+
}, o = (d) => d.done ? s(d.value) : Promise.resolve(d.value).then(i, a);
|
|
35
35
|
o((t = t.apply(r, e)).next());
|
|
36
36
|
});
|
|
37
|
-
import { ActiveSelection as
|
|
37
|
+
import { ActiveSelection as I, util as H, controlsUtils as pe, InteractiveFabricObject as ye, loadSVGFromURL as Ie, FabricImage as Z, Point as W, Rect as ve, Circle as Ae, Triangle as Se, Group as Q, Canvas as Ce, Pattern as Ne } from "fabric";
|
|
38
38
|
import { create as De } from "jsondiffpatch";
|
|
39
|
-
import
|
|
40
|
-
var
|
|
41
|
-
for (var e = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 21, t = "",
|
|
42
|
-
t +=
|
|
39
|
+
import Le from "diff-match-patch";
|
|
40
|
+
var we = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", D = function() {
|
|
41
|
+
for (var e = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 21, t = "", s = crypto.getRandomValues(new Uint8Array(e |= 0)); e--; )
|
|
42
|
+
t += we[s[e] & 63];
|
|
43
43
|
return t;
|
|
44
44
|
};
|
|
45
45
|
class R {
|
|
46
46
|
/**
|
|
47
47
|
* Конструктор принимает редактор и опции.
|
|
48
|
-
* @param
|
|
49
|
-
* @param
|
|
50
|
-
* @param
|
|
51
|
-
* @param
|
|
52
|
-
* @param
|
|
53
|
-
* @param
|
|
54
|
-
* @param
|
|
55
|
-
* @param
|
|
56
|
-
* @param
|
|
57
|
-
* @param
|
|
58
|
-
* @param
|
|
59
|
-
* @param
|
|
48
|
+
* @param params
|
|
49
|
+
* @param params.editor – редактор, содержащий canvas
|
|
50
|
+
* @param params.options — настройки редактора (см. defaults.js)
|
|
51
|
+
* @param params.options.canvasDragging — включить перетаскивание канваса
|
|
52
|
+
* @param params.options.mouseWheelZooming — включить зум колесом мыши
|
|
53
|
+
* @param params.options.bringToFrontOnSelection — поднимать объект на передний план при выборе
|
|
54
|
+
* @param params.options.copyObjectsByHotkey — копировать объекты по Ctrl+C
|
|
55
|
+
* @param params.options.pasteImageFromClipboard — вставлять изображения и объекты из буфера обмена
|
|
56
|
+
* @param params.options.undoRedoByHotKeys — отмена/повтор по Ctrl+Z/Ctrl+Y
|
|
57
|
+
* @param params.options.selectAllByHotkey — выделение всех объектов по Ctrl+A
|
|
58
|
+
* @param params.options.deleteObjectsByHotkey — удаление объектов по Delete
|
|
59
|
+
* @param params.options.resetObjectFitByDoubleClick — сброс фита объекта по двойному клику
|
|
60
|
+
* @param params.options.adaptCanvasToContainerOnResize — адаптировать канвас к размерам контейнера при изменении размеров окна
|
|
60
61
|
*/
|
|
61
62
|
constructor({ editor: e, options: t = {} }) {
|
|
62
63
|
this.isDragging = !1, this.lastMouseX = 0, this.lastMouseY = 0, this.isUndoRedoKeyPressed = !1, this.isSpacePressed = !1, this.canvasDragging = !1, this.mouseWheelZooming = !1, this.bringToFrontOnSelection = !1, this.resetObjectFitByDoubleClick = !1, this.copyObjectsByHotkey = !1, this.pasteImageFromClipboard = !1, this.undoRedoByHotKeys = !1, this.selectAllByHotkey = !1, this.deleteObjectsByHotkey = !1, this.adaptCanvasToContainerOnResize = !1, this.editor = e, this.canvas = e.canvas, this.options = t, this.handleContainerResizeBound = R.debounce(this.handleContainerResize.bind(this), 500), this.handleCopyEventBound = this.handleCopyEvent.bind(this), this.handlePasteEventBound = this.handlePasteEvent.bind(this), this.handleUndoRedoEventBound = this.handleUndoRedoEvent.bind(this), this.handleUndoRedoKeyUpBound = this.handleUndoRedoKeyUp.bind(this), this.handleSelectAllEventBound = this.handleSelectAllEvent.bind(this), this.handleDeleteObjectsEventBound = this.handleDeleteObjectsEvent.bind(this), this.handleSpaceKeyDownBound = this.handleSpaceKeyDown.bind(this), this.handleSpaceKeyUpBound = this.handleSpaceKeyUp.bind(this), this.handleObjectModifiedHistoryBound = R.debounce(this.handleObjectModifiedHistory.bind(this), 300), this.handleObjectRotatingHistoryBound = R.debounce(this.handleObjectRotatingHistory.bind(this), 300), this.handleObjectAddedHistoryBound = this.handleObjectAddedHistory.bind(this), this.handleObjectRemovedHistoryBound = this.handleObjectRemovedHistory.bind(this), this.handleOverlayUpdateBound = this.handleOverlayUpdate.bind(this), this.handleCanvasDragStartBound = this.handleCanvasDragStart.bind(this), this.handleCanvasDraggingBound = this.handleCanvasDragging.bind(this), this.handleCanvasDragEndBound = this.handleCanvasDragEnd.bind(this), this.handleMouseWheelZoomBound = this.handleMouseWheelZoom.bind(this), this.handleBringToFrontBound = this.handleBringToFront.bind(this), this.handleResetObjectFitBound = this.handleResetObjectFit.bind(this), this.handleLockedSelectionBound = this._filterLockedSelection.bind(this), this.init();
|
|
@@ -68,35 +69,35 @@ class R {
|
|
|
68
69
|
const {
|
|
69
70
|
adaptCanvasToContainerOnResize: e,
|
|
70
71
|
canvasDragging: t,
|
|
71
|
-
mouseWheelZooming:
|
|
72
|
-
bringToFrontOnSelection:
|
|
72
|
+
mouseWheelZooming: s,
|
|
73
|
+
bringToFrontOnSelection: n,
|
|
73
74
|
copyObjectsByHotkey: i,
|
|
74
|
-
pasteImageFromClipboard:
|
|
75
|
+
pasteImageFromClipboard: a,
|
|
75
76
|
undoRedoByHotKeys: o,
|
|
76
|
-
selectAllByHotkey:
|
|
77
|
-
deleteObjectsByHotkey:
|
|
77
|
+
selectAllByHotkey: d,
|
|
78
|
+
deleteObjectsByHotkey: c,
|
|
78
79
|
resetObjectFitByDoubleClick: l
|
|
79
80
|
} = this.options;
|
|
80
|
-
t && (this.canvas.on("mouse:down", this.handleCanvasDragStartBound), this.canvas.on("mouse:move", this.handleCanvasDraggingBound), this.canvas.on("mouse:up", this.handleCanvasDragEndBound), document.addEventListener("keydown", this.handleSpaceKeyDownBound, { capture: !0 }), document.addEventListener("keyup", this.handleSpaceKeyUpBound, { capture: !0 })),
|
|
81
|
+
t && (this.canvas.on("mouse:down", this.handleCanvasDragStartBound), this.canvas.on("mouse:move", this.handleCanvasDraggingBound), this.canvas.on("mouse:up", this.handleCanvasDragEndBound), document.addEventListener("keydown", this.handleSpaceKeyDownBound, { capture: !0 }), document.addEventListener("keyup", this.handleSpaceKeyUpBound, { capture: !0 })), s && this.canvas.on("mouse:wheel", this.handleMouseWheelZoomBound), n && (this.canvas.on("selection:created", this.handleBringToFrontBound), this.canvas.on("selection:updated", this.handleBringToFrontBound)), l && this.canvas.on("mouse:dblclick", this.handleResetObjectFitBound), e && window.addEventListener("resize", this.handleContainerResizeBound, { capture: !0 }), i && document.addEventListener("keydown", this.handleCopyEventBound, { capture: !0 }), a && document.addEventListener("paste", this.handlePasteEventBound, { capture: !0 }), o && (document.addEventListener("keydown", this.handleUndoRedoEventBound, { capture: !0 }), document.addEventListener("keyup", this.handleUndoRedoKeyUpBound, { capture: !0 })), d && document.addEventListener("keydown", this.handleSelectAllEventBound, { capture: !0 }), c && document.addEventListener("keydown", this.handleDeleteObjectsEventBound, { capture: !0 }), this.canvas.on("object:modified", this.handleObjectModifiedHistoryBound), this.canvas.on("object:rotating", this.handleObjectRotatingHistoryBound), this.canvas.on("object:added", this.handleObjectAddedHistoryBound), this.canvas.on("object:removed", this.handleObjectRemovedHistoryBound), this.canvas.on("object:added", this.handleOverlayUpdateBound), this.canvas.on("selection:created", this.handleOverlayUpdateBound), this.canvas.on("selection:created", this.handleLockedSelectionBound), this.canvas.on("selection:updated", this.handleLockedSelectionBound);
|
|
81
82
|
}
|
|
82
83
|
/**
|
|
83
84
|
* При массовом выделении объектов удаляем из него залоченные.
|
|
84
|
-
* @param
|
|
85
|
-
* @param
|
|
86
|
-
* @param
|
|
85
|
+
* @param params - параметры события
|
|
86
|
+
* @param params.selected - массив выделенных объектов
|
|
87
|
+
* @param params.e - событие указателя (опционально)
|
|
87
88
|
*/
|
|
88
89
|
_filterLockedSelection({ selected: e, e: t }) {
|
|
89
|
-
if (!(e != null && e.length) || !(t instanceof MouseEvent) || e.length === 1 || !e.some((
|
|
90
|
-
const
|
|
91
|
-
if (
|
|
90
|
+
if (!(e != null && e.length) || !(t instanceof MouseEvent) || e.length === 1 || !e.some((a) => a.locked)) return;
|
|
91
|
+
const n = e.filter((a) => !a.locked);
|
|
92
|
+
if (n.length === 0) {
|
|
92
93
|
this.canvas.discardActiveObject();
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
95
|
-
if (
|
|
96
|
-
this.canvas.setActiveObject(
|
|
96
|
+
if (n.length === 1) {
|
|
97
|
+
this.canvas.setActiveObject(n[0]);
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
99
|
-
const i = new
|
|
100
|
+
const i = new I(n, {
|
|
100
101
|
canvas: this.canvas
|
|
101
102
|
});
|
|
102
103
|
this.canvas.setActiveObject(i), this.canvas.requestRenderAll();
|
|
@@ -134,58 +135,58 @@ class R {
|
|
|
134
135
|
}
|
|
135
136
|
/**
|
|
136
137
|
* Обработчик для Ctrl+C (копирование).
|
|
137
|
-
* @param
|
|
138
|
-
* @param
|
|
139
|
-
* @param
|
|
140
|
-
* @param
|
|
138
|
+
* @param event — объект события
|
|
139
|
+
* @param event.ctrlKey — зажата ли клавиша Ctrl
|
|
140
|
+
* @param event.metaKey — зажата ли клавиша Cmd (для Mac)
|
|
141
|
+
* @param event.code — код клавиши
|
|
141
142
|
*/
|
|
142
143
|
handleCopyEvent(e) {
|
|
143
|
-
const { ctrlKey: t, metaKey:
|
|
144
|
-
!t && !
|
|
144
|
+
const { ctrlKey: t, metaKey: s, code: n } = e;
|
|
145
|
+
!t && !s || n !== "KeyC" || (e.preventDefault(), this.editor.clipboardManager.copy());
|
|
145
146
|
}
|
|
146
147
|
/**
|
|
147
148
|
* Обработчик вставки объекта или изображения из буфера обмена.
|
|
148
|
-
* @param
|
|
149
|
+
* @param event — объект события
|
|
149
150
|
*/
|
|
150
151
|
handlePasteEvent(e) {
|
|
151
152
|
this.editor.clipboardManager.handlePasteEvent(e);
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
154
155
|
* Обработчик для отмены/повтора (Ctrl+Z/Ctrl+Y).
|
|
155
|
-
*
|
|
156
|
-
* @param
|
|
157
|
-
* @param
|
|
158
|
-
* @param
|
|
156
|
+
* @param event — объект события
|
|
157
|
+
* @param event.ctrlKey — зажата ли клавиша Ctrl
|
|
158
|
+
* @param event.metaKey — зажата ли клавиша Cmd (для Mac)
|
|
159
|
+
* @param event.code — код клавиши
|
|
159
160
|
*/
|
|
160
161
|
handleUndoRedoEvent(e) {
|
|
161
|
-
return
|
|
162
|
-
const { ctrlKey: t, metaKey:
|
|
163
|
-
!t && !
|
|
162
|
+
return y(this, null, function* () {
|
|
163
|
+
const { ctrlKey: t, metaKey: s, code: n, repeat: i } = e;
|
|
164
|
+
!t && !s || i || !/Mac/i.test(navigator.userAgent) && this.isUndoRedoKeyPressed || (n === "KeyZ" ? (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.undo()) : n === "KeyY" && (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.redo()));
|
|
164
165
|
});
|
|
165
166
|
}
|
|
166
167
|
/**
|
|
167
168
|
* Обработчик для отпускания клавиш Ctrl+Z/Ctrl+Y.
|
|
168
|
-
* @param
|
|
169
|
-
* @param
|
|
169
|
+
* @param event — объект события
|
|
170
|
+
* @param event.code — код клавиши
|
|
170
171
|
*/
|
|
171
172
|
handleUndoRedoKeyUp({ code: e }) {
|
|
172
173
|
["KeyZ", "KeyY"].includes(e) && (this.isUndoRedoKeyPressed = !1);
|
|
173
174
|
}
|
|
174
175
|
/**
|
|
175
176
|
* Обработчик для выделения всех объектов (Ctrl+A).
|
|
176
|
-
* @param
|
|
177
|
-
* @param
|
|
178
|
-
* @param
|
|
179
|
-
* @param
|
|
177
|
+
* @param event — объект события
|
|
178
|
+
* @param event.ctrlKey — зажата ли клавиша Ctrl
|
|
179
|
+
* @param event.metaKey — зажата ли клавиша Cmd (для Mac)
|
|
180
|
+
* @param event.code — код клавиши
|
|
180
181
|
*/
|
|
181
182
|
handleSelectAllEvent(e) {
|
|
182
|
-
const { ctrlKey: t, metaKey:
|
|
183
|
-
!t && !
|
|
183
|
+
const { ctrlKey: t, metaKey: s, code: n } = e;
|
|
184
|
+
!t && !s || n !== "KeyA" || (e.preventDefault(), this.editor.selectionManager.selectAll());
|
|
184
185
|
}
|
|
185
186
|
/**
|
|
186
187
|
* Обработчик для удаления объектов (Delete).
|
|
187
|
-
* @param
|
|
188
|
-
* @param
|
|
188
|
+
* @param event — объект события
|
|
189
|
+
* @param event.code — код клавиши
|
|
189
190
|
*/
|
|
190
191
|
handleDeleteObjectsEvent(e) {
|
|
191
192
|
e.code === "Delete" && (e.preventDefault(), this.editor.deletionManager.deleteSelectedObjects());
|
|
@@ -193,17 +194,17 @@ class R {
|
|
|
193
194
|
/**
|
|
194
195
|
* Обработчик для нажатия пробела.
|
|
195
196
|
* Отключает выделение объектов и делает курсор "grab" для перетаскивания канваса.
|
|
196
|
-
* @param
|
|
197
|
-
* @param
|
|
197
|
+
* @param event — объект события
|
|
198
|
+
* @param event.code — код клавиши
|
|
198
199
|
*/
|
|
199
200
|
handleSpaceKeyDown(e) {
|
|
200
201
|
if (e.code !== "Space") return;
|
|
201
|
-
const { canvas: t, editor:
|
|
202
|
-
|
|
202
|
+
const { canvas: t, editor: s, isSpacePressed: n, isDragging: i } = this;
|
|
203
|
+
n || i || (this.isSpacePressed = !0, e.preventDefault(), t.set({
|
|
203
204
|
selection: !1,
|
|
204
205
|
defaultCursor: "grab"
|
|
205
|
-
}), t.setCursor("grab"),
|
|
206
|
-
|
|
206
|
+
}), t.setCursor("grab"), s.canvasManager.getObjects().forEach((a) => {
|
|
207
|
+
a.set({
|
|
207
208
|
selectable: !1,
|
|
208
209
|
evented: !1
|
|
209
210
|
});
|
|
@@ -213,8 +214,8 @@ class R {
|
|
|
213
214
|
* Обработчик для отпускания пробела.
|
|
214
215
|
* Завершает перетаскивание канваса, если оно активно.
|
|
215
216
|
* Включает выделение объектов и возвращает курсор в состояние "default".
|
|
216
|
-
* @param
|
|
217
|
-
* @param
|
|
217
|
+
* @param event — объект события
|
|
218
|
+
* @param event.code — код клавиши
|
|
218
219
|
*/
|
|
219
220
|
handleSpaceKeyUp(e) {
|
|
220
221
|
e.code === "Space" && (this.isSpacePressed = !1, this.isDragging && this.handleCanvasDragEnd(), this.canvas.set({
|
|
@@ -230,16 +231,16 @@ class R {
|
|
|
230
231
|
// --- Обработчики для событий canvas (Fabric) ---
|
|
231
232
|
/**
|
|
232
233
|
* Начало перетаскивания канваса (срабатывает при mouse:down и зажатом пробеле).
|
|
233
|
-
* @param
|
|
234
|
-
* @param
|
|
234
|
+
* @param options - событие указателя
|
|
235
|
+
* @param options.e — объект события (MouseEvent или TouchEvent)
|
|
235
236
|
*/
|
|
236
237
|
handleCanvasDragStart({ e }) {
|
|
237
238
|
!this.isSpacePressed || !(e instanceof MouseEvent) || (this.isDragging = !0, this.lastMouseX = e.clientX, this.lastMouseY = e.clientY, this.canvas.setCursor("grabbing"));
|
|
238
239
|
}
|
|
239
240
|
/**
|
|
240
241
|
* Перетаскивание канваса (mouse:move).
|
|
241
|
-
* @param
|
|
242
|
-
* @param
|
|
242
|
+
* @param options
|
|
243
|
+
* @param options.e — объект события
|
|
243
244
|
*
|
|
244
245
|
* TODO: Надо как-то ограничить область перетаскивания, чтобы канвас не уходил сильно далеко за пределы экрана
|
|
245
246
|
*/
|
|
@@ -257,18 +258,18 @@ class R {
|
|
|
257
258
|
}
|
|
258
259
|
/**
|
|
259
260
|
* Обработчик зума колесиком мыши. Работает при зажатом Ctrl или Cmd.
|
|
260
|
-
* @param
|
|
261
|
-
* @param
|
|
261
|
+
* @param options
|
|
262
|
+
* @param options.e - объект события
|
|
262
263
|
*/
|
|
263
264
|
handleMouseWheelZoom({ e }) {
|
|
264
265
|
if (!e.ctrlKey && !e.metaKey) return;
|
|
265
|
-
const
|
|
266
|
-
this.editor.transformManager.zoom(
|
|
266
|
+
const s = -e.deltaY * 1e-3;
|
|
267
|
+
this.editor.transformManager.zoom(s), e.preventDefault(), e.stopPropagation();
|
|
267
268
|
}
|
|
268
269
|
/**
|
|
269
270
|
* Обработчик, поднимающий выделенные объекты на передний план.
|
|
270
|
-
* @param
|
|
271
|
-
* @param
|
|
271
|
+
* @param event - объект события выделения
|
|
272
|
+
* @param event.selected - массив выбранных объектов
|
|
272
273
|
*/
|
|
273
274
|
handleBringToFront({ selected: e }) {
|
|
274
275
|
e != null && e.length && e.forEach((t) => {
|
|
@@ -277,7 +278,7 @@ class R {
|
|
|
277
278
|
}
|
|
278
279
|
/**
|
|
279
280
|
* Обработчик сброса объекта по двойному клику.
|
|
280
|
-
* @param
|
|
281
|
+
* @param options - объект события fabric
|
|
281
282
|
*/
|
|
282
283
|
handleResetObjectFit(e) {
|
|
283
284
|
const t = e == null ? void 0 : e.target;
|
|
@@ -296,17 +297,17 @@ class R {
|
|
|
296
297
|
* @returns новую обёртку-обработчик
|
|
297
298
|
*/
|
|
298
299
|
static debounce(e, t) {
|
|
299
|
-
let
|
|
300
|
-
return function(...
|
|
301
|
-
|
|
302
|
-
e.apply(this,
|
|
300
|
+
let s = null;
|
|
301
|
+
return function(...n) {
|
|
302
|
+
s !== null && clearTimeout(s), s = setTimeout(() => {
|
|
303
|
+
e.apply(this, n);
|
|
303
304
|
}, t);
|
|
304
305
|
};
|
|
305
306
|
}
|
|
306
307
|
}
|
|
307
|
-
class
|
|
308
|
+
class Oe {
|
|
308
309
|
/**
|
|
309
|
-
*
|
|
310
|
+
* Класс для динамической загрузки внешних модулей.
|
|
310
311
|
*/
|
|
311
312
|
constructor() {
|
|
312
313
|
this.cache = /* @__PURE__ */ new Map(), this.loaders = {
|
|
@@ -315,11 +316,11 @@ class Ne {
|
|
|
315
316
|
}
|
|
316
317
|
/**
|
|
317
318
|
* Загружает модуль по имени и сохраняет промис в кеше.
|
|
318
|
-
* @param
|
|
319
|
-
* @returns
|
|
319
|
+
* @param name — строковый литерал, например 'jspdf'.
|
|
320
|
+
* @returns Промис, который разрешается в загруженный модуль.
|
|
320
321
|
*/
|
|
321
322
|
loadModule(e) {
|
|
322
|
-
return this.loaders[e] ? (this.cache.has(e) || this.cache.set(e, this.loaders[e]()), this.cache.get(e)) : Promise.reject(new Error(
|
|
323
|
+
return this.loaders[e] ? (this.cache.has(e) || this.cache.set(e, this.loaders[e]()), this.cache.get(e)) : Promise.reject(new Error(`Unknown module "${e}"`));
|
|
323
324
|
}
|
|
324
325
|
}
|
|
325
326
|
class Ee {
|
|
@@ -347,12 +348,12 @@ class Ee {
|
|
|
347
348
|
var {
|
|
348
349
|
data: t
|
|
349
350
|
} = e, {
|
|
350
|
-
requestId:
|
|
351
|
-
success:
|
|
351
|
+
requestId: s,
|
|
352
|
+
success: n,
|
|
352
353
|
data: i,
|
|
353
|
-
error:
|
|
354
|
-
} = t, o = this._callbacks.get(
|
|
355
|
-
o && (
|
|
354
|
+
error: a
|
|
355
|
+
} = t, o = this._callbacks.get(s);
|
|
356
|
+
o && (n ? o.resolve(i) : o.reject(new Error(a)), this._callbacks.delete(s));
|
|
356
357
|
}
|
|
357
358
|
/**
|
|
358
359
|
* Универсальный метод отправки команды в воркер
|
|
@@ -362,16 +363,16 @@ class Ee {
|
|
|
362
363
|
* @returns {Promise<any>}
|
|
363
364
|
*/
|
|
364
365
|
post(e, t) {
|
|
365
|
-
var
|
|
366
|
-
return new Promise((i,
|
|
367
|
-
this._callbacks.set(
|
|
366
|
+
var s = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : [], n = "".concat(e, ":").concat(D(8));
|
|
367
|
+
return new Promise((i, a) => {
|
|
368
|
+
this._callbacks.set(n, {
|
|
368
369
|
resolve: i,
|
|
369
|
-
reject:
|
|
370
|
+
reject: a
|
|
370
371
|
}), this.worker.postMessage({
|
|
371
372
|
action: e,
|
|
372
373
|
payload: t,
|
|
373
|
-
requestId:
|
|
374
|
-
},
|
|
374
|
+
requestId: n
|
|
375
|
+
}, s);
|
|
375
376
|
});
|
|
376
377
|
}
|
|
377
378
|
/**
|
|
@@ -381,132 +382,132 @@ class Ee {
|
|
|
381
382
|
this.worker.terminate();
|
|
382
383
|
}
|
|
383
384
|
}
|
|
384
|
-
const
|
|
385
|
-
function P(r, e, t,
|
|
386
|
-
const i =
|
|
387
|
-
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(
|
|
385
|
+
const C = 12, Te = 2, J = 8, $ = 20, ke = 100, K = 20, q = 8, xe = 100, ee = 32, te = 1, Be = "#2B2D33", se = "#3D8BF4", ne = "#FFFFFF";
|
|
386
|
+
function P(r, e, t, s, n) {
|
|
387
|
+
const i = C, a = Te;
|
|
388
|
+
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(n.angle)), r.fillStyle = ne, r.strokeStyle = se, r.lineWidth = te, r.beginPath(), r.roundRect(-12 / 2, -12 / 2, i, i, a), r.fill(), r.stroke(), r.restore();
|
|
388
389
|
}
|
|
389
|
-
function
|
|
390
|
-
const i =
|
|
391
|
-
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(
|
|
390
|
+
function he(r, e, t, s, n) {
|
|
391
|
+
const i = J, a = $, o = ke;
|
|
392
|
+
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(n.angle)), r.fillStyle = ne, r.strokeStyle = se, r.lineWidth = te, r.beginPath(), r.roundRect(-8 / 2, -20 / 2, i, a, o), r.fill(), r.stroke(), r.restore();
|
|
392
393
|
}
|
|
393
|
-
function
|
|
394
|
-
const i =
|
|
395
|
-
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(
|
|
394
|
+
function ge(r, e, t, s, n) {
|
|
395
|
+
const i = K, a = q, o = xe;
|
|
396
|
+
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(n.angle)), r.fillStyle = ne, r.strokeStyle = se, r.lineWidth = te, r.beginPath(), r.roundRect(-20 / 2, -8 / 2, i, a, o), r.fill(), r.stroke(), r.restore();
|
|
396
397
|
}
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
function
|
|
400
|
-
const
|
|
401
|
-
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(
|
|
398
|
+
const Ue = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE4Ljc1IDQuMzc1djMuNzVhLjYyNS42MjUgMCAwIDEtLjYyNS42MjVoLTMuNzVhLjYyNS42MjUgMCAwIDEgMC0xLjI1aDIuMTRsLTIuMDc3LTEuOTAzLS4wMi0uMDE5YTYuMjUgNi4yNSAwIDEgMC0uMTMgOC45NjcuNjI2LjYyNiAwIDAgMSAuODYuOTA5QTcuNDU2IDcuNDU2IDAgMCAxIDEwIDE3LjVoLS4xMDNhNy41IDcuNSAwIDEgMSA1LjM5Ni0xMi44MTJMMTcuNSA2LjcwM1Y0LjM3NWEuNjI1LjYyNSAwIDAgMSAxLjI1IDBaIi8+PC9zdmc+", me = new Image();
|
|
399
|
+
me.src = Ue;
|
|
400
|
+
function Ze(r, e, t, s, n) {
|
|
401
|
+
const a = ee / 2;
|
|
402
|
+
r.save(), r.translate(e, t), r.rotate(H.degreesToRadians(n.angle)), r.fillStyle = Be, r.beginPath(), r.arc(0, 0, a, 0, 2 * Math.PI), r.fill(), r.drawImage(me, -16 / 2, -16 / 2, a, a), r.restore();
|
|
402
403
|
}
|
|
403
|
-
const
|
|
404
|
+
const ze = {
|
|
404
405
|
// Угловые точки
|
|
405
406
|
tl: {
|
|
406
407
|
render: P,
|
|
407
|
-
sizeX:
|
|
408
|
-
sizeY:
|
|
408
|
+
sizeX: C,
|
|
409
|
+
sizeY: C,
|
|
409
410
|
offsetX: 0,
|
|
410
411
|
offsetY: 0
|
|
411
412
|
},
|
|
412
413
|
tr: {
|
|
413
414
|
render: P,
|
|
414
|
-
sizeX:
|
|
415
|
-
sizeY:
|
|
415
|
+
sizeX: C,
|
|
416
|
+
sizeY: C,
|
|
416
417
|
offsetX: 0,
|
|
417
418
|
offsetY: 0
|
|
418
419
|
},
|
|
419
420
|
bl: {
|
|
420
421
|
render: P,
|
|
421
|
-
sizeX:
|
|
422
|
-
sizeY:
|
|
422
|
+
sizeX: C,
|
|
423
|
+
sizeY: C,
|
|
423
424
|
offsetX: 0,
|
|
424
425
|
offsetY: 0
|
|
425
426
|
},
|
|
426
427
|
br: {
|
|
427
428
|
render: P,
|
|
428
|
-
sizeX:
|
|
429
|
-
sizeY:
|
|
429
|
+
sizeX: C,
|
|
430
|
+
sizeY: C,
|
|
430
431
|
offsetX: 0,
|
|
431
432
|
offsetY: 0
|
|
432
433
|
},
|
|
433
434
|
// Середина вертикалей
|
|
434
435
|
ml: {
|
|
435
|
-
render:
|
|
436
|
-
sizeX:
|
|
437
|
-
sizeY:
|
|
436
|
+
render: he,
|
|
437
|
+
sizeX: J,
|
|
438
|
+
sizeY: $,
|
|
438
439
|
offsetX: 0,
|
|
439
440
|
offsetY: 0
|
|
440
441
|
},
|
|
441
442
|
mr: {
|
|
442
|
-
render:
|
|
443
|
-
sizeX:
|
|
444
|
-
sizeY:
|
|
443
|
+
render: he,
|
|
444
|
+
sizeX: J,
|
|
445
|
+
sizeY: $,
|
|
445
446
|
offsetX: 0,
|
|
446
447
|
offsetY: 0
|
|
447
448
|
},
|
|
448
449
|
// Середина горизонталей
|
|
449
450
|
mt: {
|
|
450
|
-
render:
|
|
451
|
-
sizeX:
|
|
452
|
-
sizeY:
|
|
451
|
+
render: ge,
|
|
452
|
+
sizeX: K,
|
|
453
|
+
sizeY: q,
|
|
453
454
|
offsetX: 0,
|
|
454
455
|
offsetY: 0
|
|
455
456
|
},
|
|
456
457
|
mb: {
|
|
457
|
-
render:
|
|
458
|
-
sizeX:
|
|
459
|
-
sizeY:
|
|
458
|
+
render: ge,
|
|
459
|
+
sizeX: K,
|
|
460
|
+
sizeY: q,
|
|
460
461
|
offsetX: 0,
|
|
461
462
|
offsetY: 0
|
|
462
463
|
},
|
|
463
464
|
// Специальный «rotate» контрол
|
|
464
465
|
mtr: {
|
|
465
|
-
render:
|
|
466
|
-
sizeX:
|
|
467
|
-
sizeY:
|
|
466
|
+
render: Ze,
|
|
467
|
+
sizeX: ee,
|
|
468
|
+
sizeY: ee,
|
|
468
469
|
offsetX: 0,
|
|
469
470
|
offsetY: -32
|
|
470
471
|
}
|
|
471
472
|
};
|
|
472
|
-
class
|
|
473
|
+
class Re {
|
|
473
474
|
static apply() {
|
|
474
|
-
const e =
|
|
475
|
-
Object.entries(
|
|
475
|
+
const e = pe.createObjectDefaultControls();
|
|
476
|
+
Object.entries(ze).forEach(([t, s]) => {
|
|
476
477
|
Object.assign(e[t], {
|
|
477
|
-
render:
|
|
478
|
-
sizeX:
|
|
479
|
-
sizeY:
|
|
480
|
-
offsetX:
|
|
481
|
-
offsetY:
|
|
482
|
-
}), t === "mtr" && (e[t].cursorStyle = "grab", e[t].mouseDownHandler = (i,
|
|
478
|
+
render: s.render,
|
|
479
|
+
sizeX: s.sizeX,
|
|
480
|
+
sizeY: s.sizeY,
|
|
481
|
+
offsetX: s.offsetX,
|
|
482
|
+
offsetY: s.offsetY
|
|
483
|
+
}), t === "mtr" && (e[t].cursorStyle = "grab", e[t].mouseDownHandler = (i, a, o, d) => {
|
|
483
484
|
var l;
|
|
484
|
-
(l =
|
|
485
|
+
(l = a.target.canvas) == null || l.setCursor("grabbing");
|
|
485
486
|
});
|
|
486
|
-
}),
|
|
487
|
+
}), ye.ownDefaults.controls = e;
|
|
487
488
|
}
|
|
488
489
|
}
|
|
489
|
-
var
|
|
490
|
-
function
|
|
490
|
+
var He = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNi44NzUgMi41YS42MjUuNjI1IDAgMCAwLS42MjUuNjI0VjYuMjVIMy4xMjVhLjYyNS42MjUgMCAwIDAtLjYyNS42MjV2MTBjMCAuMzQ1LjI4LjYyNS42MjUuNjI1aDEwYy4zNDUgMCAuNjI1LS4yOC42MjUtLjYyNXYtMy4xMjZoMy4xMjVjLjM0NSAwIC42MjUtLjI4LjYyNS0uNjI1di0xMGEuNjI1LjYyNSAwIDAgMC0uNjI1LS42MjVoLTEwWm02Ljg3NSAxMGgyLjVWMy43NUg3LjV2Mi41aDUuNjI1Yy4zNDUgMCAuNjI1LjI4LjYyNS42MjV2NS42MjRabS0xMCAzLjc1VjcuNWg4Ljc1djguNzVIMy43NVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", _e = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMi41IDcuNWMwLS42OS41Ni0xLjI1IDEuMjUtMS4yNWgxMi41Yy42OSAwIDEuMjUuNTYgMS4yNSAxLjI1djguNzVjMCAuNjktLjU2IDEuMjUtMS4yNSAxLjI1SDMuNzVjLS42OSAwLTEuMjUtLjU2LTEuMjUtMS4yNVY3LjVabTEzLjc1IDBIMy43NXY4Ljc1aDEyLjVWNy41WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAgMS44NzVhMi4xODggMi4xODggMCAwIDAtMi4xODggMi4xODh2Mi44MTJhLjYyNS42MjUgMCAxIDEtMS4yNSAwVjQuMDYyYTMuNDM3IDMuNDM3IDAgMSAxIDYuODc1IDB2Mi44MTNhLjYyNS42MjUgMCAxIDEtMS4yNSAwVjQuMDYyQTIuMTg4IDIuMTg4IDAgMCAwIDEwIDEuODc2WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEwIDEyLjgxM2EuOTM3LjkzNyAwIDEgMCAwLTEuODc1LjkzNy45MzcgMCAwIDAgMCAxLjg3NFoiLz48L3N2Zz4=", Ye = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE2LjI1IDYuMjVINy41VjQuMzc1YTIuNSAyLjUgMCAwIDEgMi41LTIuNWMxLjIgMCAyLjI4MS44NiAyLjUxMiAyYS42MjUuNjI1IDAgMCAwIDEuMjI2LS4yNWMtLjM1NC0xLjczOC0xLjkyNS0zLTMuNzM4LTNhMy43NTQgMy43NTQgMCAwIDAtMy43NSAzLjc1VjYuMjVoLTIuNUExLjI1IDEuMjUgMCAwIDAgMi41IDcuNXY4Ljc1YTEuMjUgMS4yNSAwIDAgMCAxLjI1IDEuMjVoMTIuNWExLjI1IDEuMjUgMCAwIDAgMS4yNS0xLjI1VjcuNWExLjI1IDEuMjUgMCAwIDAtMS4yNS0xLjI1Wm0wIDEwSDMuNzVWNy41aDEyLjV2OC43NVptLTUuMzEzLTQuMzc1YS45MzcuOTM3IDAgMSAxLTEuODc0IDAgLjkzNy45MzcgMCAwIDEgMS44NzQgMFoiLz48L3N2Zz4K", Pe = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTIuNSA4LjEyNSAxMCAxMi41bDcuNS00LjM3NUwxMCAzLjc1IDIuNSA4LjEyNVoiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05LjY4NSAzLjIxYS42MjUuNjI1IDAgMCAxIC42MyAwbDcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOGw3LjUtNC4zNzVaTTMuNzQgOC4xMjUgMTAgMTEuNzc2bDYuMjYtMy42NTFMMTAgNC40NzQgMy43NCA4LjEyNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuNCA5LjQ2YS42MjUuNjI1IDAgMCAxIC42MyAwTDEwIDExLjc3NmwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCA5LjQ2Wm0tMS42NiAyLjQxNUwxMCAxNS41MjZsNi4yNi0zLjY1MS0xLjk3NC0xLjE1MS0zLjk3MSAyLjMxNmEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtMy45Ny0yLjMxNi0xLjk3NSAxLjE1MVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==", We = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS42ODUgMy4yMWEuNjI1LjYyNSAwIDAgMSAuNjMgMGw3LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhsNy41LTQuMzc1Wk0zLjc0IDguMTI1IDEwIDExLjc3Nmw2LjI2LTMuNjUxTDEwIDQuNDc0IDMuNzQgOC4xMjVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjcxNCAxMCAxMCAxMi41bDQuMjg2LTIuNSAzLjIxNCAxLjg3NUwxMCAxNi4yNWwtNy41LTQuMzc1TDUuNzE0IDEwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS40IDkuNDZhLjYyNS42MjUgMCAwIDEgLjYzIDBMMTAgMTEuNzc2bDMuOTctMi4zMTZhLjYyNS42MjUgMCAwIDEgLjYzIDBsMy4yMTUgMS44NzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhMNS40IDkuNDZabS0xLjY2IDIuNDE1TDEwIDE1LjUyNmw2LjI2LTMuNjUxLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2LTEuOTc1IDEuMTUxWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+", Fe = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTIuNSA2LjI1IDcuNSA0LjM3NSA3LjUtNC4zNzVMMTAgMS44NzUgMi41IDYuMjVaIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOS42ODUgMS4zMzVhLjYyNS42MjUgMCAwIDEgLjYzIDBsNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4bDcuNS00LjM3NVpNMy43NCA2LjI1IDEwIDkuOTAxbDYuMjYtMy42NTFMMTAgMi41OTkgMy43NCA2LjI1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS40IDExLjMzNWEuNjI1LjYyNSAwIDAgMSAuNjMgMEwxMCAxMy42NTFsMy45Ny0yLjMxNmEuNjI1LjYyNSAwIDAgMSAuNjMgMGwzLjIxNSAxLjg3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOEw1LjQgMTEuMzM1Wk0zLjc0IDEzLjc1IDEwIDE3LjQwMWw2LjI2LTMuNjUxLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2TDMuNzQgMTMuNzVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjQgNy41ODVhLjYyNS42MjUgMCAwIDEgLjYzIDBMMTAgOS45MDFsMy45Ny0yLjMxNmEuNjI1LjYyNSAwIDAgMSAuNjMgMGwzLjIxNSAxLjg3NWEuNjI1LjYyNSAwIDAgMSAwIDEuMDhsLTcuNSA0LjM3NWEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtNy41LTQuMzc1YS42MjUuNjI1IDAgMCAxIDAtMS4wOEw1LjQgNy41ODVaTTMuNzQgMTAgMTAgMTMuNjUxIDE2LjI2IDEwbC0xLjk3NC0xLjE1MS0zLjk3MSAyLjMxNmEuNjI1LjYyNSAwIDAgMS0uNjMgMGwtMy45Ny0yLjMxNkwzLjc0IDEwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+", Ve = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMS45NiAxMy40MzVhLjYyNS42MjUgMCAwIDEgLjg1NS0uMjI1TDEwIDE3LjQwMWw3LjE4NS00LjE5YS42MjUuNjI1IDAgMCAxIC42MyAxLjA3OWwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEtLjIyNS0uODU1Wk05LjY4NSAxLjMzNWEuNjI1LjYyNSAwIDAgMSAuNjMgMGw3LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEgMCAxLjA4bC03LjUgNC4zNzVhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTcuNS00LjM3NWEuNjI1LjYyNSAwIDAgMSAwLTEuMDhsNy41LTQuMzc1Wk0zLjc0IDYuMjUgMTAgOS45MDFsNi4yNi0zLjY1MUwxMCAyLjU5OSAzLjc0IDYuMjVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Im01LjcxNCAxMS44NzUgNC4yODYgMi41IDQuMjg2LTIuNUwxNy41IDEzLjc1IDEwIDE4LjEyNSAyLjUgMTMuNzVsMy4yMTQtMS44NzVaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjQgMTEuMzM1YS42MjUuNjI1IDAgMCAxIC42MyAwTDEwIDEzLjY1MWwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCAxMS4zMzVaTTMuNzQgMTMuNzUgMTAgMTcuNDAxbDYuMjYtMy42NTEtMS45NzQtMS4xNTEtMy45NzEgMi4zMTZhLjYyNS42MjUgMCAwIDEtLjYzIDBsLTMuOTctMi4zMTZMMy43NCAxMy43NVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuNCA3LjU4NWEuNjI1LjYyNSAwIDAgMSAuNjMgMEwxMCA5LjkwMWwzLjk3LTIuMzE2YS42MjUuNjI1IDAgMCAxIC42MyAwbDMuMjE1IDEuODc1YS42MjUuNjI1IDAgMCAxIDAgMS4wOGwtNy41IDQuMzc1YS42MjUuNjI1IDAgMCAxLS42MyAwbC03LjUtNC4zNzVhLjYyNS42MjUgMCAwIDEgMC0xLjA4TDUuNCA3LjU4NVpNMy43NCAxMCAxMCAxMy42NTEgMTYuMjYgMTBsLTEuOTc0LTEuMTUxLTMuOTcxIDIuMzE2YS42MjUuNjI1IDAgMCAxLS42MyAwbC0zLjk3LTIuMzE2TDMuNzQgMTBaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=", Ge = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI0VDNEU0MCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOC4xMjUgMS4yNUExLjg3NSAxLjg3NSAwIDAgMCA2LjI1IDMuMTI1di42MjVIMy4xMjVhLjYyNS42MjUgMCAwIDAgMCAxLjI1aC42MjV2MTEuMjVBMS4yNSAxLjI1IDAgMCAwIDUgMTcuNWgxMGExLjI1IDEuMjUgMCAwIDAgMS4yNS0xLjI1VjVoLjYyNWEuNjI1LjYyNSAwIDAgMCAwLTEuMjVIMTMuNzV2LS42MjVhMS44NzUgMS44NzUgMCAwIDAtMS44NzUtMS44NzVoLTMuNzVabTQuMzc1IDIuNXYtLjYyNWEuNjI1LjYyNSAwIDAgMC0uNjI1LS42MjVoLTMuNzVhLjYyNS42MjUgMCAwIDAtLjYyNS42MjV2LjYyNWg1Wk01IDE2LjI1VjVoMTB2MTEuMjVINVpNOC4xMjUgNy41Yy4zNDUgMCAuNjI1LjI4LjYyNS42MjV2NWEuNjI1LjYyNSAwIDEgMS0xLjI1IDB2LTVjMC0uMzQ1LjI4LS42MjUuNjI1LS42MjVabTQuMzc1IDUuNjI1di01YS42MjUuNjI1IDAgMCAwLTEuMjUgMHY1YS42MjUuNjI1IDAgMSAwIDEuMjUgMFoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==";
|
|
491
|
+
function ue(r, e, t, s, n, i, a) {
|
|
491
492
|
try {
|
|
492
|
-
var o = r[i](
|
|
493
|
-
} catch (
|
|
494
|
-
return void t(
|
|
493
|
+
var o = r[i](a), d = o.value;
|
|
494
|
+
} catch (c) {
|
|
495
|
+
return void t(c);
|
|
495
496
|
}
|
|
496
|
-
o.done ? e(
|
|
497
|
+
o.done ? e(d) : Promise.resolve(d).then(s, n);
|
|
497
498
|
}
|
|
498
|
-
function
|
|
499
|
+
function Xe(r) {
|
|
499
500
|
return function() {
|
|
500
501
|
var e = this, t = arguments;
|
|
501
|
-
return new Promise(function(
|
|
502
|
+
return new Promise(function(s, n) {
|
|
502
503
|
var i = r.apply(e, t);
|
|
503
|
-
function
|
|
504
|
-
|
|
504
|
+
function a(d) {
|
|
505
|
+
ue(i, s, n, a, o, "next", d);
|
|
505
506
|
}
|
|
506
|
-
function o(
|
|
507
|
-
|
|
507
|
+
function o(d) {
|
|
508
|
+
ue(i, s, n, a, o, "throw", d);
|
|
508
509
|
}
|
|
509
|
-
|
|
510
|
+
a(void 0);
|
|
510
511
|
});
|
|
511
512
|
};
|
|
512
513
|
}
|
|
@@ -569,18 +570,18 @@ const z = {
|
|
|
569
570
|
}],
|
|
570
571
|
offsetTop: 50,
|
|
571
572
|
icons: {
|
|
572
|
-
copyPaste:
|
|
573
|
-
delete:
|
|
574
|
-
lock:
|
|
575
|
-
unlock:
|
|
576
|
-
bringToFront:
|
|
577
|
-
sendToBack:
|
|
578
|
-
bringForward:
|
|
579
|
-
sendBackwards:
|
|
573
|
+
copyPaste: He,
|
|
574
|
+
delete: Ge,
|
|
575
|
+
lock: _e,
|
|
576
|
+
unlock: Ye,
|
|
577
|
+
bringToFront: Fe,
|
|
578
|
+
sendToBack: Ve,
|
|
579
|
+
bringForward: Pe,
|
|
580
|
+
sendBackwards: We
|
|
580
581
|
},
|
|
581
582
|
handlers: {
|
|
582
583
|
copyPaste: function() {
|
|
583
|
-
var r =
|
|
584
|
+
var r = Xe(function* (t) {
|
|
584
585
|
yield t.clipboardManager.copy(), yield t.clipboardManager.paste();
|
|
585
586
|
});
|
|
586
587
|
function e(t) {
|
|
@@ -611,45 +612,45 @@ const z = {
|
|
|
611
612
|
}
|
|
612
613
|
}
|
|
613
614
|
};
|
|
614
|
-
function
|
|
615
|
+
function Me(r, e) {
|
|
615
616
|
var t = Object.keys(r);
|
|
616
617
|
if (Object.getOwnPropertySymbols) {
|
|
617
|
-
var
|
|
618
|
-
e && (
|
|
619
|
-
return Object.getOwnPropertyDescriptor(r,
|
|
620
|
-
})), t.push.apply(t,
|
|
618
|
+
var s = Object.getOwnPropertySymbols(r);
|
|
619
|
+
e && (s = s.filter(function(n) {
|
|
620
|
+
return Object.getOwnPropertyDescriptor(r, n).enumerable;
|
|
621
|
+
})), t.push.apply(t, s);
|
|
621
622
|
}
|
|
622
623
|
return t;
|
|
623
624
|
}
|
|
624
|
-
function
|
|
625
|
+
function A(r) {
|
|
625
626
|
for (var e = 1; e < arguments.length; e++) {
|
|
626
627
|
var t = arguments[e] != null ? arguments[e] : {};
|
|
627
|
-
e % 2 ?
|
|
628
|
-
|
|
629
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(r, Object.getOwnPropertyDescriptors(t)) :
|
|
630
|
-
Object.defineProperty(r,
|
|
628
|
+
e % 2 ? Me(Object(t), !0).forEach(function(s) {
|
|
629
|
+
Qe(r, s, t[s]);
|
|
630
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(r, Object.getOwnPropertyDescriptors(t)) : Me(Object(t)).forEach(function(s) {
|
|
631
|
+
Object.defineProperty(r, s, Object.getOwnPropertyDescriptor(t, s));
|
|
631
632
|
});
|
|
632
633
|
}
|
|
633
634
|
return r;
|
|
634
635
|
}
|
|
635
|
-
function
|
|
636
|
-
return (e =
|
|
636
|
+
function Qe(r, e, t) {
|
|
637
|
+
return (e = Je(e)) in r ? Object.defineProperty(r, e, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : r[e] = t, r;
|
|
637
638
|
}
|
|
638
|
-
function
|
|
639
|
-
var e =
|
|
639
|
+
function Je(r) {
|
|
640
|
+
var e = $e(r, "string");
|
|
640
641
|
return typeof e == "symbol" ? e : e + "";
|
|
641
642
|
}
|
|
642
|
-
function
|
|
643
|
+
function $e(r, e) {
|
|
643
644
|
if (typeof r != "object" || !r) return r;
|
|
644
645
|
var t = r[Symbol.toPrimitive];
|
|
645
646
|
if (t !== void 0) {
|
|
646
|
-
var
|
|
647
|
-
if (typeof
|
|
647
|
+
var s = t.call(r, e);
|
|
648
|
+
if (typeof s != "object") return s;
|
|
648
649
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
649
650
|
}
|
|
650
651
|
return (e === "string" ? String : Number)(r);
|
|
651
652
|
}
|
|
652
|
-
class
|
|
653
|
+
class Ke {
|
|
653
654
|
/**
|
|
654
655
|
* @param {object} options
|
|
655
656
|
* @param {ImageEditor} options.editor - экземпляр редактора с доступом к canvas
|
|
@@ -660,12 +661,12 @@ class $e {
|
|
|
660
661
|
} = e;
|
|
661
662
|
if (this.options = t.options, !!this.options.showToolbar) {
|
|
662
663
|
this.editor = t, this.canvas = t.canvas;
|
|
663
|
-
var
|
|
664
|
-
this.config =
|
|
665
|
-
style:
|
|
666
|
-
btnStyle:
|
|
667
|
-
icons:
|
|
668
|
-
handlers:
|
|
664
|
+
var s = this.options.toolbar || {};
|
|
665
|
+
this.config = A(A(A({}, z), s), {}, {
|
|
666
|
+
style: A(A({}, z.style), s.style || {}),
|
|
667
|
+
btnStyle: A(A({}, z.btnStyle), s.btnStyle || {}),
|
|
668
|
+
icons: A(A({}, z.icons), s.icons || {}),
|
|
669
|
+
handlers: A(A({}, z.handlers), s.handlers || {})
|
|
669
670
|
}), this.currentTarget = null, this.currentLocked = null, this.isTransforming = !1, this._onMouseDown = this._handleMouseDown.bind(this), this._onObjectMoving = this._startTransform.bind(this), this._onObjectScaling = this._startTransform.bind(this), this._onObjectRotating = this._startTransform.bind(this), this._onMouseUp = this._endTransform.bind(this), this._onObjectModified = this._endTransform.bind(this), this._onSelectionChange = this._updateToolbar.bind(this), this._onSelectionClear = () => {
|
|
670
671
|
this.el.style.display = "none";
|
|
671
672
|
}, this._createDOM(), this._bindEvents();
|
|
@@ -680,11 +681,11 @@ class $e {
|
|
|
680
681
|
style: e
|
|
681
682
|
} = this.config;
|
|
682
683
|
this.el = document.createElement("div"), Object.assign(this.el.style, e), this.canvas.wrapperEl.appendChild(this.el), this._onBtnOver = (t) => {
|
|
683
|
-
var
|
|
684
|
-
|
|
684
|
+
var s = t.target.closest("button");
|
|
685
|
+
s && Object.assign(s.style, this.config.btnHover);
|
|
685
686
|
}, this._onBtnOut = (t) => {
|
|
686
|
-
var
|
|
687
|
-
|
|
687
|
+
var s = t.target.closest("button");
|
|
688
|
+
s && Object.assign(s.style, this.config.btnStyle);
|
|
688
689
|
}, this.el.addEventListener("mouseover", this._onBtnOver), this.el.addEventListener("mouseout", this._onBtnOut);
|
|
689
690
|
}
|
|
690
691
|
/**
|
|
@@ -697,22 +698,22 @@ class $e {
|
|
|
697
698
|
_renderButtons(e) {
|
|
698
699
|
var t = this;
|
|
699
700
|
this.el.innerHTML = "";
|
|
700
|
-
var
|
|
701
|
+
var s = function() {
|
|
701
702
|
var {
|
|
702
|
-
name:
|
|
703
|
+
name: a,
|
|
703
704
|
handle: o
|
|
704
|
-
} =
|
|
705
|
-
icons:
|
|
706
|
-
btnStyle:
|
|
705
|
+
} = n, {
|
|
706
|
+
icons: d,
|
|
707
|
+
btnStyle: c,
|
|
707
708
|
handlers: l
|
|
708
709
|
} = t.config, h = document.createElement("button");
|
|
709
|
-
h.innerHTML =
|
|
710
|
+
h.innerHTML = d[o] ? '<img src="'.concat(d[o], '" title="').concat(a, '" />') : a, Object.assign(h.style, c), h.onclick = () => {
|
|
710
711
|
var g;
|
|
711
712
|
return (g = l[o]) === null || g === void 0 ? void 0 : g.call(l, t.editor);
|
|
712
713
|
}, t.el.appendChild(h);
|
|
713
714
|
};
|
|
714
|
-
for (var
|
|
715
|
-
|
|
715
|
+
for (var n of e)
|
|
716
|
+
s();
|
|
716
717
|
}
|
|
717
718
|
/**
|
|
718
719
|
* Привязывает события к canvas
|
|
@@ -758,8 +759,8 @@ class $e {
|
|
|
758
759
|
var t = !!e.locked;
|
|
759
760
|
if (e !== this.currentTarget || t !== this.currentLocked) {
|
|
760
761
|
this.currentTarget = e, this.currentLocked = t;
|
|
761
|
-
var
|
|
762
|
-
this._renderButtons(
|
|
762
|
+
var s = t ? this.config.lockedActions : this.config.actions;
|
|
763
|
+
this._renderButtons(s);
|
|
763
764
|
}
|
|
764
765
|
this._updatePos();
|
|
765
766
|
}
|
|
@@ -777,16 +778,16 @@ class $e {
|
|
|
777
778
|
}
|
|
778
779
|
var {
|
|
779
780
|
el: t,
|
|
780
|
-
config:
|
|
781
|
-
canvas:
|
|
781
|
+
config: s,
|
|
782
|
+
canvas: n
|
|
782
783
|
} = this;
|
|
783
784
|
e.setCoords();
|
|
784
|
-
var i =
|
|
785
|
-
x:
|
|
785
|
+
var i = n.getZoom(), [, , , , a, o] = n.viewportTransform, {
|
|
786
|
+
x: d
|
|
786
787
|
} = e.getCenterPoint(), {
|
|
787
|
-
top:
|
|
788
|
+
top: c,
|
|
788
789
|
height: l
|
|
789
|
-
} = e.getBoundingRect(!1, !0), h =
|
|
790
|
+
} = e.getBoundingRect(!1, !0), h = d * i + a, g = h - t.offsetWidth / 2, u = (c + l) * i + o + s.offsetTop;
|
|
790
791
|
Object.assign(t.style, {
|
|
791
792
|
left: "".concat(g, "px"),
|
|
792
793
|
top: "".concat(u, "px"),
|
|
@@ -801,7 +802,7 @@ class $e {
|
|
|
801
802
|
this.el.removeEventListener("mouseover", this._onBtnOver), this.el.removeEventListener("mouseout", this._onBtnOut), this.canvas.off("mouse:down", this._onMouseDown), this.canvas.off("object:moving", this._onObjectMoving), this.canvas.off("object:scaling", this._onObjectScaling), this.canvas.off("object:rotating", this._onObjectRotating), this.canvas.off("mouse:up", this._onMouseUp), this.canvas.off("object:modified", this._onObjectModified), this.canvas.off("selection:created", this._onSelectionChange), this.canvas.off("selection:updated", this._onSelectionChange), this.canvas.off("selection:changed", this._onSelectionChange), this.canvas.off("after:render", this._onSelectionChange), this.canvas.off("selection:cleared", this._onSelectionClear), this.el.remove();
|
|
802
803
|
}
|
|
803
804
|
}
|
|
804
|
-
class
|
|
805
|
+
class qe {
|
|
805
806
|
constructor({ editor: e }) {
|
|
806
807
|
this.editor = e, this.canvas = e.canvas, this._historySuspendCount = 0, this.baseState = null, this.patches = [], this.currentIndex = 0, this.maxHistoryLength = e.options.maxHistoryLength, this.totalChangesCount = 0, this.baseStateChangesCount = 0, this._createDiffPatcher();
|
|
807
808
|
}
|
|
@@ -837,7 +838,7 @@ class Ke {
|
|
|
837
838
|
includeValueOnMove: !1
|
|
838
839
|
},
|
|
839
840
|
textDiff: {
|
|
840
|
-
diffMatchPatch:
|
|
841
|
+
diffMatchPatch: Le,
|
|
841
842
|
minLength: 60
|
|
842
843
|
}
|
|
843
844
|
});
|
|
@@ -852,14 +853,12 @@ class Ke {
|
|
|
852
853
|
}
|
|
853
854
|
/**
|
|
854
855
|
* Проверяет, есть ли в редакторе несохранённые изменения
|
|
855
|
-
* @returns {boolean}
|
|
856
856
|
*/
|
|
857
857
|
hasUnsavedChanges() {
|
|
858
858
|
return this.totalChangesCount > 0;
|
|
859
859
|
}
|
|
860
860
|
/**
|
|
861
861
|
* Получает текущую позицию в общей истории изменений
|
|
862
|
-
* @returns {number}
|
|
863
862
|
*/
|
|
864
863
|
getCurrentChangePosition() {
|
|
865
864
|
return this.baseStateChangesCount + this.currentIndex;
|
|
@@ -868,11 +867,11 @@ class Ke {
|
|
|
868
867
|
* Получаем полное состояние, применяя все диффы к базовому состоянию.
|
|
869
868
|
*/
|
|
870
869
|
getFullState() {
|
|
871
|
-
const { baseState: e, currentIndex: t, patches:
|
|
872
|
-
let
|
|
870
|
+
const { baseState: e, currentIndex: t, patches: s } = this;
|
|
871
|
+
let n = JSON.parse(JSON.stringify(e));
|
|
873
872
|
for (let i = 0; i < t; i += 1)
|
|
874
|
-
|
|
875
|
-
return console.log("getFullState state",
|
|
873
|
+
n = this.diffPatcher.patch(n, s[i].diff);
|
|
874
|
+
return console.log("getFullState state", n), n;
|
|
876
875
|
}
|
|
877
876
|
/**
|
|
878
877
|
* Сохраняем текущее состояние в виде диффа от последнего сохранённого полного состояния.
|
|
@@ -900,28 +899,28 @@ class Ke {
|
|
|
900
899
|
this.baseState = e, this.patches = [], this.currentIndex = 0, console.log("Базовое состояние сохранено.");
|
|
901
900
|
return;
|
|
902
901
|
}
|
|
903
|
-
const t = this.getFullState(),
|
|
904
|
-
if (!
|
|
902
|
+
const t = this.getFullState(), s = this.diffPatcher.diff(t, e);
|
|
903
|
+
if (!s) {
|
|
905
904
|
console.log("Нет изменений для сохранения.");
|
|
906
905
|
return;
|
|
907
906
|
}
|
|
908
|
-
console.log("baseState", this.baseState), this.currentIndex < this.patches.length && this.patches.splice(this.currentIndex), console.log("diff",
|
|
907
|
+
console.log("baseState", this.baseState), this.currentIndex < this.patches.length && this.patches.splice(this.currentIndex), console.log("diff", s), this.totalChangesCount += 1, this.patches.push({ id: D(), diff: s }), this.currentIndex += 1, this.patches.length > this.maxHistoryLength && (this.baseState = this.diffPatcher.patch(this.baseState, this.patches[0].diff), this.patches.shift(), this.currentIndex -= 1, this.baseStateChangesCount += 1), console.log("Состояние сохранено. Текущий индекс истории:", this.currentIndex);
|
|
909
908
|
}
|
|
910
909
|
/**
|
|
911
910
|
* Функция загрузки состояния в канвас.
|
|
912
|
-
* @param
|
|
911
|
+
* @param fullState - полное состояние канваса
|
|
913
912
|
* @fires editor:history-state-loaded
|
|
914
913
|
*/
|
|
915
914
|
loadStateFromFullState(e) {
|
|
916
|
-
return
|
|
915
|
+
return y(this, null, function* () {
|
|
917
916
|
if (!e) return;
|
|
918
917
|
console.log("loadStateFromFullState fullState", e);
|
|
919
|
-
const { canvas: t, canvasManager:
|
|
918
|
+
const { canvas: t, canvasManager: s, interactionBlocker: n } = this.editor, { width: i, height: a } = t;
|
|
920
919
|
yield t.loadFromJSON(e);
|
|
921
|
-
const o = t.getObjects().find((
|
|
922
|
-
o && (this.editor.montageArea = o, (i !== e.width ||
|
|
923
|
-
const
|
|
924
|
-
|
|
920
|
+
const o = t.getObjects().find((c) => c.id === "montage-area");
|
|
921
|
+
o && (this.editor.montageArea = o, (i !== e.width || a !== e.height) && s.updateCanvasAndFitObjects());
|
|
922
|
+
const d = t.getObjects().find((c) => c.id === "overlay-mask");
|
|
923
|
+
d && (n.overlayMask = d, n.overlayMask.visible = !1), t.renderAll(), t.fire("editor:history-state-loaded", {
|
|
925
924
|
fullState: e,
|
|
926
925
|
currentIndex: this.currentIndex,
|
|
927
926
|
totalChangesCount: this.totalChangesCount,
|
|
@@ -936,7 +935,7 @@ class Ke {
|
|
|
936
935
|
* @fires editor:undo
|
|
937
936
|
*/
|
|
938
937
|
undo() {
|
|
939
|
-
return
|
|
938
|
+
return y(this, null, function* () {
|
|
940
939
|
if (!this.skipHistory) {
|
|
941
940
|
if (this.currentIndex <= 0) {
|
|
942
941
|
console.log("Нет предыдущих состояний для отмены.");
|
|
@@ -973,7 +972,7 @@ class Ke {
|
|
|
973
972
|
* @fires editor:redo
|
|
974
973
|
*/
|
|
975
974
|
redo() {
|
|
976
|
-
return
|
|
975
|
+
return y(this, null, function* () {
|
|
977
976
|
if (!this.skipHistory) {
|
|
978
977
|
if (this.currentIndex >= this.patches.length) {
|
|
979
978
|
console.log("Нет состояний для повтора.");
|
|
@@ -1006,8 +1005,8 @@ class Ke {
|
|
|
1006
1005
|
});
|
|
1007
1006
|
}
|
|
1008
1007
|
}
|
|
1009
|
-
const
|
|
1010
|
-
class
|
|
1008
|
+
const et = 0.1, tt = 2, st = 0.1, nt = 90, B = 16, U = 16, T = 4096, k = 4096;
|
|
1009
|
+
class N {
|
|
1011
1010
|
constructor({ editor: e }) {
|
|
1012
1011
|
this.editor = e, this.options = e.options, this._createdBlobUrls = [], this.acceptContentTypes = this.editor.options.acceptContentTypes, this.acceptFormats = this.getAllowedFormatsFromContentTypes();
|
|
1013
1012
|
}
|
|
@@ -1023,81 +1022,82 @@ class C {
|
|
|
1023
1022
|
* @param options.withoutSave - Не сохранять в историю изменений
|
|
1024
1023
|
* @returns возвращает Promise с объектом изображения или null в случае ошибки
|
|
1025
1024
|
*/
|
|
1026
|
-
importImage(
|
|
1027
|
-
return
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1025
|
+
importImage(e) {
|
|
1026
|
+
return y(this, null, function* () {
|
|
1027
|
+
const {
|
|
1028
|
+
source: t,
|
|
1029
|
+
scale: s = `image-${this.options.scaleType}`,
|
|
1030
|
+
withoutSave: n = !1
|
|
1031
|
+
} = e;
|
|
1032
|
+
if (!t) return null;
|
|
1033
|
+
const { canvas: i, montageArea: a, transformManager: o, historyManager: d, errorManager: c } = this.editor, l = yield this.getContentType(t), h = N.getFormatFromContentType(l), { acceptContentTypes: g, acceptFormats: u } = this;
|
|
1034
1034
|
if (!this.isAllowedContentType(l)) {
|
|
1035
|
-
const
|
|
1036
|
-
return
|
|
1035
|
+
const f = `Неверный contentType для изображения: ${l}. Ожидается один из: ${this.acceptContentTypes.join(", ")}.`;
|
|
1036
|
+
return c.emitError({
|
|
1037
1037
|
origin: "ImageManager",
|
|
1038
1038
|
method: "importImage",
|
|
1039
1039
|
code: "INVALID_CONTENT_TYPE",
|
|
1040
|
-
message:
|
|
1041
|
-
data: { source:
|
|
1040
|
+
message: f,
|
|
1041
|
+
data: { source: t, format: h, contentType: l, acceptContentTypes: g, acceptFormats: u }
|
|
1042
1042
|
}), null;
|
|
1043
1043
|
}
|
|
1044
|
-
|
|
1044
|
+
d.suspendHistory();
|
|
1045
1045
|
try {
|
|
1046
|
-
let
|
|
1047
|
-
if (
|
|
1048
|
-
|
|
1049
|
-
else if (typeof
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1046
|
+
let f, M;
|
|
1047
|
+
if (t instanceof File)
|
|
1048
|
+
f = URL.createObjectURL(t);
|
|
1049
|
+
else if (typeof t == "string") {
|
|
1050
|
+
const v = yield (yield fetch(t, { mode: "cors" })).blob();
|
|
1051
|
+
f = URL.createObjectURL(v);
|
|
1052
1052
|
} else
|
|
1053
|
-
return
|
|
1053
|
+
return c.emitError({
|
|
1054
1054
|
origin: "ImageManager",
|
|
1055
1055
|
method: "importImage",
|
|
1056
1056
|
code: "INVALID_SOURCE_TYPE",
|
|
1057
1057
|
message: "Неверный тип источника изображения. Ожидается URL или объект File.",
|
|
1058
|
-
data: { source:
|
|
1058
|
+
data: { source: t, format: h, contentType: l, acceptContentTypes: g, acceptFormats: u }
|
|
1059
1059
|
}), null;
|
|
1060
|
-
if (this._createdBlobUrls.push(
|
|
1061
|
-
const
|
|
1062
|
-
M = H.groupSVGElements(
|
|
1060
|
+
if (this._createdBlobUrls.push(f), h === "svg") {
|
|
1061
|
+
const p = yield Ie(f);
|
|
1062
|
+
M = H.groupSVGElements(p.objects, p.options);
|
|
1063
1063
|
} else
|
|
1064
|
-
M = yield Z.fromURL(
|
|
1065
|
-
const { width:
|
|
1064
|
+
M = yield Z.fromURL(f, { crossOrigin: "anonymous" });
|
|
1065
|
+
const { width: m, height: j } = M;
|
|
1066
1066
|
if (M instanceof Z) {
|
|
1067
|
-
const
|
|
1068
|
-
let
|
|
1069
|
-
if (
|
|
1070
|
-
const
|
|
1071
|
-
this._createdBlobUrls.push(
|
|
1072
|
-
} else if (
|
|
1073
|
-
const
|
|
1074
|
-
this._createdBlobUrls.push(
|
|
1067
|
+
const p = M.getElement();
|
|
1068
|
+
let v = "";
|
|
1069
|
+
if (p instanceof HTMLImageElement ? v = p.src : p instanceof HTMLCanvasElement && (v = p.toDataURL()), j > k || m > T) {
|
|
1070
|
+
const w = yield this.resizeImageToBoundaries(v, "max"), O = URL.createObjectURL(w);
|
|
1071
|
+
this._createdBlobUrls.push(O), M = yield Z.fromURL(O, { crossOrigin: "anonymous" });
|
|
1072
|
+
} else if (j < U || m < B) {
|
|
1073
|
+
const w = yield this.resizeImageToBoundaries(v, "min"), O = URL.createObjectURL(w);
|
|
1074
|
+
this._createdBlobUrls.push(O), M = yield Z.fromURL(O, { crossOrigin: "anonymous" });
|
|
1075
1075
|
}
|
|
1076
1076
|
}
|
|
1077
|
-
if (M.set("id", `${M.type}-${D()}`), M.set("format", h),
|
|
1077
|
+
if (M.set("id", `${M.type}-${D()}`), M.set("format", h), s === "scale-montage")
|
|
1078
1078
|
this.editor.canvasManager.scaleMontageAreaToImage({ object: M, withoutSave: !0 });
|
|
1079
1079
|
else {
|
|
1080
|
-
const { width:
|
|
1081
|
-
|
|
1080
|
+
const { width: p, height: v } = a, w = this.calculateScaleFactor({ imageObject: M, scaleType: s });
|
|
1081
|
+
s === "image-contain" && w < 1 ? o.fitObject({ object: M, type: "contain", withoutSave: !0 }) : s === "image-cover" && (m > p || j > v) && o.fitObject({ object: M, type: "cover", withoutSave: !0 });
|
|
1082
1082
|
}
|
|
1083
|
-
i.add(M), i.centerObject(M), i.setActiveObject(M), i.renderAll(),
|
|
1084
|
-
const
|
|
1083
|
+
i.add(M), i.centerObject(M), i.setActiveObject(M), i.renderAll(), d.resumeHistory(), n || d.saveState();
|
|
1084
|
+
const L = {
|
|
1085
1085
|
image: M,
|
|
1086
1086
|
format: h,
|
|
1087
1087
|
contentType: l,
|
|
1088
|
-
scale:
|
|
1089
|
-
withoutSave:
|
|
1090
|
-
source:
|
|
1088
|
+
scale: s,
|
|
1089
|
+
withoutSave: n,
|
|
1090
|
+
source: t
|
|
1091
1091
|
};
|
|
1092
|
-
return i.fire("editor:image-imported",
|
|
1093
|
-
} catch (
|
|
1094
|
-
return
|
|
1092
|
+
return i.fire("editor:image-imported", L), L;
|
|
1093
|
+
} catch (f) {
|
|
1094
|
+
return c.emitError({
|
|
1095
1095
|
origin: "ImageManager",
|
|
1096
1096
|
method: "importImage",
|
|
1097
1097
|
code: "IMPORT_FAILED",
|
|
1098
|
-
message: `Ошибка импорта изображения: ${
|
|
1099
|
-
data: { source:
|
|
1100
|
-
}),
|
|
1098
|
+
message: `Ошибка импорта изображения: ${f.message}`,
|
|
1099
|
+
data: { source: t, format: h, contentType: l, scale: s, withoutSave: n }
|
|
1100
|
+
}), d.resumeHistory(), null;
|
|
1101
1101
|
}
|
|
1102
1102
|
});
|
|
1103
1103
|
}
|
|
@@ -1105,19 +1105,19 @@ class C {
|
|
|
1105
1105
|
* Функция для ресайза изображения до максимальных размеров,
|
|
1106
1106
|
* если оно их превышает. Сохраняет пропорции.
|
|
1107
1107
|
*
|
|
1108
|
-
* @param
|
|
1109
|
-
* @param
|
|
1110
|
-
* @returns
|
|
1108
|
+
* @param dataURL - dataURL изображения
|
|
1109
|
+
* @param size ('max | min') - максимальный или минимальный размер
|
|
1110
|
+
* @returns возвращает Promise с Blob-объектом уменьшенного изображения
|
|
1111
1111
|
*/
|
|
1112
1112
|
resizeImageToBoundaries(e, t = "max") {
|
|
1113
|
-
return
|
|
1114
|
-
let
|
|
1115
|
-
t === "min" && (
|
|
1116
|
-
const
|
|
1113
|
+
return y(this, null, function* () {
|
|
1114
|
+
let s = `Размер изображения больше максимального размера канваса, поэтому оно будет уменьшено до максимальных размеров c сохранением пропорций: ${T}x${k}`;
|
|
1115
|
+
t === "min" && (s = `Размер изображения меньше минимального размера канваса, поэтому оно будет увеличено до минимальных размеров c сохранением пропорций: ${B}x${U}`);
|
|
1116
|
+
const n = {
|
|
1117
1117
|
dataURL: e,
|
|
1118
1118
|
sizeType: t,
|
|
1119
|
-
maxWidth:
|
|
1120
|
-
maxHeight:
|
|
1119
|
+
maxWidth: T,
|
|
1120
|
+
maxHeight: k,
|
|
1121
1121
|
minWidth: B,
|
|
1122
1122
|
minHeight: U
|
|
1123
1123
|
};
|
|
@@ -1125,9 +1125,9 @@ class C {
|
|
|
1125
1125
|
origin: "ImageManager",
|
|
1126
1126
|
method: "resizeImageToBoundaries",
|
|
1127
1127
|
code: "IMAGE_RESIZE_WARNING",
|
|
1128
|
-
message:
|
|
1129
|
-
data:
|
|
1130
|
-
}), this.editor.workerManager.post("resizeImage",
|
|
1128
|
+
message: s,
|
|
1129
|
+
data: n
|
|
1130
|
+
}), this.editor.workerManager.post("resizeImage", n);
|
|
1131
1131
|
});
|
|
1132
1132
|
}
|
|
1133
1133
|
/**
|
|
@@ -1142,101 +1142,101 @@ class C {
|
|
|
1142
1142
|
* @fires editor:canvas-exported
|
|
1143
1143
|
*/
|
|
1144
1144
|
exportCanvasAsImageFile() {
|
|
1145
|
-
return
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1145
|
+
return y(this, arguments, function* (e = {}) {
|
|
1146
|
+
const {
|
|
1147
|
+
fileName: t = "image.png",
|
|
1148
|
+
contentType: s = "image/png",
|
|
1149
|
+
exportAsBase64: n = !1,
|
|
1150
|
+
exportAsBlob: i = !1
|
|
1151
|
+
} = e, { canvas: a, montageArea: o, workerManager: d } = this.editor;
|
|
1152
1152
|
try {
|
|
1153
|
-
const c =
|
|
1154
|
-
|
|
1155
|
-
const { left:
|
|
1156
|
-
["image/jpg", "image/jpeg"].includes(
|
|
1157
|
-
const j =
|
|
1158
|
-
j && (j.visible = !1),
|
|
1159
|
-
const
|
|
1160
|
-
if (
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
const
|
|
1164
|
-
image:
|
|
1165
|
-
exportAsBase64:
|
|
1166
|
-
exportAsBlob:
|
|
1167
|
-
fileName:
|
|
1153
|
+
const c = s === "application/pdf", l = c ? "image/jpg" : s, h = N.getFormatFromContentType(l);
|
|
1154
|
+
o.setCoords();
|
|
1155
|
+
const { left: g, top: u, width: f, height: M } = o.getBoundingRect(), m = yield a.clone(["id", "format", "locked"]);
|
|
1156
|
+
["image/jpg", "image/jpeg"].includes(l) && (m.backgroundColor = "#ffffff");
|
|
1157
|
+
const j = m.getObjects().find((b) => b.id === o.id);
|
|
1158
|
+
j && (j.visible = !1), m.viewportTransform = [1, 0, 0, 1, -g, -u], m.setDimensions({ width: f, height: M }, { backstoreOnly: !0 }), m.renderAll();
|
|
1159
|
+
const L = m.getObjects().filter((b) => b.format).every((b) => b.format === "svg");
|
|
1160
|
+
if (h === "svg" && L) {
|
|
1161
|
+
const b = m.toSVG();
|
|
1162
|
+
m.dispose();
|
|
1163
|
+
const S = {
|
|
1164
|
+
image: N._exportSVGStringAsFile(b, {
|
|
1165
|
+
exportAsBase64: n,
|
|
1166
|
+
exportAsBlob: i,
|
|
1167
|
+
fileName: t
|
|
1168
1168
|
}),
|
|
1169
1169
|
format: "svg",
|
|
1170
1170
|
contentType: "image/svg+xml",
|
|
1171
|
-
fileName:
|
|
1171
|
+
fileName: t.replace(/\.[^/.]+$/, ".svg")
|
|
1172
1172
|
};
|
|
1173
|
-
return
|
|
1173
|
+
return a.fire("editor:canvas-exported", S), S;
|
|
1174
1174
|
}
|
|
1175
|
-
const
|
|
1176
|
-
|
|
1177
|
-
|
|
1175
|
+
const p = yield new Promise((b, x) => {
|
|
1176
|
+
m.getElement().toBlob((S) => {
|
|
1177
|
+
S ? b(S) : x(new Error("Failed to create Blob from canvas"));
|
|
1178
1178
|
});
|
|
1179
1179
|
});
|
|
1180
|
-
if (
|
|
1181
|
-
const
|
|
1182
|
-
image:
|
|
1183
|
-
format:
|
|
1184
|
-
contentType:
|
|
1185
|
-
fileName:
|
|
1180
|
+
if (m.dispose(), i) {
|
|
1181
|
+
const b = {
|
|
1182
|
+
image: p,
|
|
1183
|
+
format: h,
|
|
1184
|
+
contentType: l,
|
|
1185
|
+
fileName: t
|
|
1186
1186
|
};
|
|
1187
|
-
return
|
|
1187
|
+
return a.fire("editor:canvas-exported", b), b;
|
|
1188
1188
|
}
|
|
1189
|
-
const v = yield createImageBitmap(
|
|
1189
|
+
const v = yield createImageBitmap(p), w = yield d.post(
|
|
1190
1190
|
"toDataURL",
|
|
1191
|
-
{ format:
|
|
1191
|
+
{ format: h, quality: 1, bitmap: v },
|
|
1192
1192
|
[v]
|
|
1193
1193
|
);
|
|
1194
1194
|
if (c) {
|
|
1195
|
-
const x =
|
|
1196
|
-
orientation: x >
|
|
1195
|
+
const x = f * 0.264583, S = M * 0.264583, fe = (yield this.editor.moduleLoader.loadModule("jspdf")).jsPDF, X = new fe({
|
|
1196
|
+
orientation: x > S ? "landscape" : "portrait",
|
|
1197
1197
|
unit: "mm",
|
|
1198
|
-
format: [x,
|
|
1198
|
+
format: [x, S]
|
|
1199
1199
|
});
|
|
1200
|
-
if (
|
|
1201
|
-
const
|
|
1202
|
-
image:
|
|
1200
|
+
if (X.addImage(w, "JPG", 0, 0, x, S), n) {
|
|
1201
|
+
const re = {
|
|
1202
|
+
image: X.output("datauristring"),
|
|
1203
1203
|
format: "pdf",
|
|
1204
1204
|
contentType: "application/pdf",
|
|
1205
|
-
fileName:
|
|
1205
|
+
fileName: t
|
|
1206
1206
|
};
|
|
1207
|
-
return
|
|
1207
|
+
return a.fire("editor:canvas-exported", re), re;
|
|
1208
1208
|
}
|
|
1209
|
-
const je =
|
|
1210
|
-
image: new File([je],
|
|
1209
|
+
const je = X.output("blob"), oe = {
|
|
1210
|
+
image: new File([je], t, { type: "application/pdf" }),
|
|
1211
1211
|
format: "pdf",
|
|
1212
1212
|
contentType: "application/pdf",
|
|
1213
|
-
fileName:
|
|
1213
|
+
fileName: t
|
|
1214
1214
|
};
|
|
1215
|
-
return
|
|
1215
|
+
return a.fire("editor:canvas-exported", oe), oe;
|
|
1216
1216
|
}
|
|
1217
|
-
if (
|
|
1218
|
-
const
|
|
1219
|
-
image:
|
|
1220
|
-
format:
|
|
1221
|
-
contentType:
|
|
1222
|
-
fileName:
|
|
1217
|
+
if (n) {
|
|
1218
|
+
const b = {
|
|
1219
|
+
image: w,
|
|
1220
|
+
format: h,
|
|
1221
|
+
contentType: l,
|
|
1222
|
+
fileName: t
|
|
1223
1223
|
};
|
|
1224
|
-
return
|
|
1224
|
+
return a.fire("editor:canvas-exported", b), b;
|
|
1225
1225
|
}
|
|
1226
|
-
const
|
|
1227
|
-
image: new File([
|
|
1228
|
-
format:
|
|
1229
|
-
contentType:
|
|
1230
|
-
fileName:
|
|
1226
|
+
const O = h === "svg" && !L ? t.replace(/\.[^/.]+$/, ".png") : t, ae = {
|
|
1227
|
+
image: new File([p], O, { type: l }),
|
|
1228
|
+
format: h,
|
|
1229
|
+
contentType: l,
|
|
1230
|
+
fileName: O
|
|
1231
1231
|
};
|
|
1232
|
-
return
|
|
1232
|
+
return a.fire("editor:canvas-exported", ae), ae;
|
|
1233
1233
|
} catch (c) {
|
|
1234
1234
|
return this.editor.errorManager.emitError({
|
|
1235
1235
|
origin: "ImageManager",
|
|
1236
1236
|
method: "exportCanvasAsImageFile",
|
|
1237
1237
|
code: "IMAGE_EXPORT_FAILED",
|
|
1238
1238
|
message: `Ошибка экспорта изображения: ${c.message}`,
|
|
1239
|
-
data: { contentType:
|
|
1239
|
+
data: { contentType: s, fileName: t, exportAsBase64: n, exportAsBlob: i }
|
|
1240
1240
|
}), null;
|
|
1241
1241
|
}
|
|
1242
1242
|
});
|
|
@@ -1253,86 +1253,86 @@ class C {
|
|
|
1253
1253
|
* @fires editor:object-exported
|
|
1254
1254
|
*/
|
|
1255
1255
|
exportObjectAsImageFile() {
|
|
1256
|
-
return
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1256
|
+
return y(this, arguments, function* (e = {}) {
|
|
1257
|
+
const {
|
|
1258
|
+
object: t,
|
|
1259
|
+
fileName: s = "image.png",
|
|
1260
|
+
contentType: n = "image/png",
|
|
1261
|
+
exportAsBase64: i = !1,
|
|
1262
|
+
exportAsBlob: a = !1
|
|
1263
|
+
} = e, { canvas: o, workerManager: d } = this.editor, c = t || o.getActiveObject();
|
|
1264
1264
|
if (!c)
|
|
1265
1265
|
return this.editor.errorManager.emitError({
|
|
1266
1266
|
origin: "ImageManager",
|
|
1267
1267
|
method: "exportObjectAsImageFile",
|
|
1268
1268
|
code: "NO_OBJECT_SELECTED",
|
|
1269
1269
|
message: "Не выбран объект для экспорта",
|
|
1270
|
-
data: { contentType:
|
|
1270
|
+
data: { contentType: n, fileName: s, exportAsBase64: i, exportAsBlob: a }
|
|
1271
1271
|
}), null;
|
|
1272
1272
|
try {
|
|
1273
|
-
const
|
|
1274
|
-
if (
|
|
1275
|
-
const
|
|
1276
|
-
exportAsBase64:
|
|
1277
|
-
exportAsBlob:
|
|
1278
|
-
fileName:
|
|
1273
|
+
const l = N.getFormatFromContentType(n);
|
|
1274
|
+
if (l === "svg") {
|
|
1275
|
+
const M = c.toSVG(), m = N._exportSVGStringAsFile(M, {
|
|
1276
|
+
exportAsBase64: i,
|
|
1277
|
+
exportAsBlob: a,
|
|
1278
|
+
fileName: s
|
|
1279
1279
|
}), j = {
|
|
1280
1280
|
object: c,
|
|
1281
|
-
image:
|
|
1282
|
-
format:
|
|
1281
|
+
image: m,
|
|
1282
|
+
format: l,
|
|
1283
1283
|
contentType: "image/svg+xml",
|
|
1284
|
-
fileName:
|
|
1284
|
+
fileName: s.replace(/\.[^/.]+$/, ".svg")
|
|
1285
1285
|
};
|
|
1286
|
-
return
|
|
1286
|
+
return o.fire("editor:object-exported", j), j;
|
|
1287
1287
|
}
|
|
1288
|
-
if (
|
|
1289
|
-
const
|
|
1288
|
+
if (i && c instanceof Z) {
|
|
1289
|
+
const M = yield createImageBitmap(c.getElement()), m = yield d.post(
|
|
1290
1290
|
"toDataURL",
|
|
1291
1291
|
{
|
|
1292
|
-
format:
|
|
1292
|
+
format: l,
|
|
1293
1293
|
quality: 1,
|
|
1294
|
-
bitmap:
|
|
1294
|
+
bitmap: M
|
|
1295
1295
|
},
|
|
1296
|
-
[
|
|
1296
|
+
[M]
|
|
1297
1297
|
), j = {
|
|
1298
1298
|
object: c,
|
|
1299
|
-
image:
|
|
1300
|
-
format:
|
|
1301
|
-
contentType:
|
|
1302
|
-
fileName:
|
|
1299
|
+
image: m,
|
|
1300
|
+
format: l,
|
|
1301
|
+
contentType: n,
|
|
1302
|
+
fileName: s
|
|
1303
1303
|
};
|
|
1304
|
-
return
|
|
1304
|
+
return o.fire("editor:object-exported", j), j;
|
|
1305
1305
|
}
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
-
j ?
|
|
1306
|
+
const h = c.toCanvasElement(), g = yield new Promise((M, m) => {
|
|
1307
|
+
h.toBlob((j) => {
|
|
1308
|
+
j ? M(j) : m(new Error("Failed to create Blob from canvas"));
|
|
1309
1309
|
});
|
|
1310
1310
|
});
|
|
1311
|
-
if (
|
|
1312
|
-
const
|
|
1311
|
+
if (a) {
|
|
1312
|
+
const M = {
|
|
1313
1313
|
object: c,
|
|
1314
|
-
image:
|
|
1315
|
-
format:
|
|
1316
|
-
contentType:
|
|
1317
|
-
fileName:
|
|
1314
|
+
image: g,
|
|
1315
|
+
format: l,
|
|
1316
|
+
contentType: n,
|
|
1317
|
+
fileName: s
|
|
1318
1318
|
};
|
|
1319
|
-
return
|
|
1319
|
+
return o.fire("editor:object-exported", M), M;
|
|
1320
1320
|
}
|
|
1321
|
-
const
|
|
1321
|
+
const u = new File([g], s, { type: n }), f = {
|
|
1322
1322
|
object: c,
|
|
1323
|
-
image:
|
|
1324
|
-
format:
|
|
1325
|
-
contentType:
|
|
1326
|
-
fileName:
|
|
1323
|
+
image: u,
|
|
1324
|
+
format: l,
|
|
1325
|
+
contentType: n,
|
|
1326
|
+
fileName: s
|
|
1327
1327
|
};
|
|
1328
|
-
return
|
|
1329
|
-
} catch (
|
|
1328
|
+
return o.fire("editor:object-exported", f), f;
|
|
1329
|
+
} catch (l) {
|
|
1330
1330
|
return this.editor.errorManager.emitError({
|
|
1331
1331
|
origin: "ImageManager",
|
|
1332
1332
|
method: "exportObjectAsImageFile",
|
|
1333
1333
|
code: "IMAGE_EXPORT_FAILED",
|
|
1334
|
-
message: `Ошибка экспорта объекта: ${
|
|
1335
|
-
data: { contentType:
|
|
1334
|
+
message: `Ошибка экспорта объекта: ${l.message}`,
|
|
1335
|
+
data: { contentType: n, fileName: s, exportAsBase64: i, exportAsBlob: a }
|
|
1336
1336
|
}), null;
|
|
1337
1337
|
}
|
|
1338
1338
|
});
|
|
@@ -1348,7 +1348,7 @@ class C {
|
|
|
1348
1348
|
* @returns массив допустимых форматов изображений
|
|
1349
1349
|
*/
|
|
1350
1350
|
getAllowedFormatsFromContentTypes() {
|
|
1351
|
-
return this.acceptContentTypes.map((e) =>
|
|
1351
|
+
return this.acceptContentTypes.map((e) => N.getFormatFromContentType(e)).filter((e) => e);
|
|
1352
1352
|
}
|
|
1353
1353
|
/**
|
|
1354
1354
|
* Проверяет, является ли contentType допустимым типом изображения.
|
|
@@ -1364,7 +1364,7 @@ class C {
|
|
|
1364
1364
|
* @public
|
|
1365
1365
|
*/
|
|
1366
1366
|
getContentType(e) {
|
|
1367
|
-
return
|
|
1367
|
+
return y(this, null, function* () {
|
|
1368
1368
|
return typeof e == "string" ? this.getContentTypeFromUrl(e) : e.type || "application/octet-stream";
|
|
1369
1369
|
});
|
|
1370
1370
|
}
|
|
@@ -1375,15 +1375,15 @@ class C {
|
|
|
1375
1375
|
* @public
|
|
1376
1376
|
*/
|
|
1377
1377
|
getContentTypeFromUrl(e) {
|
|
1378
|
-
return
|
|
1378
|
+
return y(this, null, function* () {
|
|
1379
1379
|
if (e.startsWith("data:")) {
|
|
1380
1380
|
const t = e.match(/^data:([^;]+)/);
|
|
1381
1381
|
return t ? t[1] : "application/octet-stream";
|
|
1382
1382
|
}
|
|
1383
1383
|
try {
|
|
1384
|
-
const
|
|
1385
|
-
if (
|
|
1386
|
-
return
|
|
1384
|
+
const s = (yield fetch(e, { method: "HEAD" })).headers.get("content-type");
|
|
1385
|
+
if (s && s.startsWith("image/"))
|
|
1386
|
+
return s.split(";")[0];
|
|
1387
1387
|
} catch (t) {
|
|
1388
1388
|
console.warn("HEAD запрос неудачен, определяем тип по расширению:", t);
|
|
1389
1389
|
}
|
|
@@ -1393,19 +1393,19 @@ class C {
|
|
|
1393
1393
|
/**
|
|
1394
1394
|
* Определяет contentType по расширению файла в URL
|
|
1395
1395
|
* @param url - URL файла
|
|
1396
|
-
* @returns
|
|
1396
|
+
* @returns MIME-тип
|
|
1397
1397
|
* @public
|
|
1398
1398
|
*/
|
|
1399
1399
|
getContentTypeFromExtension(e) {
|
|
1400
1400
|
var t;
|
|
1401
1401
|
try {
|
|
1402
|
-
const
|
|
1403
|
-
return this.acceptContentTypes.forEach((
|
|
1404
|
-
const o =
|
|
1405
|
-
o && (i[o] =
|
|
1406
|
-
}),
|
|
1407
|
-
} catch (
|
|
1408
|
-
return console.warn("Не удалось определить расширение из URL:", e,
|
|
1402
|
+
const n = (t = new URL(e).pathname.split(".").pop()) == null ? void 0 : t.toLowerCase(), i = {};
|
|
1403
|
+
return this.acceptContentTypes.forEach((a) => {
|
|
1404
|
+
const o = N.getFormatFromContentType(a);
|
|
1405
|
+
o && (i[o] = a);
|
|
1406
|
+
}), n && i[n] || "application/octet-stream";
|
|
1407
|
+
} catch (s) {
|
|
1408
|
+
return console.warn("Не удалось определить расширение из URL:", e, s), "application/octet-stream";
|
|
1409
1409
|
}
|
|
1410
1410
|
}
|
|
1411
1411
|
/**
|
|
@@ -1419,10 +1419,10 @@ class C {
|
|
|
1419
1419
|
imageObject: e,
|
|
1420
1420
|
scaleType: t = "contain"
|
|
1421
1421
|
}) {
|
|
1422
|
-
const { montageArea:
|
|
1423
|
-
if (!
|
|
1424
|
-
const
|
|
1425
|
-
return t === "contain" || t === "image-contain" ? Math.min(
|
|
1422
|
+
const { montageArea: s } = this.editor;
|
|
1423
|
+
if (!s || !e) return 1;
|
|
1424
|
+
const n = s.width, i = s.height, { width: a, height: o } = e;
|
|
1425
|
+
return t === "contain" || t === "image-contain" ? Math.min(n / a, i / o) : t === "cover" || t === "image-cover" ? Math.max(n / a, i / o) : 1;
|
|
1426
1426
|
}
|
|
1427
1427
|
/**
|
|
1428
1428
|
* Преобразует SVG-строку в Blob, файл, или base64
|
|
@@ -1437,10 +1437,10 @@ class C {
|
|
|
1437
1437
|
*/
|
|
1438
1438
|
static _exportSVGStringAsFile(e, {
|
|
1439
1439
|
exportAsBase64: t,
|
|
1440
|
-
exportAsBlob:
|
|
1441
|
-
fileName:
|
|
1440
|
+
exportAsBlob: s,
|
|
1441
|
+
fileName: n = "image.svg"
|
|
1442
1442
|
} = {}) {
|
|
1443
|
-
return
|
|
1443
|
+
return s ? new Blob([e], { type: "image/svg+xml" }) : t ? `data:image/svg+xml;base64,${window.btoa(encodeURIComponent(e))}` : new File([e], n.replace(/\.[^/.]+$/, ".svg"), { type: "image/svg+xml" });
|
|
1444
1444
|
}
|
|
1445
1445
|
/**
|
|
1446
1446
|
* Извлекает чистый формат (subtype) из contentType,
|
|
@@ -1454,72 +1454,72 @@ class C {
|
|
|
1454
1454
|
return t ? t[1] : "";
|
|
1455
1455
|
}
|
|
1456
1456
|
}
|
|
1457
|
-
class
|
|
1457
|
+
class it {
|
|
1458
1458
|
/**
|
|
1459
|
-
* @param
|
|
1460
|
-
* @param
|
|
1459
|
+
* @param options
|
|
1460
|
+
* @param options.editor – экземпляр редактора
|
|
1461
1461
|
*/
|
|
1462
1462
|
constructor({ editor: e }) {
|
|
1463
1463
|
this.editor = e;
|
|
1464
1464
|
}
|
|
1465
1465
|
/**
|
|
1466
1466
|
* Устанавливаем внутреннюю ширину канваса (для экспорта)
|
|
1467
|
-
* @param
|
|
1468
|
-
* @param
|
|
1469
|
-
* @param
|
|
1470
|
-
* @param
|
|
1471
|
-
* @param
|
|
1467
|
+
* @param width - ширина канваса
|
|
1468
|
+
* @param options
|
|
1469
|
+
* @param options.preserveProportional - Сохранить пропорции
|
|
1470
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1471
|
+
* @param options.adaptCanvasToContainer - Адаптировать канвас к контейнеру
|
|
1472
1472
|
* @fires editor:resolution-width-changed
|
|
1473
1473
|
*/
|
|
1474
|
-
setResolutionWidth(e, { preserveProportional: t, withoutSave:
|
|
1475
|
-
var
|
|
1474
|
+
setResolutionWidth(e, { preserveProportional: t, withoutSave: s, adaptCanvasToContainer: n } = {}) {
|
|
1475
|
+
var f;
|
|
1476
1476
|
if (!e) return;
|
|
1477
1477
|
const {
|
|
1478
1478
|
canvas: i,
|
|
1479
|
-
montageArea:
|
|
1479
|
+
montageArea: a,
|
|
1480
1480
|
options: { canvasBackstoreWidth: o }
|
|
1481
|
-
} = this.editor, { width:
|
|
1482
|
-
if (!o || o === "auto" ||
|
|
1483
|
-
const M = l /
|
|
1484
|
-
this.setResolutionHeight(
|
|
1481
|
+
} = this.editor, { width: d, height: c } = a, l = Math.max(Math.min(Number(e), T), B);
|
|
1482
|
+
if (!o || o === "auto" || n ? this.adaptCanvasToContainer() : o ? this.setCanvasBackstoreWidth(Number(o)) : this.setCanvasBackstoreWidth(l), a.set({ width: l }), (f = i.clipPath) == null || f.set({ width: l }), t) {
|
|
1483
|
+
const M = l / d, m = c * M;
|
|
1484
|
+
this.setResolutionHeight(m);
|
|
1485
1485
|
return;
|
|
1486
1486
|
}
|
|
1487
|
-
const { left: h, top: g } = this.getObjectDefaultCoords(
|
|
1488
|
-
i.setViewportTransform([u, 0, 0, u, h, g]), this.centerMontageArea(),
|
|
1487
|
+
const { left: h, top: g } = this.getObjectDefaultCoords(a), u = i.getZoom();
|
|
1488
|
+
i.setViewportTransform([u, 0, 0, u, h, g]), this.centerMontageArea(), s || this.editor.historyManager.saveState(), i.fire("editor:resolution-width-changed", {
|
|
1489
1489
|
width: l,
|
|
1490
1490
|
preserveProportional: t,
|
|
1491
|
-
withoutSave:
|
|
1492
|
-
adaptCanvasToContainer:
|
|
1491
|
+
withoutSave: s,
|
|
1492
|
+
adaptCanvasToContainer: n
|
|
1493
1493
|
});
|
|
1494
1494
|
}
|
|
1495
1495
|
/**
|
|
1496
1496
|
* Устанавливаем внутреннюю высоту канваса (для экспорта)
|
|
1497
|
-
* @param
|
|
1498
|
-
* @param
|
|
1499
|
-
* @param
|
|
1500
|
-
* @param
|
|
1501
|
-
* @param
|
|
1497
|
+
* @param height - высота канваса
|
|
1498
|
+
* @param options
|
|
1499
|
+
* @param options.preserveProportional - Сохранить пропорции
|
|
1500
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1501
|
+
* @param options.adaptCanvasToContainer - Адаптировать канвас к контейнеру
|
|
1502
1502
|
* @fires editor:resolution-height-changed
|
|
1503
1503
|
*/
|
|
1504
|
-
setResolutionHeight(e, { preserveProportional: t, withoutSave:
|
|
1505
|
-
var
|
|
1504
|
+
setResolutionHeight(e, { preserveProportional: t, withoutSave: s, adaptCanvasToContainer: n } = {}) {
|
|
1505
|
+
var f;
|
|
1506
1506
|
if (!e) return;
|
|
1507
1507
|
const {
|
|
1508
1508
|
canvas: i,
|
|
1509
|
-
montageArea:
|
|
1509
|
+
montageArea: a,
|
|
1510
1510
|
options: { canvasBackstoreHeight: o }
|
|
1511
|
-
} = this.editor, { width:
|
|
1512
|
-
if (!o || o === "auto" ||
|
|
1513
|
-
const M = l /
|
|
1514
|
-
this.setResolutionWidth(
|
|
1511
|
+
} = this.editor, { width: d, height: c } = a, l = Math.max(Math.min(Number(e), k), U);
|
|
1512
|
+
if (!o || o === "auto" || n ? this.adaptCanvasToContainer() : o ? this.setCanvasBackstoreHeight(Number(o)) : this.setCanvasBackstoreHeight(l), a.set({ height: l }), (f = i.clipPath) == null || f.set({ height: l }), t) {
|
|
1513
|
+
const M = l / c, m = d * M;
|
|
1514
|
+
this.setResolutionWidth(m);
|
|
1515
1515
|
return;
|
|
1516
1516
|
}
|
|
1517
|
-
const { left: h, top: g } = this.getObjectDefaultCoords(
|
|
1518
|
-
i.setViewportTransform([u, 0, 0, u, h, g]), this.centerMontageArea(),
|
|
1517
|
+
const { left: h, top: g } = this.getObjectDefaultCoords(a), u = i.getZoom();
|
|
1518
|
+
i.setViewportTransform([u, 0, 0, u, h, g]), this.centerMontageArea(), s || this.editor.historyManager.saveState(), i.fire("editor:resolution-height-changed", {
|
|
1519
1519
|
height: l,
|
|
1520
1520
|
preserveProportional: t,
|
|
1521
|
-
withoutSave:
|
|
1522
|
-
adaptCanvasToContainer:
|
|
1521
|
+
withoutSave: s,
|
|
1522
|
+
adaptCanvasToContainer: n
|
|
1523
1523
|
});
|
|
1524
1524
|
}
|
|
1525
1525
|
/**
|
|
@@ -1527,51 +1527,50 @@ class st {
|
|
|
1527
1527
|
* и устанавливает правильный viewportTransform.
|
|
1528
1528
|
*/
|
|
1529
1529
|
centerMontageArea() {
|
|
1530
|
-
var
|
|
1531
|
-
const { canvas: e, montageArea: t } = this.editor,
|
|
1530
|
+
var d;
|
|
1531
|
+
const { canvas: e, montageArea: t } = this.editor, s = e.getWidth(), n = e.getHeight(), i = e.getZoom(), a = new W(s / 2, n / 2);
|
|
1532
1532
|
t.set({
|
|
1533
|
-
left:
|
|
1534
|
-
top:
|
|
1535
|
-
}), (
|
|
1536
|
-
left:
|
|
1537
|
-
top:
|
|
1533
|
+
left: s / 2,
|
|
1534
|
+
top: n / 2
|
|
1535
|
+
}), (d = e.clipPath) == null || d.set({
|
|
1536
|
+
left: s / 2,
|
|
1537
|
+
top: n / 2
|
|
1538
1538
|
}), e.renderAll();
|
|
1539
1539
|
const o = e.viewportTransform;
|
|
1540
|
-
o[4] =
|
|
1540
|
+
o[4] = s / 2 - a.x * i, o[5] = n / 2 - a.y * i, e.setViewportTransform(o), e.renderAll();
|
|
1541
1541
|
}
|
|
1542
1542
|
/**
|
|
1543
1543
|
* Метод для получения координат объекта с учетом текущего зума
|
|
1544
|
-
* @param
|
|
1545
|
-
* @returns
|
|
1544
|
+
* @param object - объект, координаты которого нужно получить
|
|
1545
|
+
* @returns координаты объекта
|
|
1546
1546
|
*/
|
|
1547
1547
|
getObjectDefaultCoords(e) {
|
|
1548
|
-
const { canvas: t } = this.editor,
|
|
1549
|
-
if (!
|
|
1548
|
+
const { canvas: t } = this.editor, s = e || t.getActiveObject();
|
|
1549
|
+
if (!s)
|
|
1550
1550
|
return this.editor.errorManager.emitError({
|
|
1551
1551
|
origin: "CanvasManager",
|
|
1552
1552
|
method: "getObjectDefaultCoords",
|
|
1553
1553
|
code: "NO_ACTIVE_OBJECT",
|
|
1554
1554
|
message: "Не выбран объект для получения координат"
|
|
1555
1555
|
}), { left: 0, top: 0 };
|
|
1556
|
-
const { width:
|
|
1557
|
-
return { left: o, top:
|
|
1556
|
+
const { width: n, height: i } = s, a = t.getZoom(), o = (n - n * a) / 2, d = (i - i * a) / 2;
|
|
1557
|
+
return { left: o, top: d };
|
|
1558
1558
|
}
|
|
1559
1559
|
/**
|
|
1560
1560
|
* Устанавливаем ширину канваса в backstore (для экспорта)
|
|
1561
|
-
* @param {Number} width
|
|
1562
1561
|
*/
|
|
1563
1562
|
setCanvasBackstoreWidth(e) {
|
|
1564
1563
|
if (!e || typeof e != "number") return;
|
|
1565
|
-
const t = Math.max(Math.min(e,
|
|
1564
|
+
const t = Math.max(Math.min(e, T), B);
|
|
1566
1565
|
this.editor.canvas.setDimensions({ width: t }, { backstoreOnly: !0 });
|
|
1567
1566
|
}
|
|
1568
1567
|
/**
|
|
1569
1568
|
* Устанавливаем высоту канваса в backstore (для экспорта)
|
|
1570
|
-
* @param
|
|
1569
|
+
* @param height
|
|
1571
1570
|
*/
|
|
1572
1571
|
setCanvasBackstoreHeight(e) {
|
|
1573
1572
|
if (!e || typeof e != "number") return;
|
|
1574
|
-
const t = Math.max(Math.min(e,
|
|
1573
|
+
const t = Math.max(Math.min(e, k), U);
|
|
1575
1574
|
this.editor.canvas.setDimensions({ height: t }, { backstoreOnly: !0 });
|
|
1576
1575
|
}
|
|
1577
1576
|
/**
|
|
@@ -1580,8 +1579,8 @@ class st {
|
|
|
1580
1579
|
* с учётом минимальных и максимальных значений.
|
|
1581
1580
|
*/
|
|
1582
1581
|
adaptCanvasToContainer() {
|
|
1583
|
-
const { canvas: e } = this.editor, t = e.editorContainer,
|
|
1584
|
-
console.log("adaptCanvasToContainer newWidth", i), console.log("adaptCanvasToContainer newHeight",
|
|
1582
|
+
const { canvas: e } = this.editor, t = e.editorContainer, s = t.clientWidth, n = t.clientHeight, i = Math.max(Math.min(s, T), B), a = Math.max(Math.min(n, k), U);
|
|
1583
|
+
console.log("adaptCanvasToContainer newWidth", i), console.log("adaptCanvasToContainer newHeight", a), e.setDimensions({ width: i, height: a }, { backstoreOnly: !0 });
|
|
1585
1584
|
}
|
|
1586
1585
|
/**
|
|
1587
1586
|
* Обновляет размеры канваса и вписывает объекты в монтажную область.
|
|
@@ -1592,14 +1591,14 @@ class st {
|
|
|
1592
1591
|
const {
|
|
1593
1592
|
canvas: e,
|
|
1594
1593
|
selectionManager: t,
|
|
1595
|
-
transformManager:
|
|
1594
|
+
transformManager: s,
|
|
1596
1595
|
montageArea: {
|
|
1597
|
-
width:
|
|
1596
|
+
width: n,
|
|
1598
1597
|
height: i
|
|
1599
1598
|
}
|
|
1600
1599
|
} = this.editor;
|
|
1601
|
-
this.setResolutionWidth(
|
|
1602
|
-
width:
|
|
1600
|
+
this.setResolutionWidth(n, { adaptCanvasToContainer: !0, withoutSave: !0 }), this.setResolutionHeight(i, { adaptCanvasToContainer: !0, withoutSave: !0 }), this.centerMontageArea(), t.selectAll(), s.fitObject({ fitAsOneObject: !0, withoutSave: !0 }), e.fire("editor:canvas-updated", {
|
|
1601
|
+
width: n,
|
|
1603
1602
|
height: i
|
|
1604
1603
|
});
|
|
1605
1604
|
}
|
|
@@ -1612,20 +1611,20 @@ class st {
|
|
|
1612
1611
|
*
|
|
1613
1612
|
* Метод нужно вызывать после zoomToPoint.
|
|
1614
1613
|
*
|
|
1615
|
-
* @param
|
|
1614
|
+
* @param zoom — текущее значение zoom (например, 1, 1.2, 2 и т.д.)
|
|
1616
1615
|
*/
|
|
1617
1616
|
updateCssDimensionsForZoom(e) {
|
|
1618
|
-
const { canvas: t, montageArea:
|
|
1619
|
-
if (!(
|
|
1620
|
-
const o =
|
|
1617
|
+
const { canvas: t, montageArea: s } = this.editor, n = s.width * e, i = s.height * e, a = t.wrapperEl.parentNode;
|
|
1618
|
+
if (!(a instanceof HTMLElement)) return;
|
|
1619
|
+
const o = n <= a.clientWidth ? "100%" : n, d = i <= a.clientHeight ? "100%" : i;
|
|
1621
1620
|
t.setDimensions(
|
|
1622
|
-
{ width: o, height:
|
|
1621
|
+
{ width: o, height: d },
|
|
1623
1622
|
{ cssOnly: !0 }
|
|
1624
1623
|
);
|
|
1625
1624
|
}
|
|
1626
1625
|
/**
|
|
1627
1626
|
* Устанавливаем CSS ширину канваса для отображения
|
|
1628
|
-
* @param
|
|
1627
|
+
* @param width
|
|
1629
1628
|
* @fires editor:display-canvas-width-changed
|
|
1630
1629
|
*/
|
|
1631
1630
|
setCanvasCSSWidth(e) {
|
|
@@ -1637,7 +1636,7 @@ class st {
|
|
|
1637
1636
|
}
|
|
1638
1637
|
/**
|
|
1639
1638
|
* Устанавливаем CSS высоту канваса для отображения
|
|
1640
|
-
* @param
|
|
1639
|
+
* @param height
|
|
1641
1640
|
* @fires editor:display-canvas-height-changed
|
|
1642
1641
|
*/
|
|
1643
1642
|
setCanvasCSSHeight(e) {
|
|
@@ -1649,7 +1648,7 @@ class st {
|
|
|
1649
1648
|
}
|
|
1650
1649
|
/**
|
|
1651
1650
|
* Устанавливаем CSS ширину обертки канваса для отображения
|
|
1652
|
-
* @param
|
|
1651
|
+
* @param width
|
|
1653
1652
|
* @fires editor:display-wrapper-width-changed
|
|
1654
1653
|
*/
|
|
1655
1654
|
setCanvasWrapperWidth(e) {
|
|
@@ -1661,7 +1660,7 @@ class st {
|
|
|
1661
1660
|
}
|
|
1662
1661
|
/**
|
|
1663
1662
|
* Устанавливаем CSS высоту обертки канваса для отображения
|
|
1664
|
-
* @param
|
|
1663
|
+
* @param height
|
|
1665
1664
|
* @fires editor:display-wrapper-height-changed
|
|
1666
1665
|
*/
|
|
1667
1666
|
setCanvasWrapperHeight(e) {
|
|
@@ -1673,7 +1672,7 @@ class st {
|
|
|
1673
1672
|
}
|
|
1674
1673
|
/**
|
|
1675
1674
|
* Устанавливаем CSS ширину контейнера редактора для отображения
|
|
1676
|
-
* @param
|
|
1675
|
+
* @param width
|
|
1677
1676
|
* @fires editor:display-container-width-changed
|
|
1678
1677
|
*/
|
|
1679
1678
|
setEditorContainerWidth(e) {
|
|
@@ -1685,7 +1684,7 @@ class st {
|
|
|
1685
1684
|
}
|
|
1686
1685
|
/**
|
|
1687
1686
|
* Устанавливаем CSS высоту контейнера редактора для отображения
|
|
1688
|
-
* @param
|
|
1687
|
+
* @param height
|
|
1689
1688
|
* @fires editor:display-container-height-changed
|
|
1690
1689
|
*/
|
|
1691
1690
|
setEditorContainerHeight(e) {
|
|
@@ -1697,79 +1696,79 @@ class st {
|
|
|
1697
1696
|
}
|
|
1698
1697
|
/**
|
|
1699
1698
|
* Устанавливаем CSS ширину или высоту канваса для отображения
|
|
1700
|
-
* @param
|
|
1701
|
-
* @param
|
|
1699
|
+
* @param options
|
|
1700
|
+
* @param options.element - элемент, для которого устанавливаем размеры:
|
|
1702
1701
|
* canvas (upper & lower), wrapper, container
|
|
1703
|
-
* @param
|
|
1704
|
-
* @param
|
|
1702
|
+
* @param options.dimension - размер, который нужно установить: width или height
|
|
1703
|
+
* @param options.value - значение размера (строка или число)
|
|
1705
1704
|
* @fires editor:display-{element}-{dimension}-changed
|
|
1706
1705
|
*/
|
|
1707
|
-
setDisplayDimension({ element: e = "canvas", dimension: t, value:
|
|
1708
|
-
if (!
|
|
1709
|
-
const { canvas:
|
|
1706
|
+
setDisplayDimension({ element: e = "canvas", dimension: t, value: s } = {}) {
|
|
1707
|
+
if (!s) return;
|
|
1708
|
+
const { canvas: n, options: { editorContainer: i } } = this.editor, a = [];
|
|
1710
1709
|
switch (e) {
|
|
1711
1710
|
case "canvas":
|
|
1712
|
-
|
|
1711
|
+
a.push(n.lowerCanvasEl, n.upperCanvasEl);
|
|
1713
1712
|
break;
|
|
1714
1713
|
case "wrapper":
|
|
1715
|
-
|
|
1714
|
+
a.push(n.wrapperEl);
|
|
1716
1715
|
break;
|
|
1717
1716
|
case "container":
|
|
1718
|
-
|
|
1717
|
+
a.push(i);
|
|
1719
1718
|
break;
|
|
1720
1719
|
default:
|
|
1721
|
-
|
|
1720
|
+
a.push(n.lowerCanvasEl, n.upperCanvasEl);
|
|
1722
1721
|
}
|
|
1723
1722
|
const o = t === "width" ? "width" : "height";
|
|
1724
|
-
if (typeof
|
|
1725
|
-
|
|
1726
|
-
|
|
1723
|
+
if (typeof s == "string") {
|
|
1724
|
+
a.forEach((c) => {
|
|
1725
|
+
c.style[o] = s;
|
|
1727
1726
|
});
|
|
1728
1727
|
return;
|
|
1729
1728
|
}
|
|
1730
|
-
if (isNaN(
|
|
1731
|
-
const
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
}),
|
|
1729
|
+
if (isNaN(s)) return;
|
|
1730
|
+
const d = `${s}px`;
|
|
1731
|
+
a.forEach((c) => {
|
|
1732
|
+
c.style[o] = d;
|
|
1733
|
+
}), n.fire(`editor:display-${e}-${o}-changed`, {
|
|
1735
1734
|
element: e,
|
|
1736
|
-
value:
|
|
1735
|
+
value: s
|
|
1737
1736
|
});
|
|
1738
1737
|
}
|
|
1739
1738
|
/**
|
|
1740
1739
|
* Если изображение вписывается в допустимые значения, то масштабируем под него канвас
|
|
1741
|
-
* @param
|
|
1742
|
-
* @param
|
|
1743
|
-
* @param
|
|
1744
|
-
* @param
|
|
1740
|
+
* @param options
|
|
1741
|
+
* @param options.object - Объект с изображением, которое нужно масштабировать
|
|
1742
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1743
|
+
* @param options.preserveAspectRatio - Сохранять изначальные пропорции монтажной области
|
|
1745
1744
|
* @fires editor:montage-area-scaled-to-image
|
|
1746
1745
|
*/
|
|
1747
|
-
scaleMontageAreaToImage({ object: e, preserveAspectRatio: t, withoutSave:
|
|
1746
|
+
scaleMontageAreaToImage({ object: e, preserveAspectRatio: t, withoutSave: s } = {}) {
|
|
1748
1747
|
const {
|
|
1749
|
-
canvas:
|
|
1748
|
+
canvas: n,
|
|
1750
1749
|
montageArea: i,
|
|
1751
|
-
transformManager:
|
|
1750
|
+
transformManager: a,
|
|
1752
1751
|
options: {
|
|
1753
1752
|
montageAreaWidth: o,
|
|
1754
|
-
montageAreaHeight:
|
|
1753
|
+
montageAreaHeight: d
|
|
1755
1754
|
}
|
|
1756
|
-
} = this.editor,
|
|
1757
|
-
if (!
|
|
1758
|
-
const { width: l, height: h } =
|
|
1759
|
-
let g = Math.min(l,
|
|
1755
|
+
} = this.editor, c = e || n.getActiveObject();
|
|
1756
|
+
if (!c || c.type !== "image" && c.format !== "svg") return;
|
|
1757
|
+
const { width: l, height: h } = c;
|
|
1758
|
+
let g = Math.min(l, T), u = Math.min(h, k);
|
|
1760
1759
|
if (t) {
|
|
1761
1760
|
const {
|
|
1762
|
-
width:
|
|
1761
|
+
width: f,
|
|
1763
1762
|
height: M
|
|
1764
|
-
} = i,
|
|
1765
|
-
g =
|
|
1763
|
+
} = i, m = l / f, j = h / M, L = Math.max(m, j);
|
|
1764
|
+
g = f * L, u = M * L;
|
|
1766
1765
|
}
|
|
1767
|
-
this.setResolutionWidth(g, { withoutSave: !0 }), this.setResolutionHeight(u, { withoutSave: !0 }), (l > o || h >
|
|
1768
|
-
object:
|
|
1766
|
+
this.setResolutionWidth(g, { withoutSave: !0 }), this.setResolutionHeight(u, { withoutSave: !0 }), (l > o || h > d) && a.calculateAndApplyDefaultZoom(), a.resetObject(c, { withoutSave: !0 }), n.centerObject(c), n.renderAll(), s || this.editor.historyManager.saveState(), n.fire("editor:montage-area-scaled-to-image", {
|
|
1767
|
+
object: c,
|
|
1769
1768
|
width: g,
|
|
1770
1769
|
height: u,
|
|
1771
1770
|
preserveAspectRatio: t,
|
|
1772
|
-
withoutSave:
|
|
1771
|
+
withoutSave: s
|
|
1773
1772
|
});
|
|
1774
1773
|
}
|
|
1775
1774
|
/**
|
|
@@ -1777,69 +1776,69 @@ class st {
|
|
|
1777
1776
|
* @fires editor:cleared
|
|
1778
1777
|
*/
|
|
1779
1778
|
clearCanvas() {
|
|
1780
|
-
const { canvas: e, montageArea: t, historyManager:
|
|
1781
|
-
|
|
1779
|
+
const { canvas: e, montageArea: t, historyManager: s } = this.editor;
|
|
1780
|
+
s.suspendHistory(), e.clear(), e.add(t), e.renderAll(), s.resumeHistory(), s.saveState(), e == null || e.fire("editor:cleared");
|
|
1782
1781
|
}
|
|
1783
1782
|
/**
|
|
1784
1783
|
* Установка зума и масштаба для канваса и сброс трансформации всех объектов
|
|
1785
|
-
* @param
|
|
1786
|
-
* @param
|
|
1784
|
+
* @param options
|
|
1785
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1787
1786
|
* @fires editor:default-scale-set
|
|
1788
1787
|
*/
|
|
1789
1788
|
setDefaultScale({ withoutSave: e } = {}) {
|
|
1790
1789
|
const {
|
|
1791
1790
|
canvas: t,
|
|
1792
|
-
transformManager:
|
|
1793
|
-
historyManager:
|
|
1791
|
+
transformManager: s,
|
|
1792
|
+
historyManager: n,
|
|
1794
1793
|
options: {
|
|
1795
1794
|
montageAreaWidth: i,
|
|
1796
|
-
montageAreaHeight:
|
|
1795
|
+
montageAreaHeight: a
|
|
1797
1796
|
}
|
|
1798
1797
|
} = this.editor;
|
|
1799
|
-
|
|
1798
|
+
s.resetZoom(), this.setResolutionWidth(i, { withoutSave: !0 }), this.setResolutionHeight(a, { withoutSave: !0 }), t.renderAll(), s.resetObjects(), e || n.saveState(), t.fire("editor:default-scale-set");
|
|
1800
1799
|
}
|
|
1801
1800
|
/**
|
|
1802
1801
|
* Получение всех объектов внутри монтажной области редактора
|
|
1803
|
-
* @returns
|
|
1802
|
+
* @returns массив объектов
|
|
1804
1803
|
*/
|
|
1805
1804
|
getObjects() {
|
|
1806
|
-
const { canvas: e, montageArea: t, interactionBlocker: { overlayMask:
|
|
1807
|
-
return e.getObjects().filter((i) => i.id !== t.id && i.id !==
|
|
1805
|
+
const { canvas: e, montageArea: t, interactionBlocker: { overlayMask: s } } = this.editor;
|
|
1806
|
+
return e.getObjects().filter((i) => i.id !== t.id && i.id !== (s == null ? void 0 : s.id));
|
|
1808
1807
|
}
|
|
1809
1808
|
}
|
|
1810
|
-
class
|
|
1809
|
+
class at {
|
|
1811
1810
|
constructor({ editor: e }) {
|
|
1812
|
-
this.editor = e, this.options = e.options, this.minZoom = this.options.minZoom ||
|
|
1811
|
+
this.editor = e, this.options = e.options, this.minZoom = this.options.minZoom || et, this.maxZoom = this.options.maxZoom || tt, this.defaultZoom = this.options.defaultScale, this.maxZoomFactor = this.options.maxZoomFactor;
|
|
1813
1812
|
}
|
|
1814
1813
|
/**
|
|
1815
1814
|
* Метод рассчитывает и применяет зум по умолчанию для монтажной области редактора.
|
|
1816
1815
|
* Зум рассчитывается исходя из размеров контейнера редактора и текущих размеров монтажной области.
|
|
1817
1816
|
* Расчёт происходит таким образом, чтобы монтажная область визуально целиком помещалась в контейнер редактора.
|
|
1818
1817
|
* Если scale не передан, то используется значение из options.defaultScale.
|
|
1819
|
-
* @param
|
|
1818
|
+
* @param scale - Желаемый масштаб относительно размеров контейнера редактора.
|
|
1820
1819
|
*/
|
|
1821
1820
|
calculateAndApplyDefaultZoom(e = this.options.defaultScale) {
|
|
1822
|
-
const { canvas: t } = this.editor,
|
|
1823
|
-
this.defaultZoom = Math.min(
|
|
1821
|
+
const { canvas: t } = this.editor, s = t.editorContainer, n = s.clientWidth, i = s.clientHeight, { width: a, height: o } = this.editor.montageArea, d = n / a * e, c = i / o * e;
|
|
1822
|
+
this.defaultZoom = Math.min(d, c);
|
|
1824
1823
|
const { defaultZoom: l, maxZoomFactor: h, minZoom: g, maxZoom: u } = this;
|
|
1825
1824
|
this.minZoom = Math.min(l / h, g), this.maxZoom = Math.max(l * h, u), this.setZoom();
|
|
1826
1825
|
}
|
|
1827
1826
|
/**
|
|
1828
1827
|
* Увеличение/уменьшение масштаба
|
|
1829
|
-
* @param
|
|
1830
|
-
* @param
|
|
1831
|
-
* @param
|
|
1832
|
-
* @param
|
|
1828
|
+
* @param scale - Шаг зума
|
|
1829
|
+
* @param options - Координаты зума (по умолчанию центр канваса)
|
|
1830
|
+
* @param options.pointX - Координата X точки зума
|
|
1831
|
+
* @param options.pointY - Координата Y точки зума
|
|
1833
1832
|
* @fires editor:zoom-changed
|
|
1834
1833
|
* Если передавать координаты курсора, то нужно быть аккуратнее, так как юзер может выйти за пределы рабочей области
|
|
1835
1834
|
*/
|
|
1836
|
-
zoom(e =
|
|
1835
|
+
zoom(e = st, t = {}) {
|
|
1837
1836
|
var g, u;
|
|
1838
1837
|
if (!e) return;
|
|
1839
|
-
const { minZoom:
|
|
1840
|
-
let h = Number((
|
|
1841
|
-
h >
|
|
1842
|
-
currentZoom:
|
|
1838
|
+
const { minZoom: s, maxZoom: n } = this, { canvas: i } = this.editor, a = i.getZoom(), o = i.getCenterPoint(), d = (g = t.pointX) != null ? g : o.x, c = (u = t.pointY) != null ? u : o.y, l = new W(d, c);
|
|
1839
|
+
let h = Number((a + Number(e)).toFixed(2));
|
|
1840
|
+
h > n && (h = n), h < s && (h = s), i.zoomToPoint(l, h), console.log({
|
|
1841
|
+
currentZoom: a,
|
|
1843
1842
|
zoom: h,
|
|
1844
1843
|
point: l
|
|
1845
1844
|
}), i.fire("editor:zoom-changed", {
|
|
@@ -1850,15 +1849,15 @@ class it {
|
|
|
1850
1849
|
}
|
|
1851
1850
|
/**
|
|
1852
1851
|
* Установка зума
|
|
1853
|
-
* @param
|
|
1852
|
+
* @param zoom - Зум
|
|
1854
1853
|
* @fires editor:zoom-changed
|
|
1855
1854
|
*/
|
|
1856
1855
|
setZoom(e = this.defaultZoom) {
|
|
1857
|
-
const { minZoom: t, maxZoom:
|
|
1858
|
-
let
|
|
1859
|
-
e >
|
|
1860
|
-
currentZoom:
|
|
1861
|
-
zoom:
|
|
1856
|
+
const { minZoom: t, maxZoom: s } = this, { canvas: n } = this.editor, i = new W(n.getCenterPoint());
|
|
1857
|
+
let a = e;
|
|
1858
|
+
e > s && (a = s), e < t && (a = t), n.zoomToPoint(i, a), n.fire("editor:zoom-changed", {
|
|
1859
|
+
currentZoom: n.getZoom(),
|
|
1860
|
+
zoom: a,
|
|
1862
1861
|
point: i
|
|
1863
1862
|
});
|
|
1864
1863
|
}
|
|
@@ -1875,105 +1874,108 @@ class it {
|
|
|
1875
1874
|
}
|
|
1876
1875
|
/**
|
|
1877
1876
|
* Поворот объекта на заданный угол
|
|
1878
|
-
* @param
|
|
1879
|
-
* @param
|
|
1880
|
-
* @param
|
|
1877
|
+
* @param angle
|
|
1878
|
+
* @param options
|
|
1879
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1881
1880
|
* @fires editor:object-rotated
|
|
1882
1881
|
*/
|
|
1883
|
-
rotate(e =
|
|
1884
|
-
const { canvas:
|
|
1882
|
+
rotate(e = nt, { withoutSave: t } = {}) {
|
|
1883
|
+
const { canvas: s, historyManager: n } = this.editor, i = s.getActiveObject();
|
|
1885
1884
|
if (!i) return;
|
|
1886
|
-
const
|
|
1887
|
-
i.rotate(
|
|
1885
|
+
const a = i.angle + e;
|
|
1886
|
+
i.rotate(a), i.setCoords(), s.renderAll(), t || n.saveState(), s.fire("editor:object-rotated", {
|
|
1888
1887
|
object: i,
|
|
1889
1888
|
withoutSave: t,
|
|
1890
|
-
angle:
|
|
1889
|
+
angle: a
|
|
1891
1890
|
});
|
|
1892
1891
|
}
|
|
1893
1892
|
/**
|
|
1894
1893
|
* Отразить по горизонтали
|
|
1895
|
-
* @param
|
|
1896
|
-
* @param
|
|
1894
|
+
* @param options
|
|
1895
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1897
1896
|
* @fires editor:object-flipped-x
|
|
1898
1897
|
*/
|
|
1899
1898
|
flipX({ withoutSave: e } = {}) {
|
|
1900
|
-
const { canvas: t, historyManager:
|
|
1901
|
-
|
|
1902
|
-
object:
|
|
1899
|
+
const { canvas: t, historyManager: s } = this.editor, n = t.getActiveObject();
|
|
1900
|
+
n && (n.flipX = !n.flipX, t.renderAll(), e || s.saveState(), t.fire("editor:object-flipped-x", {
|
|
1901
|
+
object: n,
|
|
1903
1902
|
withoutSave: e
|
|
1904
1903
|
}));
|
|
1905
1904
|
}
|
|
1906
1905
|
/**
|
|
1907
1906
|
* Отразить по вертикали
|
|
1908
|
-
* @param
|
|
1909
|
-
* @param
|
|
1907
|
+
* @param options
|
|
1908
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1910
1909
|
* @fires editor:object-flipped-y
|
|
1911
1910
|
*/
|
|
1912
1911
|
flipY({ withoutSave: e } = {}) {
|
|
1913
|
-
const { canvas: t, historyManager:
|
|
1914
|
-
|
|
1915
|
-
object:
|
|
1912
|
+
const { canvas: t, historyManager: s } = this.editor, n = t.getActiveObject();
|
|
1913
|
+
n && (n.flipY = !n.flipY, t.renderAll(), e || s.saveState(), t.fire("editor:object-flipped-y", {
|
|
1914
|
+
object: n,
|
|
1916
1915
|
withoutSave: e
|
|
1917
1916
|
}));
|
|
1918
1917
|
}
|
|
1919
1918
|
/**
|
|
1920
1919
|
* Установка прозрачности объекта
|
|
1921
|
-
* @param
|
|
1920
|
+
* @param options
|
|
1921
|
+
* @param options.object - Объект, для которого нужно установить прозрачность
|
|
1922
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1923
|
+
* @param options.opacity - Прозрачность от 0 до 1
|
|
1922
1924
|
* @fires editor:object-opacity-changed
|
|
1923
1925
|
*/
|
|
1924
1926
|
setActiveObjectOpacity({
|
|
1925
1927
|
object: e,
|
|
1926
1928
|
opacity: t = 1,
|
|
1927
|
-
withoutSave:
|
|
1929
|
+
withoutSave: s
|
|
1928
1930
|
} = {}) {
|
|
1929
|
-
const { canvas:
|
|
1930
|
-
|
|
1931
|
+
const { canvas: n, historyManager: i } = this.editor, a = e || n.getActiveObject();
|
|
1932
|
+
a && (a instanceof I ? a.getObjects().forEach((o) => {
|
|
1931
1933
|
o.set("opacity", t);
|
|
1932
|
-
}) :
|
|
1933
|
-
object:
|
|
1934
|
+
}) : a.set("opacity", t), n.renderAll(), s || i.saveState(), n.fire("editor:object-opacity-changed", {
|
|
1935
|
+
object: a,
|
|
1934
1936
|
opacity: t,
|
|
1935
|
-
withoutSave:
|
|
1937
|
+
withoutSave: s
|
|
1936
1938
|
}));
|
|
1937
1939
|
}
|
|
1938
1940
|
/**
|
|
1939
1941
|
* Масштабирование объекта
|
|
1940
|
-
* @param
|
|
1941
|
-
* @param
|
|
1942
|
-
* @param
|
|
1942
|
+
* @param options
|
|
1943
|
+
* @param options.object - Объект с изображением, которое нужно масштабировать
|
|
1944
|
+
* @param options.type - Тип масштабирования
|
|
1943
1945
|
* 'contain' - скейлит картинку, чтобы она вмещалась
|
|
1944
1946
|
* 'cover' - скейлит картинку, чтобы она вписалась в размер канвас
|
|
1945
|
-
* @param
|
|
1946
|
-
* @param
|
|
1947
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1948
|
+
* @param options.fitAsOneObject - Масштабировать все объекты в активной группе как один объект
|
|
1947
1949
|
* @fires editor:image-fitted
|
|
1948
1950
|
*/
|
|
1949
1951
|
fitObject({
|
|
1950
1952
|
object: e,
|
|
1951
1953
|
type: t = this.options.scaleType,
|
|
1952
|
-
withoutSave:
|
|
1953
|
-
fitAsOneObject:
|
|
1954
|
+
withoutSave: s,
|
|
1955
|
+
fitAsOneObject: n
|
|
1954
1956
|
} = {}) {
|
|
1955
|
-
const { canvas: i, imageManager:
|
|
1956
|
-
if (
|
|
1957
|
-
if (
|
|
1958
|
-
const
|
|
1959
|
-
i.discardActiveObject(),
|
|
1960
|
-
const g =
|
|
1957
|
+
const { canvas: i, imageManager: a, historyManager: o } = this.editor, d = e || i.getActiveObject();
|
|
1958
|
+
if (d) {
|
|
1959
|
+
if (d.set("angle", 0), d instanceof I && !n) {
|
|
1960
|
+
const c = d.getObjects();
|
|
1961
|
+
i.discardActiveObject(), c.forEach((h) => {
|
|
1962
|
+
const g = a.calculateScaleFactor({ imageObject: h, scaleType: t });
|
|
1961
1963
|
h.scale(g), i.centerObject(h);
|
|
1962
1964
|
});
|
|
1963
|
-
const l = new
|
|
1965
|
+
const l = new I(c, { canvas: i });
|
|
1964
1966
|
i.setActiveObject(l);
|
|
1965
1967
|
} else {
|
|
1966
|
-
const
|
|
1967
|
-
imageObject:
|
|
1968
|
+
const c = a.calculateScaleFactor({
|
|
1969
|
+
imageObject: d,
|
|
1968
1970
|
scaleType: t
|
|
1969
1971
|
});
|
|
1970
|
-
|
|
1972
|
+
d.scale(c), i.centerObject(d);
|
|
1971
1973
|
}
|
|
1972
|
-
i.renderAll(),
|
|
1973
|
-
object:
|
|
1974
|
+
i.renderAll(), s || o.saveState(), i.fire("editor:object-fitted", {
|
|
1975
|
+
object: d,
|
|
1974
1976
|
type: t,
|
|
1975
|
-
withoutSave:
|
|
1976
|
-
fitAsOneObject:
|
|
1977
|
+
withoutSave: s,
|
|
1978
|
+
fitAsOneObject: n
|
|
1977
1979
|
});
|
|
1978
1980
|
}
|
|
1979
1981
|
}
|
|
@@ -1987,66 +1989,54 @@ class it {
|
|
|
1987
1989
|
}
|
|
1988
1990
|
/**
|
|
1989
1991
|
* Сброс масштаба объекта до дефолтного
|
|
1990
|
-
* @param
|
|
1991
|
-
* @param
|
|
1992
|
-
* @param
|
|
1993
|
-
* @param
|
|
1994
|
-
* @returns
|
|
1992
|
+
* @param object
|
|
1993
|
+
* @param options
|
|
1994
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
1995
|
+
* @param options.alwaysFitObject - вписывать объект в рабочую область даже если он меньше рабочей области
|
|
1995
1996
|
* @fires editor:object-reset
|
|
1996
1997
|
*/
|
|
1997
|
-
resetObject(e, { alwaysFitObject: t = !1, withoutSave:
|
|
1998
|
+
resetObject(e, { alwaysFitObject: t = !1, withoutSave: s = !1 } = {}) {
|
|
1998
1999
|
const {
|
|
1999
|
-
canvas:
|
|
2000
|
+
canvas: n,
|
|
2000
2001
|
montageArea: i,
|
|
2001
|
-
imageManager:
|
|
2002
|
+
imageManager: a,
|
|
2002
2003
|
historyManager: o,
|
|
2003
|
-
options: { scaleType:
|
|
2004
|
-
} = this.editor,
|
|
2005
|
-
if (!
|
|
2006
|
-
if (o.suspendHistory(),
|
|
2004
|
+
options: { scaleType: d }
|
|
2005
|
+
} = this.editor, c = e || n.getActiveObject();
|
|
2006
|
+
if (!c || c.locked) return;
|
|
2007
|
+
if (o.suspendHistory(), c.type === "image" || c.format === "svg" || c.set({
|
|
2007
2008
|
scaleX: 1,
|
|
2008
2009
|
scaleY: 1,
|
|
2009
2010
|
flipX: !1,
|
|
2010
2011
|
flipY: !1,
|
|
2011
2012
|
angle: 0
|
|
2012
2013
|
}), t)
|
|
2013
|
-
this.fitObject({ object:
|
|
2014
|
+
this.fitObject({ object: c, withoutSave: !0, fitAsOneObject: !0 });
|
|
2014
2015
|
else {
|
|
2015
|
-
const { width: h, height: g } = i, { width: u, height:
|
|
2016
|
-
imageObject:
|
|
2017
|
-
scaleType:
|
|
2016
|
+
const { width: h, height: g } = i, { width: u, height: f } = c, M = a.calculateScaleFactor({
|
|
2017
|
+
imageObject: c,
|
|
2018
|
+
scaleType: d
|
|
2018
2019
|
});
|
|
2019
|
-
|
|
2020
|
+
d === "contain" && M < 1 || d === "cover" && (u > h || f > g) ? this.fitObject({ object: c, withoutSave: !0, fitAsOneObject: !0 }) : c.set({ scaleX: 1, scaleY: 1 });
|
|
2020
2021
|
}
|
|
2021
|
-
|
|
2022
|
-
object:
|
|
2023
|
-
withoutSave:
|
|
2022
|
+
c.set({ flipX: !1, flipY: !1, angle: 0 }), n.centerObject(c), n.renderAll(), o.resumeHistory(), s || o.saveState(), n.fire("editor:object-reset", {
|
|
2023
|
+
object: c,
|
|
2024
|
+
withoutSave: s,
|
|
2024
2025
|
alwaysFitObject: t
|
|
2025
2026
|
});
|
|
2026
2027
|
}
|
|
2027
2028
|
}
|
|
2028
|
-
class
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
* @param {ImageEditor} options.editor – экземпляр редактора
|
|
2032
|
-
*/
|
|
2033
|
-
constructor(e) {
|
|
2034
|
-
var {
|
|
2035
|
-
editor: t
|
|
2036
|
-
} = e;
|
|
2037
|
-
this.editor = t, this.isBlocked = !1, this.overlayMask = null, this._createOverlay();
|
|
2029
|
+
class ot {
|
|
2030
|
+
constructor({ editor: e }) {
|
|
2031
|
+
this.editor = e, this.isBlocked = !1, this.overlayMask = null, this._createOverlay();
|
|
2038
2032
|
}
|
|
2039
2033
|
/**
|
|
2040
2034
|
* Создаёт overlay для блокировки монтажной области
|
|
2041
|
-
* @private
|
|
2042
|
-
* @returns {void}
|
|
2043
2035
|
*/
|
|
2044
2036
|
_createOverlay() {
|
|
2045
|
-
|
|
2037
|
+
const {
|
|
2046
2038
|
historyManager: e,
|
|
2047
|
-
options: {
|
|
2048
|
-
overlayMaskColor: t = "rgba(0,0,0,0.5)"
|
|
2049
|
-
}
|
|
2039
|
+
options: { overlayMaskColor: t = "rgba(0,0,0,0.5)" }
|
|
2050
2040
|
} = this.editor;
|
|
2051
2041
|
e.suspendHistory(), this.overlayMask = this.editor.shapeManager.addRectangle({
|
|
2052
2042
|
fill: t,
|
|
@@ -2057,156 +2047,104 @@ class nt {
|
|
|
2057
2047
|
hasControls: !1,
|
|
2058
2048
|
visible: !1,
|
|
2059
2049
|
id: "overlay-mask"
|
|
2060
|
-
}, {
|
|
2061
|
-
withoutSelection: !0
|
|
2062
|
-
}), e.resumeHistory();
|
|
2050
|
+
}, { withoutSelection: !0 }), e.resumeHistory();
|
|
2063
2051
|
}
|
|
2064
2052
|
/**
|
|
2065
2053
|
* Обновляет размеры и позицию overlay, выносит его на передний план
|
|
2066
|
-
* @returns {void}
|
|
2067
2054
|
*/
|
|
2068
2055
|
refresh() {
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
}
|
|
2074
|
-
if (!(!t || !this.overlayMask)) {
|
|
2075
|
-
a.suspendHistory(), t.setCoords();
|
|
2076
|
-
var {
|
|
2077
|
-
left: s,
|
|
2078
|
-
top: i,
|
|
2079
|
-
width: n,
|
|
2080
|
-
height: o
|
|
2081
|
-
} = t.getBoundingRect();
|
|
2082
|
-
this.overlayMask.set({
|
|
2083
|
-
left: s,
|
|
2084
|
-
top: i,
|
|
2085
|
-
width: n,
|
|
2086
|
-
height: o
|
|
2087
|
-
}), e.discardActiveObject(), this.editor.layerManager.bringToFront(this.overlayMask, {
|
|
2088
|
-
withoutSave: !0
|
|
2089
|
-
}), a.resumeHistory();
|
|
2090
|
-
}
|
|
2056
|
+
const { canvas: e, montageArea: t, historyManager: s } = this.editor;
|
|
2057
|
+
if (!t || !this.overlayMask) return;
|
|
2058
|
+
s.suspendHistory(), t.setCoords();
|
|
2059
|
+
const { left: n, top: i, width: a, height: o } = t.getBoundingRect();
|
|
2060
|
+
this.overlayMask.set({ left: n, top: i, width: a, height: o }), e.discardActiveObject(), this.editor.layerManager.bringToFront(this.overlayMask, { withoutSave: !0 }), s.resumeHistory();
|
|
2091
2061
|
}
|
|
2092
2062
|
/**
|
|
2093
2063
|
* Выключает редактор:
|
|
2094
2064
|
* - убирает все селекты, события мыши, скейл/драг–н–дроп
|
|
2095
2065
|
* - делает все объекты не‑evented и не‑selectable
|
|
2096
2066
|
* - делает видимым overlayMask поверх всех объектов в монтажной области
|
|
2097
|
-
* @returns {void}
|
|
2098
2067
|
*/
|
|
2099
2068
|
block() {
|
|
2100
|
-
if (!this.
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
} = this.editor;
|
|
2106
|
-
a.suspendHistory(), this.isBlocked = !0, e.discardActiveObject(), e.selection = !1, e.skipTargetFind = !0, t.getObjects().forEach((s) => {
|
|
2107
|
-
s.evented = !1, s.selectable = !1;
|
|
2108
|
-
}), e.upperCanvasEl.style.pointerEvents = "none", e.lowerCanvasEl.style.pointerEvents = "none", this.overlayMask.visible = !0, this.refresh(), e.fire("editor:disabled"), a.resumeHistory();
|
|
2109
|
-
}
|
|
2069
|
+
if (this.isBlocked || !this.overlayMask) return;
|
|
2070
|
+
const { canvas: e, canvasManager: t, historyManager: s } = this.editor;
|
|
2071
|
+
s.suspendHistory(), this.isBlocked = !0, e.discardActiveObject(), e.selection = !1, e.skipTargetFind = !0, t.getObjects().forEach((n) => {
|
|
2072
|
+
n.evented = !1, n.selectable = !1;
|
|
2073
|
+
}), e.upperCanvasEl.style.pointerEvents = "none", e.lowerCanvasEl.style.pointerEvents = "none", this.overlayMask.visible = !0, this.refresh(), e.fire("editor:disabled"), s.resumeHistory();
|
|
2110
2074
|
}
|
|
2111
2075
|
/**
|
|
2112
2076
|
* Включает редактор
|
|
2113
|
-
* @returns {void}
|
|
2114
2077
|
*/
|
|
2115
2078
|
unblock() {
|
|
2116
|
-
if (this.isBlocked)
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
} = this.editor;
|
|
2122
|
-
a.suspendHistory(), this.isBlocked = !1, e.selection = !0, e.skipTargetFind = !1, t.getObjects().forEach((s) => {
|
|
2123
|
-
s.evented = !0, s.selectable = !0;
|
|
2124
|
-
}), e.upperCanvasEl.style.pointerEvents = "", e.lowerCanvasEl.style.pointerEvents = "", this.overlayMask.visible = !1, e.requestRenderAll(), e.fire("editor:enabled"), a.resumeHistory();
|
|
2125
|
-
}
|
|
2079
|
+
if (!this.isBlocked || !this.overlayMask) return;
|
|
2080
|
+
const { canvas: e, canvasManager: t, historyManager: s } = this.editor;
|
|
2081
|
+
s.suspendHistory(), this.isBlocked = !1, e.selection = !0, e.skipTargetFind = !1, t.getObjects().forEach((n) => {
|
|
2082
|
+
n.evented = !0, n.selectable = !0;
|
|
2083
|
+
}), e.upperCanvasEl.style.pointerEvents = "", e.lowerCanvasEl.style.pointerEvents = "", this.overlayMask.visible = !1, e.requestRenderAll(), e.fire("editor:enabled"), s.resumeHistory();
|
|
2126
2084
|
}
|
|
2127
2085
|
}
|
|
2128
2086
|
class F {
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
* @param {ImageEditor} options.editor - экземпляр редактора с доступом к canvas
|
|
2132
|
-
*/
|
|
2133
|
-
constructor(e) {
|
|
2134
|
-
var {
|
|
2135
|
-
editor: t
|
|
2136
|
-
} = e;
|
|
2137
|
-
this.editor = t;
|
|
2087
|
+
constructor({ editor: e }) {
|
|
2088
|
+
this.editor = e;
|
|
2138
2089
|
}
|
|
2139
2090
|
/**
|
|
2140
2091
|
* Поднять объект навверх по оси Z
|
|
2141
|
-
* @param
|
|
2142
|
-
* @param
|
|
2143
|
-
* @param
|
|
2092
|
+
* @param object
|
|
2093
|
+
* @param options
|
|
2094
|
+
* @param options.withoutSave - Не сохранять действие в истории изменений
|
|
2144
2095
|
* @fires editor:object-bring-to-front
|
|
2145
2096
|
*/
|
|
2146
|
-
bringToFront(e) {
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
}
|
|
2153
|
-
s.suspendHistory();
|
|
2154
|
-
var i = e || a.getActiveObject();
|
|
2155
|
-
i && (i.type === "activeselection" ? i.getObjects().forEach((n) => {
|
|
2156
|
-
a.bringObjectToFront(n);
|
|
2157
|
-
}) : a.bringObjectToFront(i), a.renderAll(), s.resumeHistory(), t || s.saveState(), a.fire("editor:object-bring-to-front", {
|
|
2097
|
+
bringToFront(e, { withoutSave: t } = {}) {
|
|
2098
|
+
const { canvas: s, historyManager: n } = this.editor;
|
|
2099
|
+
n.suspendHistory();
|
|
2100
|
+
const i = e || s.getActiveObject();
|
|
2101
|
+
i && (i instanceof I ? i.getObjects().forEach((a) => {
|
|
2102
|
+
s.bringObjectToFront(a);
|
|
2103
|
+
}) : s.bringObjectToFront(i), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:object-bring-to-front", {
|
|
2158
2104
|
object: i,
|
|
2159
2105
|
withoutSave: t
|
|
2160
2106
|
}));
|
|
2161
2107
|
}
|
|
2162
2108
|
/**
|
|
2163
2109
|
* Поднять объект на один уровень вверх по оси Z
|
|
2164
|
-
* @param
|
|
2165
|
-
* @param
|
|
2166
|
-
* @param
|
|
2110
|
+
* @param object
|
|
2111
|
+
* @param options
|
|
2112
|
+
* @param options.withoutSave - Не сохранять действие в истории изменений
|
|
2167
2113
|
* @fires editor:object-bring-forward
|
|
2168
2114
|
*/
|
|
2169
|
-
bringForward(e) {
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
historyManager: s
|
|
2175
|
-
} = this.editor;
|
|
2176
|
-
s.suspendHistory();
|
|
2177
|
-
var i = e || a.getActiveObject();
|
|
2178
|
-
i && (i.type === "activeselection" ? F._moveSelectionForward(a, i) : a.bringObjectForward(i), a.renderAll(), s.resumeHistory(), t || s.saveState(), a.fire("editor:object-bring-forward", {
|
|
2115
|
+
bringForward(e, { withoutSave: t } = {}) {
|
|
2116
|
+
const { canvas: s, historyManager: n } = this.editor;
|
|
2117
|
+
n.suspendHistory();
|
|
2118
|
+
const i = e || s.getActiveObject();
|
|
2119
|
+
i && (i instanceof I ? F._moveSelectionForward(s, i) : s.bringObjectForward(i), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:object-bring-forward", {
|
|
2179
2120
|
object: i,
|
|
2180
2121
|
withoutSave: t
|
|
2181
2122
|
}));
|
|
2182
2123
|
}
|
|
2183
2124
|
/**
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
sendToBack(e) {
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
canvas: a,
|
|
2195
|
-
montageArea: s,
|
|
2125
|
+
* Отправить объект на задний план по оси Z
|
|
2126
|
+
* @param object
|
|
2127
|
+
* @param options
|
|
2128
|
+
* @param options.withoutSave - Не сохранять действие в истории изменений
|
|
2129
|
+
* @fires editor:object-send-to-back
|
|
2130
|
+
*/
|
|
2131
|
+
sendToBack(e, { withoutSave: t } = {}) {
|
|
2132
|
+
const {
|
|
2133
|
+
canvas: s,
|
|
2134
|
+
montageArea: n,
|
|
2196
2135
|
historyManager: i,
|
|
2197
|
-
interactionBlocker: {
|
|
2198
|
-
overlayMask: n
|
|
2199
|
-
}
|
|
2136
|
+
interactionBlocker: { overlayMask: a }
|
|
2200
2137
|
} = this.editor;
|
|
2201
2138
|
i.suspendHistory();
|
|
2202
|
-
|
|
2139
|
+
const o = e || s.getActiveObject();
|
|
2203
2140
|
if (o) {
|
|
2204
|
-
if (o
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2141
|
+
if (o instanceof I) {
|
|
2142
|
+
const d = o.getObjects();
|
|
2143
|
+
for (let c = d.length - 1; c >= 0; c -= 1)
|
|
2144
|
+
s.sendObjectToBack(d[c]);
|
|
2145
|
+
} else
|
|
2146
|
+
s.sendObjectToBack(o);
|
|
2147
|
+
s.sendObjectToBack(n), a && s.sendObjectToBack(a), s.renderAll(), i.resumeHistory(), t || i.saveState(), s.fire("editor:object-send-to-back", {
|
|
2210
2148
|
object: o,
|
|
2211
2149
|
withoutSave: t
|
|
2212
2150
|
});
|
|
@@ -2214,97 +2152,87 @@ class F {
|
|
|
2214
2152
|
}
|
|
2215
2153
|
/**
|
|
2216
2154
|
* Отправить объект на один уровень ниже по оси Z
|
|
2217
|
-
* @param
|
|
2218
|
-
* @param
|
|
2219
|
-
* @param
|
|
2155
|
+
* @param object
|
|
2156
|
+
* @param options
|
|
2157
|
+
* @param options.withoutSave - Не сохранять действие в истории изменений
|
|
2220
2158
|
*/
|
|
2221
|
-
sendBackwards(e) {
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
canvas: a,
|
|
2226
|
-
montageArea: s,
|
|
2159
|
+
sendBackwards(e, { withoutSave: t } = {}) {
|
|
2160
|
+
const {
|
|
2161
|
+
canvas: s,
|
|
2162
|
+
montageArea: n,
|
|
2227
2163
|
historyManager: i,
|
|
2228
|
-
interactionBlocker: {
|
|
2229
|
-
overlayMask: n
|
|
2230
|
-
}
|
|
2164
|
+
interactionBlocker: { overlayMask: a }
|
|
2231
2165
|
} = this.editor;
|
|
2232
2166
|
i.suspendHistory();
|
|
2233
|
-
|
|
2234
|
-
o && (o
|
|
2167
|
+
const o = e || s.getActiveObject();
|
|
2168
|
+
o && (o instanceof I ? F._moveSelectionBackwards(s, o) : s.sendObjectBackwards(o), s.sendObjectToBack(n), a && s.sendObjectToBack(a), s.renderAll(), i.resumeHistory(), t || i.saveState(), s.fire("editor:object-send-backwards", {
|
|
2235
2169
|
object: o,
|
|
2236
2170
|
withoutSave: t
|
|
2237
2171
|
}));
|
|
2238
2172
|
}
|
|
2239
2173
|
/**
|
|
2240
2174
|
* Сдвигает выделенные объекты на один уровень вверх относительно ближайшего верхнего объекта
|
|
2241
|
-
* @param
|
|
2242
|
-
* @param
|
|
2243
|
-
* @returns {void}
|
|
2244
|
-
* @private
|
|
2175
|
+
* @param canvas - экземпляр холста
|
|
2176
|
+
* @param activeSelection - активное выделение
|
|
2245
2177
|
*/
|
|
2246
2178
|
static _moveSelectionForward(e, t) {
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
obj: l,
|
|
2256
|
-
index: a.indexOf(l)
|
|
2257
|
-
})).sort((l, h) => h.index - l.index);
|
|
2258
|
-
d.forEach((l) => {
|
|
2259
|
-
var h = a.indexOf(l.obj);
|
|
2260
|
-
h < n && (e.moveObjectTo(l.obj, n), n = h);
|
|
2261
|
-
});
|
|
2179
|
+
const s = e.getObjects(), n = t.getObjects(), i = n.map((o) => s.indexOf(o));
|
|
2180
|
+
let a = -1;
|
|
2181
|
+
for (let o = 0; o < s.length; o += 1) {
|
|
2182
|
+
const d = s[o];
|
|
2183
|
+
if (!n.includes(d) && i.some((c) => o > c)) {
|
|
2184
|
+
a = o;
|
|
2185
|
+
break;
|
|
2186
|
+
}
|
|
2262
2187
|
}
|
|
2188
|
+
a !== -1 && n.map((d) => ({ obj: d, index: s.indexOf(d) })).sort((d, c) => c.index - d.index).forEach((d) => {
|
|
2189
|
+
const c = s.indexOf(d.obj);
|
|
2190
|
+
c < a && (e.moveObjectTo(d.obj, a), a = c);
|
|
2191
|
+
});
|
|
2263
2192
|
}
|
|
2264
2193
|
/**
|
|
2265
2194
|
* Сдвигает выделенные объекты на один уровень вниз относительно ближайшего нижнего объекта
|
|
2266
|
-
* @param
|
|
2267
|
-
* @param
|
|
2268
|
-
* @returns {void}
|
|
2269
|
-
* @private
|
|
2195
|
+
* @param canvas - экземпляр холста
|
|
2196
|
+
* @param activeSelection - активное выделение
|
|
2270
2197
|
*/
|
|
2271
2198
|
static _moveSelectionBackwards(e, t) {
|
|
2272
|
-
|
|
2273
|
-
|
|
2199
|
+
const s = e.getObjects(), n = t.getObjects(), i = Math.min(...n.map((a) => s.indexOf(a)));
|
|
2200
|
+
for (let a = n.length - 1; a >= 0; a -= 1)
|
|
2201
|
+
e.moveObjectTo(n[a], i - 1);
|
|
2274
2202
|
}
|
|
2275
2203
|
}
|
|
2276
|
-
class
|
|
2204
|
+
class rt {
|
|
2277
2205
|
/**
|
|
2278
2206
|
* Менеджер фигур для редактора.
|
|
2279
|
-
* @param
|
|
2280
|
-
* @param
|
|
2207
|
+
* @param options - Опции и настройки менеджера фигур.
|
|
2208
|
+
* @param options.editor - Ссылка на экземпляр редактора.
|
|
2281
2209
|
*/
|
|
2282
2210
|
constructor({ editor: e }) {
|
|
2283
2211
|
this.editor = e;
|
|
2284
2212
|
}
|
|
2285
2213
|
/**
|
|
2286
2214
|
* Добавление прямоугольника
|
|
2287
|
-
* @param
|
|
2288
|
-
* @param
|
|
2289
|
-
* @param
|
|
2290
|
-
* @param
|
|
2291
|
-
* @param
|
|
2292
|
-
* @param
|
|
2293
|
-
* @param
|
|
2294
|
-
* @param
|
|
2215
|
+
* @param shapeOptions
|
|
2216
|
+
* @param shapeOptions.id - Уникальный идентификатор фигуры
|
|
2217
|
+
* @param shapeOptions.left - Координата X
|
|
2218
|
+
* @param shapeOptions.top - Координата Y
|
|
2219
|
+
* @param shapeOptions.width - Ширина
|
|
2220
|
+
* @param shapeOptions.height - Высота
|
|
2221
|
+
* @param shapeOptions.fill - Цвет заливки
|
|
2222
|
+
* @param shapeOptions.rest - Остальные параметры
|
|
2295
2223
|
*
|
|
2296
|
-
* @param
|
|
2297
|
-
* @param
|
|
2298
|
-
* @param
|
|
2224
|
+
* @param flags - Флаги для управления поведением
|
|
2225
|
+
* @param flags.withoutSelection - Не выделять объект
|
|
2226
|
+
* @param flags.withoutAdding - Не добавлять объект в canvas
|
|
2299
2227
|
*/
|
|
2300
|
-
addRectangle(l = {}, { withoutSelection:
|
|
2228
|
+
addRectangle(l = {}, { withoutSelection: d, withoutAdding: c } = {}) {
|
|
2301
2229
|
var h = l, {
|
|
2302
2230
|
id: e = `rect-${D()}`,
|
|
2303
2231
|
left: t,
|
|
2304
|
-
top:
|
|
2305
|
-
width:
|
|
2232
|
+
top: s,
|
|
2233
|
+
width: n = 100,
|
|
2306
2234
|
height: i = 100,
|
|
2307
|
-
fill:
|
|
2235
|
+
fill: a = "blue"
|
|
2308
2236
|
} = h, o = Y(h, [
|
|
2309
2237
|
"id",
|
|
2310
2238
|
"left",
|
|
@@ -2313,80 +2241,80 @@ class ot {
|
|
|
2313
2241
|
"height",
|
|
2314
2242
|
"fill"
|
|
2315
2243
|
]);
|
|
2316
|
-
const { canvas: g } = this.editor, u = new
|
|
2244
|
+
const { canvas: g } = this.editor, u = new ve(E({
|
|
2317
2245
|
id: e,
|
|
2318
2246
|
left: t,
|
|
2319
|
-
top:
|
|
2320
|
-
width:
|
|
2247
|
+
top: s,
|
|
2248
|
+
width: n,
|
|
2321
2249
|
height: i,
|
|
2322
|
-
fill:
|
|
2250
|
+
fill: a
|
|
2323
2251
|
}, o));
|
|
2324
|
-
return !t && !
|
|
2252
|
+
return !t && !s && g.centerObject(u), c || (g.add(u), d || g.setActiveObject(u), g.renderAll()), u;
|
|
2325
2253
|
}
|
|
2326
2254
|
/**
|
|
2327
2255
|
* Добавление круга
|
|
2328
|
-
* @param
|
|
2329
|
-
* @param
|
|
2330
|
-
* @param
|
|
2331
|
-
* @param
|
|
2332
|
-
* @param
|
|
2333
|
-
* @param
|
|
2334
|
-
* @param
|
|
2335
|
-
* @param
|
|
2336
|
-
* @param
|
|
2256
|
+
* @param shapeOptions
|
|
2257
|
+
* @param shapeOptions.id - Уникальный идентификатор фигуры
|
|
2258
|
+
* @param shapeOptions.left - Координата X
|
|
2259
|
+
* @param shapeOptions.top - Координата Y
|
|
2260
|
+
* @param shapeOptions.radius - Радиус
|
|
2261
|
+
* @param shapeOptions.fill - Цвет заливки
|
|
2262
|
+
* @param shapeOptions.originX - Ориентация по X
|
|
2263
|
+
* @param shapeOptions.originY - Ориентация по Y
|
|
2264
|
+
* @param shapeOptions.rest - Остальные параметры
|
|
2337
2265
|
*
|
|
2338
|
-
* @param
|
|
2339
|
-
* @param
|
|
2340
|
-
* @param
|
|
2266
|
+
* @param flags - Флаги для управления поведением
|
|
2267
|
+
* @param flags.withoutSelection - Не выделять объект
|
|
2268
|
+
* @param flags.withoutAdding - Не добавлять объект в canvas
|
|
2341
2269
|
*/
|
|
2342
|
-
addCircle(
|
|
2343
|
-
var l =
|
|
2270
|
+
addCircle(c = {}, { withoutSelection: o, withoutAdding: d } = {}) {
|
|
2271
|
+
var l = c, {
|
|
2344
2272
|
id: e = `circle-${D()}`,
|
|
2345
2273
|
left: t,
|
|
2346
|
-
top:
|
|
2347
|
-
radius:
|
|
2274
|
+
top: s,
|
|
2275
|
+
radius: n = 50,
|
|
2348
2276
|
fill: i = "green"
|
|
2349
|
-
} = l,
|
|
2277
|
+
} = l, a = Y(l, [
|
|
2350
2278
|
"id",
|
|
2351
2279
|
"left",
|
|
2352
2280
|
"top",
|
|
2353
2281
|
"radius",
|
|
2354
2282
|
"fill"
|
|
2355
2283
|
]);
|
|
2356
|
-
const { canvas: h } = this.editor, g = new
|
|
2284
|
+
const { canvas: h } = this.editor, g = new Ae(E({
|
|
2357
2285
|
id: e,
|
|
2358
2286
|
left: t,
|
|
2359
|
-
top:
|
|
2287
|
+
top: s,
|
|
2360
2288
|
fill: i,
|
|
2361
|
-
radius:
|
|
2362
|
-
},
|
|
2363
|
-
return !t && !
|
|
2289
|
+
radius: n
|
|
2290
|
+
}, a));
|
|
2291
|
+
return !t && !s && h.centerObject(g), d || (h.add(g), o || h.setActiveObject(g), h.renderAll()), g;
|
|
2364
2292
|
}
|
|
2365
2293
|
/**
|
|
2366
2294
|
* Добавление треугольника
|
|
2367
|
-
* @param
|
|
2368
|
-
* @param
|
|
2369
|
-
* @param
|
|
2370
|
-
* @param
|
|
2371
|
-
* @param
|
|
2372
|
-
* @param
|
|
2373
|
-
* @param
|
|
2374
|
-
* @param
|
|
2375
|
-
* @param
|
|
2376
|
-
* @param
|
|
2295
|
+
* @param shapeOptions
|
|
2296
|
+
* @param shapeOptions.id - Уникальный идентификатор фигуры
|
|
2297
|
+
* @param shapeOptions.left - Координата X
|
|
2298
|
+
* @param shapeOptions.top - Координата Y
|
|
2299
|
+
* @param shapeOptions.width - Ширина
|
|
2300
|
+
* @param shapeOptions.height - Высота
|
|
2301
|
+
* @param shapeOptions.originX - Ориентация по X
|
|
2302
|
+
* @param shapeOptions.originY - Ориентация по Y
|
|
2303
|
+
* @param shapeOptions.fill - Цвет заливки
|
|
2304
|
+
* @param shapeOptions.rest - Остальные параметры
|
|
2377
2305
|
*
|
|
2378
|
-
* @param
|
|
2379
|
-
* @param
|
|
2380
|
-
* @param
|
|
2306
|
+
* @param flags - Флаги для управления поведением
|
|
2307
|
+
* @param flags.withoutSelection - Не выделять объект
|
|
2308
|
+
* @param flags.withoutAdding - Не добавлять объект в canvas
|
|
2381
2309
|
*/
|
|
2382
|
-
addTriangle(l = {}, { withoutSelection:
|
|
2310
|
+
addTriangle(l = {}, { withoutSelection: d, withoutAdding: c } = {}) {
|
|
2383
2311
|
var h = l, {
|
|
2384
2312
|
id: e = `triangle-${D()}`,
|
|
2385
2313
|
left: t,
|
|
2386
|
-
top:
|
|
2387
|
-
width:
|
|
2314
|
+
top: s,
|
|
2315
|
+
width: n = 100,
|
|
2388
2316
|
height: i = 100,
|
|
2389
|
-
fill:
|
|
2317
|
+
fill: a = "yellow"
|
|
2390
2318
|
} = h, o = Y(h, [
|
|
2391
2319
|
"id",
|
|
2392
2320
|
"left",
|
|
@@ -2395,21 +2323,21 @@ class ot {
|
|
|
2395
2323
|
"height",
|
|
2396
2324
|
"fill"
|
|
2397
2325
|
]);
|
|
2398
|
-
const { canvas: g } = this.editor, u = new
|
|
2326
|
+
const { canvas: g } = this.editor, u = new Se(E({
|
|
2399
2327
|
id: e,
|
|
2400
2328
|
left: t,
|
|
2401
|
-
top:
|
|
2402
|
-
fill:
|
|
2403
|
-
width:
|
|
2329
|
+
top: s,
|
|
2330
|
+
fill: a,
|
|
2331
|
+
width: n,
|
|
2404
2332
|
height: i
|
|
2405
2333
|
}, o));
|
|
2406
|
-
return !t && !
|
|
2334
|
+
return !t && !s && g.centerObject(u), c || (g.add(u), d || g.setActiveObject(u), g.renderAll()), u;
|
|
2407
2335
|
}
|
|
2408
2336
|
}
|
|
2409
|
-
class
|
|
2337
|
+
class ct {
|
|
2410
2338
|
/**
|
|
2411
|
-
* @param
|
|
2412
|
-
* @param
|
|
2339
|
+
* @param options
|
|
2340
|
+
* @param options.editor - экземпляр редактора с доступом к canvas
|
|
2413
2341
|
*/
|
|
2414
2342
|
constructor({ editor: e }) {
|
|
2415
2343
|
this.editor = e, this.clipboard = null;
|
|
@@ -2419,8 +2347,8 @@ class rt {
|
|
|
2419
2347
|
* @fires editor:object-copied
|
|
2420
2348
|
*/
|
|
2421
2349
|
copy() {
|
|
2422
|
-
const { canvas: e, errorManager: t } = this.editor,
|
|
2423
|
-
if (!
|
|
2350
|
+
const { canvas: e, errorManager: t } = this.editor, s = e.getActiveObject();
|
|
2351
|
+
if (!s) return;
|
|
2424
2352
|
if (typeof ClipboardItem == "undefined" || !navigator.clipboard) {
|
|
2425
2353
|
t.emitWarning({
|
|
2426
2354
|
origin: "ClipboardManager",
|
|
@@ -2428,11 +2356,11 @@ class rt {
|
|
|
2428
2356
|
code: "CLIPBOARD_NOT_SUPPORTED",
|
|
2429
2357
|
// eslint-disable-next-line max-len
|
|
2430
2358
|
message: "ClipboardManager. navigator.clipboard не поддерживается в этом браузере или отсутствует соединение по HTTPS-протоколу."
|
|
2431
|
-
}), this._cloneAndFire(e,
|
|
2359
|
+
}), this._cloneAndFire(e, s);
|
|
2432
2360
|
return;
|
|
2433
2361
|
}
|
|
2434
|
-
if (
|
|
2435
|
-
const g = `application/image-editor:${JSON.stringify(
|
|
2362
|
+
if (s.type !== "image") {
|
|
2363
|
+
const g = `application/image-editor:${JSON.stringify(s.toObject(["format"]))}`;
|
|
2436
2364
|
navigator.clipboard.writeText(g).catch((u) => {
|
|
2437
2365
|
t.emitWarning({
|
|
2438
2366
|
origin: "ClipboardManager",
|
|
@@ -2441,13 +2369,13 @@ class rt {
|
|
|
2441
2369
|
message: `Ошибка записи текстового объекта в буфер обмена: ${u.message}`,
|
|
2442
2370
|
data: u
|
|
2443
2371
|
});
|
|
2444
|
-
}), this._cloneAndFire(e,
|
|
2372
|
+
}), this._cloneAndFire(e, s);
|
|
2445
2373
|
return;
|
|
2446
2374
|
}
|
|
2447
|
-
const i =
|
|
2448
|
-
for (let g = 0; g <
|
|
2449
|
-
|
|
2450
|
-
const l = new Blob([
|
|
2375
|
+
const i = s.toCanvasElement().toDataURL(), a = i.slice(5).split(";")[0], o = i.split(",")[1], d = atob(o), c = new Uint8Array(d.length);
|
|
2376
|
+
for (let g = 0; g < d.length; g += 1)
|
|
2377
|
+
c[g] = d.charCodeAt(g);
|
|
2378
|
+
const l = new Blob([c.buffer], { type: a }), h = new ClipboardItem({ [a]: l });
|
|
2451
2379
|
navigator.clipboard.write([h]).catch((g) => {
|
|
2452
2380
|
t.emitWarning({
|
|
2453
2381
|
origin: "ClipboardManager",
|
|
@@ -2455,7 +2383,7 @@ class rt {
|
|
|
2455
2383
|
code: "CLIPBOARD_WRITE_IMAGE_FAILED",
|
|
2456
2384
|
message: `Ошибка записи изображения в буфер обмена: ${g.message}`
|
|
2457
2385
|
});
|
|
2458
|
-
}), this._cloneAndFire(e,
|
|
2386
|
+
}), this._cloneAndFire(e, s);
|
|
2459
2387
|
}
|
|
2460
2388
|
/**
|
|
2461
2389
|
* Клонирует объект и вызывает событие 'editor:object-copied'.
|
|
@@ -2463,42 +2391,42 @@ class rt {
|
|
|
2463
2391
|
* @param object - активный объект
|
|
2464
2392
|
*/
|
|
2465
2393
|
_cloneAndFire(e, t) {
|
|
2466
|
-
t.clone(["format"]).then((
|
|
2467
|
-
this.clipboard =
|
|
2468
|
-
}).catch((
|
|
2394
|
+
t.clone(["format"]).then((s) => {
|
|
2395
|
+
this.clipboard = s, e.fire("editor:object-copied", { object: s });
|
|
2396
|
+
}).catch((s) => {
|
|
2469
2397
|
this.editor.errorManager.emitError({
|
|
2470
2398
|
origin: "ClipboardManager",
|
|
2471
2399
|
method: "_cloneAndFire",
|
|
2472
2400
|
code: "CLONE_FAILED",
|
|
2473
2401
|
message: "Ошибка клонирования объекта",
|
|
2474
|
-
data:
|
|
2402
|
+
data: s
|
|
2475
2403
|
});
|
|
2476
2404
|
});
|
|
2477
2405
|
}
|
|
2478
2406
|
/**
|
|
2479
2407
|
* Обработчик вставки объекта или изображения из буфера обмена.
|
|
2480
|
-
* @param
|
|
2481
|
-
* @param
|
|
2482
|
-
* @param
|
|
2408
|
+
* @param event — объект события
|
|
2409
|
+
* @param event.clipboardData — данные из буфера обмена
|
|
2410
|
+
* @param event.clipboardData.items — элементы буфера обмена
|
|
2483
2411
|
*/
|
|
2484
2412
|
handlePasteEvent({ clipboardData: e }) {
|
|
2485
|
-
var
|
|
2486
|
-
if (!((
|
|
2487
|
-
const { imageManager: t } = this.editor, { items:
|
|
2488
|
-
if (
|
|
2489
|
-
const o =
|
|
2413
|
+
var a;
|
|
2414
|
+
if (!((a = e == null ? void 0 : e.items) != null && a.length)) return;
|
|
2415
|
+
const { imageManager: t } = this.editor, { items: s } = e, n = s[s.length - 1];
|
|
2416
|
+
if (n.type !== "text/html") {
|
|
2417
|
+
const o = n.getAsFile();
|
|
2490
2418
|
if (!o) return;
|
|
2491
|
-
const
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
},
|
|
2419
|
+
const d = new FileReader();
|
|
2420
|
+
d.onload = (c) => {
|
|
2421
|
+
c.target && this.editor.imageManager.importImage({ source: c.target.result });
|
|
2422
|
+
}, d.readAsDataURL(o);
|
|
2495
2423
|
return;
|
|
2496
2424
|
}
|
|
2497
2425
|
const i = e.getData("text/html");
|
|
2498
2426
|
if (i) {
|
|
2499
|
-
const
|
|
2500
|
-
if (
|
|
2501
|
-
t.importImage({ source:
|
|
2427
|
+
const c = new DOMParser().parseFromString(i, "text/html").querySelector("img");
|
|
2428
|
+
if (c != null && c.src) {
|
|
2429
|
+
t.importImage({ source: c.src });
|
|
2502
2430
|
return;
|
|
2503
2431
|
}
|
|
2504
2432
|
}
|
|
@@ -2509,7 +2437,7 @@ class rt {
|
|
|
2509
2437
|
* @fires editor:object-pasted
|
|
2510
2438
|
*/
|
|
2511
2439
|
paste() {
|
|
2512
|
-
return
|
|
2440
|
+
return y(this, null, function* () {
|
|
2513
2441
|
const { canvas: e } = this.editor;
|
|
2514
2442
|
if (!this.clipboard) return;
|
|
2515
2443
|
const t = yield this.clipboard.clone(["format"]);
|
|
@@ -2518,96 +2446,74 @@ class rt {
|
|
|
2518
2446
|
left: t.left + 10,
|
|
2519
2447
|
top: t.top + 10,
|
|
2520
2448
|
evented: !0
|
|
2521
|
-
}), t instanceof
|
|
2522
|
-
e.add(
|
|
2449
|
+
}), t instanceof I ? (t.canvas = e, t.forEachObject((s) => {
|
|
2450
|
+
e.add(s);
|
|
2523
2451
|
})) : e.add(t), e.setActiveObject(t), e.requestRenderAll(), e.fire("editor:object-pasted", { object: t });
|
|
2524
2452
|
});
|
|
2525
2453
|
}
|
|
2526
2454
|
}
|
|
2527
|
-
class
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
* @param {ImageEditor} options.editor - экземпляр редактора с доступом к canvas
|
|
2531
|
-
*/
|
|
2532
|
-
constructor(e) {
|
|
2533
|
-
var {
|
|
2534
|
-
editor: t
|
|
2535
|
-
} = e;
|
|
2536
|
-
this.editor = t;
|
|
2455
|
+
class V {
|
|
2456
|
+
constructor({ editor: e }) {
|
|
2457
|
+
this.editor = e;
|
|
2537
2458
|
}
|
|
2538
2459
|
/**
|
|
2539
2460
|
* Блокирует объект (или группу объектов) на канвасе
|
|
2540
|
-
* @param
|
|
2541
|
-
* @param
|
|
2542
|
-
* @param
|
|
2543
|
-
* @
|
|
2461
|
+
* @param options
|
|
2462
|
+
* @param options.object - объект, который нужно заблокировать
|
|
2463
|
+
* @param options.skipInnerObjects - не блокировать внутренние объекты
|
|
2464
|
+
* @param options.withoutSave - не сохранять состояние
|
|
2544
2465
|
* @fires editor:object-locked
|
|
2545
2466
|
*/
|
|
2546
|
-
lockObject() {
|
|
2547
|
-
|
|
2548
|
-
|
|
2467
|
+
lockObject({ object: e, skipInnerObjects: t, withoutSave: s } = {}) {
|
|
2468
|
+
const { canvas: n, historyManager: i } = this.editor, a = e || n.getActiveObject();
|
|
2469
|
+
if (!a || a.locked) return;
|
|
2470
|
+
const o = {
|
|
2471
|
+
lockMovementX: !0,
|
|
2472
|
+
lockMovementY: !0,
|
|
2473
|
+
lockRotation: !0,
|
|
2474
|
+
lockScalingX: !0,
|
|
2475
|
+
lockScalingY: !0,
|
|
2476
|
+
lockSkewingX: !0,
|
|
2477
|
+
lockSkewingY: !0,
|
|
2478
|
+
locked: !0
|
|
2479
|
+
};
|
|
2480
|
+
a.set(o), !t && V._isGroupOrSelection(a) && a.getObjects().forEach((c) => {
|
|
2481
|
+
c.set(o);
|
|
2482
|
+
}), n.renderAll(), s || i.saveState(), n.fire("editor:object-locked", {
|
|
2483
|
+
object: a,
|
|
2549
2484
|
skipInnerObjects: t,
|
|
2550
|
-
withoutSave:
|
|
2551
|
-
}
|
|
2552
|
-
canvas: s,
|
|
2553
|
-
historyManager: i
|
|
2554
|
-
} = this.editor, n = e || s.getActiveObject();
|
|
2555
|
-
if (!(!n || n.locked)) {
|
|
2556
|
-
var o = {
|
|
2557
|
-
lockMovementX: !0,
|
|
2558
|
-
lockMovementY: !0,
|
|
2559
|
-
lockRotation: !0,
|
|
2560
|
-
lockScalingX: !0,
|
|
2561
|
-
lockScalingY: !0,
|
|
2562
|
-
lockSkewingX: !0,
|
|
2563
|
-
lockSkewingY: !0,
|
|
2564
|
-
locked: !0
|
|
2565
|
-
};
|
|
2566
|
-
n.set(o);
|
|
2567
|
-
var c = !t && ["activeselection", "group"].includes(n.type);
|
|
2568
|
-
c && n.getObjects().forEach((d) => {
|
|
2569
|
-
d.set(o);
|
|
2570
|
-
}), s.renderAll(), a || i.saveState(), s.fire("editor:object-locked", {
|
|
2571
|
-
object: n,
|
|
2572
|
-
skipInnerObjects: t,
|
|
2573
|
-
withoutSave: a
|
|
2574
|
-
});
|
|
2575
|
-
}
|
|
2485
|
+
withoutSave: s
|
|
2486
|
+
});
|
|
2576
2487
|
}
|
|
2577
2488
|
/**
|
|
2578
2489
|
* Разблокирует объект (или группу объектов) на канвасе
|
|
2579
|
-
* @param
|
|
2580
|
-
* @param
|
|
2581
|
-
* @param
|
|
2582
|
-
* @returns
|
|
2490
|
+
* @param options
|
|
2491
|
+
* @param options.object - объект, который нужно разблокировать
|
|
2492
|
+
* @param options.withoutSave - не сохранять состояние в истории изменений
|
|
2583
2493
|
* @fires editor:object-unlocked
|
|
2584
2494
|
*/
|
|
2585
|
-
unlockObject() {
|
|
2586
|
-
|
|
2587
|
-
|
|
2495
|
+
unlockObject({ object: e, withoutSave: t } = {}) {
|
|
2496
|
+
const { canvas: s, historyManager: n } = this.editor, i = e || s.getActiveObject();
|
|
2497
|
+
if (!i) return;
|
|
2498
|
+
const a = {
|
|
2499
|
+
lockMovementX: !1,
|
|
2500
|
+
lockMovementY: !1,
|
|
2501
|
+
lockRotation: !1,
|
|
2502
|
+
lockScalingX: !1,
|
|
2503
|
+
lockScalingY: !1,
|
|
2504
|
+
lockSkewingX: !1,
|
|
2505
|
+
lockSkewingY: !1,
|
|
2506
|
+
locked: !1
|
|
2507
|
+
};
|
|
2508
|
+
i.set(a), V._isGroupOrSelection(i) && i.getObjects().forEach((o) => {
|
|
2509
|
+
o.set(a);
|
|
2510
|
+
}), s.renderAll(), t || n.saveState(), s.fire("editor:object-unlocked", {
|
|
2511
|
+
object: i,
|
|
2588
2512
|
withoutSave: t
|
|
2589
|
-
}
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
if (i) {
|
|
2594
|
-
var n = {
|
|
2595
|
-
lockMovementX: !1,
|
|
2596
|
-
lockMovementY: !1,
|
|
2597
|
-
lockRotation: !1,
|
|
2598
|
-
lockScalingX: !1,
|
|
2599
|
-
lockScalingY: !1,
|
|
2600
|
-
lockSkewingX: !1,
|
|
2601
|
-
lockSkewingY: !1,
|
|
2602
|
-
locked: !1
|
|
2603
|
-
};
|
|
2604
|
-
i.set(n), ["activeselection", "group"].includes(i.type) && i.getObjects().forEach((o) => {
|
|
2605
|
-
o.set(n);
|
|
2606
|
-
}), a.renderAll(), t || s.saveState(), a.fire("editor:object-unlocked", {
|
|
2607
|
-
object: i,
|
|
2608
|
-
withoutSave: t
|
|
2609
|
-
});
|
|
2610
|
-
}
|
|
2513
|
+
});
|
|
2514
|
+
}
|
|
2515
|
+
static _isGroupOrSelection(e) {
|
|
2516
|
+
return e instanceof I || e instanceof Q;
|
|
2611
2517
|
}
|
|
2612
2518
|
}
|
|
2613
2519
|
class dt {
|
|
@@ -2616,21 +2522,21 @@ class dt {
|
|
|
2616
2522
|
}
|
|
2617
2523
|
/**
|
|
2618
2524
|
* Группировка объектов
|
|
2619
|
-
* @param
|
|
2620
|
-
* @param
|
|
2621
|
-
* @param
|
|
2525
|
+
* @param options
|
|
2526
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
2527
|
+
* @param options.object - массив объектов для группировки
|
|
2622
2528
|
* @fires editor:objects-grouped
|
|
2623
2529
|
*/
|
|
2624
2530
|
group({
|
|
2625
2531
|
object: e,
|
|
2626
2532
|
withoutSave: t
|
|
2627
2533
|
} = {}) {
|
|
2628
|
-
const { canvas:
|
|
2629
|
-
|
|
2630
|
-
const i = e ||
|
|
2631
|
-
if (!i || !(i instanceof
|
|
2632
|
-
const
|
|
2633
|
-
|
|
2534
|
+
const { canvas: s, historyManager: n } = this.editor;
|
|
2535
|
+
n.suspendHistory();
|
|
2536
|
+
const i = e || s.getActiveObject();
|
|
2537
|
+
if (!i || !(i instanceof I)) return;
|
|
2538
|
+
const a = i.getObjects(), o = new Q(a);
|
|
2539
|
+
a.forEach((d) => s.remove(d)), o.set("id", `${o.type}-${D()}`), s.add(o), s.setActiveObject(o), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:objects-grouped", {
|
|
2634
2540
|
object: i,
|
|
2635
2541
|
group: o,
|
|
2636
2542
|
withoutSave: t
|
|
@@ -2638,25 +2544,25 @@ class dt {
|
|
|
2638
2544
|
}
|
|
2639
2545
|
/**
|
|
2640
2546
|
* Разгруппировка объектов
|
|
2641
|
-
* @param
|
|
2642
|
-
* @param
|
|
2643
|
-
* @param
|
|
2547
|
+
* @param options
|
|
2548
|
+
* @param options.object - объект для разгруппировки
|
|
2549
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
2644
2550
|
* @fires editor:objects-ungrouped
|
|
2645
2551
|
*/
|
|
2646
2552
|
ungroup({
|
|
2647
2553
|
object: e,
|
|
2648
2554
|
withoutSave: t
|
|
2649
2555
|
} = {}) {
|
|
2650
|
-
const { canvas:
|
|
2651
|
-
|
|
2652
|
-
const i = e ||
|
|
2653
|
-
if (!(i instanceof
|
|
2654
|
-
const
|
|
2655
|
-
|
|
2656
|
-
const o = new
|
|
2657
|
-
canvas:
|
|
2556
|
+
const { canvas: s, historyManager: n } = this.editor;
|
|
2557
|
+
n.suspendHistory();
|
|
2558
|
+
const i = e || s.getActiveObject();
|
|
2559
|
+
if (!(i instanceof Q)) return;
|
|
2560
|
+
const a = i.removeAll();
|
|
2561
|
+
s.remove(i), a.forEach((d) => s.add(d));
|
|
2562
|
+
const o = new I(a, {
|
|
2563
|
+
canvas: s
|
|
2658
2564
|
});
|
|
2659
|
-
|
|
2565
|
+
s.setActiveObject(o), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:objects-ungrouped", {
|
|
2660
2566
|
object: i,
|
|
2661
2567
|
selection: o,
|
|
2662
2568
|
withoutSave: t
|
|
@@ -2664,37 +2570,18 @@ class dt {
|
|
|
2664
2570
|
}
|
|
2665
2571
|
}
|
|
2666
2572
|
class lt {
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
* @param {ImageEditor} options.editor - экземпляр редактора с доступом к canvas
|
|
2670
|
-
*/
|
|
2671
|
-
constructor(e) {
|
|
2672
|
-
var {
|
|
2673
|
-
editor: t
|
|
2674
|
-
} = e;
|
|
2675
|
-
this.editor = t;
|
|
2573
|
+
constructor({ editor: e }) {
|
|
2574
|
+
this.editor = e;
|
|
2676
2575
|
}
|
|
2677
2576
|
/**
|
|
2678
2577
|
* Выделить все объекты
|
|
2679
2578
|
* @fires editor:all-objects-selected
|
|
2680
2579
|
*/
|
|
2681
2580
|
selectAll() {
|
|
2682
|
-
|
|
2683
|
-
canvas: e,
|
|
2684
|
-
canvasManager: t,
|
|
2685
|
-
objectLockManager: a
|
|
2686
|
-
} = this.editor;
|
|
2581
|
+
const { canvas: e, canvasManager: t, objectLockManager: s } = this.editor;
|
|
2687
2582
|
e.discardActiveObject();
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
}) : s[0];
|
|
2691
|
-
i && a.lockObject({
|
|
2692
|
-
object: n,
|
|
2693
|
-
skipInnerObjects: !0,
|
|
2694
|
-
withoutSave: !0
|
|
2695
|
-
}), e.setActiveObject(n), e.requestRenderAll(), e.fire("editor:all-objects-selected", {
|
|
2696
|
-
selected: n
|
|
2697
|
-
});
|
|
2583
|
+
const n = t.getObjects(), i = n.some((o) => o.locked), a = n.length > 1 ? new I(t.getObjects(), { canvas: e }) : n[0];
|
|
2584
|
+
i && s.lockObject({ object: a, skipInnerObjects: !0, withoutSave: !0 }), e.setActiveObject(a), e.requestRenderAll(), e.fire("editor:all-objects-selected", { selected: a });
|
|
2698
2585
|
}
|
|
2699
2586
|
}
|
|
2700
2587
|
class ht {
|
|
@@ -2703,24 +2590,24 @@ class ht {
|
|
|
2703
2590
|
}
|
|
2704
2591
|
/**
|
|
2705
2592
|
* Удалить выбранные объекты
|
|
2706
|
-
* @param
|
|
2707
|
-
* @param
|
|
2708
|
-
* @param
|
|
2593
|
+
* @param options
|
|
2594
|
+
* @param options.objects - массив объектов для удаления
|
|
2595
|
+
* @param options.withoutSave - Не сохранять состояние
|
|
2709
2596
|
* @fires editor:objects-deleted
|
|
2710
2597
|
*/
|
|
2711
2598
|
deleteSelectedObjects({
|
|
2712
2599
|
objects: e,
|
|
2713
2600
|
withoutSave: t
|
|
2714
2601
|
} = {}) {
|
|
2715
|
-
const { canvas:
|
|
2716
|
-
|
|
2602
|
+
const { canvas: s, historyManager: n, groupingManager: i } = this.editor, a = (e || s.getActiveObjects()).filter((o) => !o.locked);
|
|
2603
|
+
a != null && a.length && (n.suspendHistory(), a.forEach((o) => {
|
|
2717
2604
|
if (o.type === "group" && o.format !== "svg") {
|
|
2718
2605
|
i.ungroup({ object: o, withoutSave: t }), this.deleteSelectedObjects();
|
|
2719
2606
|
return;
|
|
2720
2607
|
}
|
|
2721
|
-
|
|
2722
|
-
}),
|
|
2723
|
-
objects:
|
|
2608
|
+
s.remove(o);
|
|
2609
|
+
}), s.discardActiveObject(), s.renderAll(), n.resumeHistory(), t || n.saveState(), s.fire("editor:objects-deleted", {
|
|
2610
|
+
objects: a,
|
|
2724
2611
|
withoutSave: t
|
|
2725
2612
|
}));
|
|
2726
2613
|
}
|
|
@@ -2787,112 +2674,131 @@ const gt = {
|
|
|
2787
2674
|
REDO_ERROR: "REDO_ERROR"
|
|
2788
2675
|
}
|
|
2789
2676
|
};
|
|
2790
|
-
class
|
|
2677
|
+
class G {
|
|
2791
2678
|
constructor({ editor: e }) {
|
|
2792
2679
|
this._buffer = [], this.editor = e;
|
|
2793
2680
|
}
|
|
2681
|
+
/**
|
|
2682
|
+
* Возвращает буфер с ошибками и предупреждениями
|
|
2683
|
+
*/
|
|
2794
2684
|
get buffer() {
|
|
2795
2685
|
return this._buffer;
|
|
2796
2686
|
}
|
|
2687
|
+
/**
|
|
2688
|
+
* Очищает буфер ошибок и предупреждений
|
|
2689
|
+
*/
|
|
2797
2690
|
cleanBuffer() {
|
|
2798
2691
|
this._buffer.length = 0;
|
|
2799
2692
|
}
|
|
2800
2693
|
/**
|
|
2801
2694
|
* Эмитит событие ошибки через fabricjs
|
|
2802
|
-
* @param
|
|
2803
|
-
* @param
|
|
2804
|
-
* @param
|
|
2805
|
-
* @param
|
|
2806
|
-
* @param
|
|
2807
|
-
* @param
|
|
2695
|
+
* @param options
|
|
2696
|
+
* @param options.origin — источник ошибки (по умолчанию 'ImageEditor')
|
|
2697
|
+
* @param options.method — метод, вызвавший ошибку (по умолчанию 'Unknown Method')
|
|
2698
|
+
* @param options.code — код ошибки (из errorCodes)
|
|
2699
|
+
* @param options.data — доп. данные (опционально)
|
|
2700
|
+
* @param options.message — текст ошибки (опционально, если не передан, то используется код ошибки)
|
|
2808
2701
|
* @fires editor:error
|
|
2809
2702
|
*/
|
|
2810
|
-
emitError({ origin: e = "ImageEditor", method: t = "Unknown Method", code:
|
|
2811
|
-
if (!
|
|
2812
|
-
console.warn("Неизвестный код ошибки: ", { code:
|
|
2703
|
+
emitError({ origin: e = "ImageEditor", method: t = "Unknown Method", code: s, data: n, message: i }) {
|
|
2704
|
+
if (!G.isValidErrorCode(s)) {
|
|
2705
|
+
console.warn("Неизвестный код ошибки: ", { code: s, origin: e, method: t });
|
|
2813
2706
|
return;
|
|
2814
2707
|
}
|
|
2815
|
-
if (!
|
|
2816
|
-
const
|
|
2817
|
-
console.error(`${e}. ${t}. ${
|
|
2708
|
+
if (!s) return;
|
|
2709
|
+
const a = i || s;
|
|
2710
|
+
console.error(`${e}. ${t}. ${s}. ${a}`, n);
|
|
2818
2711
|
const o = {
|
|
2819
|
-
code:
|
|
2712
|
+
code: s,
|
|
2820
2713
|
origin: e,
|
|
2821
2714
|
method: t,
|
|
2822
|
-
message:
|
|
2823
|
-
data:
|
|
2715
|
+
message: a,
|
|
2716
|
+
data: n
|
|
2824
2717
|
};
|
|
2825
|
-
this._buffer.push(
|
|
2718
|
+
this._buffer.push(E({
|
|
2826
2719
|
type: "editor:error"
|
|
2827
2720
|
}, o)), this.editor.canvas.fire("editor:error", o);
|
|
2828
2721
|
}
|
|
2829
2722
|
/**
|
|
2830
2723
|
* Эмитит предупреждение через fabricjs
|
|
2831
|
-
* @param
|
|
2832
|
-
* @param
|
|
2833
|
-
* @param
|
|
2834
|
-
* @param
|
|
2835
|
-
* @param
|
|
2836
|
-
* @param
|
|
2724
|
+
* @param options
|
|
2725
|
+
* @param options.origin — источник предупреждения (по умолчанию 'ImageEditor')
|
|
2726
|
+
* @param options.method — метод, вызвавший предупреждение (по умолчанию 'Unknown Method')
|
|
2727
|
+
* @param ptions.code — код предупреждения (из errorCodes)
|
|
2728
|
+
* @param options.data — доп. данные (опционально)
|
|
2729
|
+
* @param options.message — текст предупреждения (опционально, если не передан, то используется код предупреждения)
|
|
2837
2730
|
* @fires editor:warning
|
|
2838
2731
|
*/
|
|
2839
|
-
emitWarning({ origin: e = "ImageEditor", method: t = "Unknown Method", code:
|
|
2840
|
-
if (!
|
|
2841
|
-
console.warn("Неизвестный код предупреждения: ", { code:
|
|
2732
|
+
emitWarning({ origin: e = "ImageEditor", method: t = "Unknown Method", code: s, message: n, data: i }) {
|
|
2733
|
+
if (!G.isValidErrorCode(s)) {
|
|
2734
|
+
console.warn("Неизвестный код предупреждения: ", { code: s, origin: e, method: t });
|
|
2842
2735
|
return;
|
|
2843
2736
|
}
|
|
2844
|
-
const
|
|
2845
|
-
console.warn(`${e}. ${t}. ${
|
|
2737
|
+
const a = n || s;
|
|
2738
|
+
console.warn(`${e}. ${t}. ${s}. ${a}`, i);
|
|
2846
2739
|
const o = {
|
|
2847
|
-
code:
|
|
2740
|
+
code: s,
|
|
2848
2741
|
origin: e,
|
|
2849
2742
|
method: t,
|
|
2850
|
-
message:
|
|
2743
|
+
message: a,
|
|
2851
2744
|
data: i
|
|
2852
2745
|
};
|
|
2853
|
-
this._buffer.push(
|
|
2746
|
+
this._buffer.push(E({
|
|
2854
2747
|
type: "editor:warning"
|
|
2855
2748
|
}, o)), this.editor.canvas.fire("editor:warning", o);
|
|
2856
2749
|
}
|
|
2750
|
+
/**
|
|
2751
|
+
* Проверяет, является ли код ошибки или предупреждения допустимым
|
|
2752
|
+
* @param code - код ошибки или предупреждения
|
|
2753
|
+
* @returns true, если код допустим, иначе false
|
|
2754
|
+
*/
|
|
2857
2755
|
static isValidErrorCode(e) {
|
|
2858
2756
|
return e ? Object.values(gt).some((t) => Object.values(t).includes(e)) : !1;
|
|
2859
2757
|
}
|
|
2860
2758
|
}
|
|
2861
|
-
class
|
|
2759
|
+
class ie {
|
|
2862
2760
|
/**
|
|
2863
2761
|
* Конструктор класса ImageEditor.
|
|
2864
|
-
* @param
|
|
2865
|
-
* @param
|
|
2762
|
+
* @param canvasId - идентификатор канваса, в котором будет создан редактор
|
|
2763
|
+
* @param options - опции и настройки редактора
|
|
2866
2764
|
*/
|
|
2867
2765
|
constructor(e, t) {
|
|
2868
2766
|
this.options = t, this.containerId = e, this.editorId = `${e}-${D()}`, this.clipboard = null, this.init();
|
|
2869
2767
|
}
|
|
2768
|
+
/**
|
|
2769
|
+
* Инициализация редактора.
|
|
2770
|
+
* Создаёт все необходимые менеджеры и загружает начальное состояние.
|
|
2771
|
+
* @fires editor:ready
|
|
2772
|
+
*/
|
|
2870
2773
|
init() {
|
|
2871
|
-
return
|
|
2774
|
+
return y(this, null, function* () {
|
|
2872
2775
|
const {
|
|
2873
2776
|
editorContainerWidth: e,
|
|
2874
2777
|
editorContainerHeight: t,
|
|
2875
|
-
canvasWrapperWidth:
|
|
2876
|
-
canvasWrapperHeight:
|
|
2778
|
+
canvasWrapperWidth: s,
|
|
2779
|
+
canvasWrapperHeight: n,
|
|
2877
2780
|
canvasCSSWidth: i,
|
|
2878
|
-
canvasCSSHeight:
|
|
2781
|
+
canvasCSSHeight: a,
|
|
2879
2782
|
initialImage: o,
|
|
2880
|
-
initialStateJSON:
|
|
2881
|
-
scaleType:
|
|
2783
|
+
initialStateJSON: d,
|
|
2784
|
+
scaleType: c,
|
|
2882
2785
|
_onReadyCallback: l
|
|
2883
2786
|
} = this.options;
|
|
2884
|
-
if (
|
|
2787
|
+
if (Re.apply(), this.canvas = new Ce(this.containerId, this.options), this.moduleLoader = new Oe(), this.workerManager = new Ee(), this.errorManager = new G({ editor: this }), this.historyManager = new qe({ editor: this }), this.toolbar = new Ke({ editor: this }), this.transformManager = new at({ editor: this }), this.canvasManager = new it({ editor: this }), this.imageManager = new N({ editor: this }), this.layerManager = new F({ editor: this }), this.shapeManager = new rt({ editor: this }), this.interactionBlocker = new ot({ editor: this }), this.clipboardManager = new ct({ editor: this }), this.objectLockManager = new V({ editor: this }), this.groupingManager = new dt({ editor: this }), this.selectionManager = new lt({ editor: this }), this.deletionManager = new ht({ editor: this }), this._createMontageArea(), this._createClippingArea(), this.listeners = new R({ editor: this, options: this.options }), this.canvasManager.setEditorContainerWidth(e), this.canvasManager.setEditorContainerHeight(t), this.canvasManager.setCanvasWrapperWidth(s), this.canvasManager.setCanvasWrapperHeight(n), this.canvasManager.setCanvasCSSWidth(i), this.canvasManager.setCanvasCSSHeight(a), o != null && o.source) {
|
|
2885
2788
|
const {
|
|
2886
2789
|
source: h,
|
|
2887
|
-
scale: g = `image-${
|
|
2790
|
+
scale: g = `image-${c}`,
|
|
2888
2791
|
withoutSave: u = !0
|
|
2889
2792
|
} = o;
|
|
2890
2793
|
yield this.imageManager.importImage({ source: h, scale: g, withoutSave: u });
|
|
2891
2794
|
} else
|
|
2892
2795
|
this.canvasManager.setDefaultScale({ withoutSave: !0 });
|
|
2893
|
-
|
|
2796
|
+
d && this.historyManager.loadStateFromFullState(d), this.historyManager.saveState(), console.log("editor:ready"), this.canvas.fire("editor:ready", this), typeof l == "function" && l(this);
|
|
2894
2797
|
});
|
|
2895
2798
|
}
|
|
2799
|
+
/**
|
|
2800
|
+
* Создаёт монтажную область
|
|
2801
|
+
*/
|
|
2896
2802
|
_createMontageArea() {
|
|
2897
2803
|
const {
|
|
2898
2804
|
montageAreaWidth: e,
|
|
@@ -2901,7 +2807,7 @@ class ae {
|
|
|
2901
2807
|
this.montageArea = this.shapeManager.addRectangle({
|
|
2902
2808
|
width: e,
|
|
2903
2809
|
height: t,
|
|
2904
|
-
fill:
|
|
2810
|
+
fill: ie._createMosaicPattern(),
|
|
2905
2811
|
stroke: null,
|
|
2906
2812
|
strokeWidth: 0,
|
|
2907
2813
|
selectable: !1,
|
|
@@ -2915,6 +2821,9 @@ class ae {
|
|
|
2915
2821
|
noScaleCache: !0
|
|
2916
2822
|
}, { withoutSelection: !0 });
|
|
2917
2823
|
}
|
|
2824
|
+
/**
|
|
2825
|
+
* Создаёт область клиппинга
|
|
2826
|
+
*/
|
|
2918
2827
|
_createClippingArea() {
|
|
2919
2828
|
const {
|
|
2920
2829
|
montageAreaWidth: e,
|
|
@@ -2934,18 +2843,21 @@ class ae {
|
|
|
2934
2843
|
originY: "center"
|
|
2935
2844
|
}, { withoutSelection: !0, withoutAdding: !0 });
|
|
2936
2845
|
}
|
|
2846
|
+
/**
|
|
2847
|
+
* Метод для удаления редактора и всех слушателей.
|
|
2848
|
+
*/
|
|
2937
2849
|
destroy() {
|
|
2938
2850
|
this.listeners.destroy(), this.toolbar.destroy(), this.canvas.dispose(), this.workerManager.worker.terminate(), this.imageManager.revokeBlobUrls(), this.errorManager.cleanBuffer();
|
|
2939
2851
|
}
|
|
2940
2852
|
/**
|
|
2941
2853
|
* Создает паттерн мозаики.
|
|
2942
|
-
* @returns
|
|
2854
|
+
* @returns паттерн мозаики
|
|
2943
2855
|
*/
|
|
2944
2856
|
static _createMosaicPattern() {
|
|
2945
2857
|
const e = document.createElement("canvas");
|
|
2946
2858
|
e.width = 20, e.height = 20;
|
|
2947
2859
|
const t = e.getContext("2d");
|
|
2948
|
-
return t.fillStyle = "#ddd", t.fillRect(0, 0, 40, 40), t.fillStyle = "#ccc", t.fillRect(0, 0, 10, 10), t.fillRect(10, 10, 10, 10), new
|
|
2860
|
+
return t.fillStyle = "#ddd", t.fillRect(0, 0, 40, 40), t.fillStyle = "#ccc", t.fillRect(0, 0, 10, 10), t.fillRect(10, 10, 10, 10), new Ne({
|
|
2949
2861
|
source: e,
|
|
2950
2862
|
repeat: "repeat"
|
|
2951
2863
|
});
|
|
@@ -3039,18 +2951,18 @@ const ut = {
|
|
|
3039
2951
|
deleteObjectsByHotkey: !0,
|
|
3040
2952
|
resetObjectFitByDoubleClick: !0
|
|
3041
2953
|
};
|
|
3042
|
-
function
|
|
3043
|
-
const t =
|
|
3044
|
-
if (!
|
|
2954
|
+
function It(r, e = {}) {
|
|
2955
|
+
const t = E(E({}, ut), e), s = document.getElementById(r);
|
|
2956
|
+
if (!s)
|
|
3045
2957
|
return Promise.reject(new Error(`Контейнер с ID "${r}" не найден.`));
|
|
3046
|
-
const
|
|
3047
|
-
return
|
|
2958
|
+
const n = document.createElement("canvas");
|
|
2959
|
+
return n.id = `${r}-canvas`, s.appendChild(n), t.editorContainer = s, new Promise((i) => {
|
|
3048
2960
|
t._onReadyCallback = i;
|
|
3049
|
-
const
|
|
3050
|
-
window[r] =
|
|
2961
|
+
const a = new ie(n.id, t);
|
|
2962
|
+
window[r] = a;
|
|
3051
2963
|
});
|
|
3052
2964
|
}
|
|
3053
2965
|
export {
|
|
3054
|
-
|
|
2966
|
+
It as default
|
|
3055
2967
|
};
|
|
3056
2968
|
//# sourceMappingURL=main.js.map
|