mce 0.13.0 → 0.13.2
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/README.md +3 -2
- package/dist/components/Floatbar.vue.d.ts +15 -0
- package/dist/components/Selector.vue.d.ts +12 -14
- package/dist/components/shared/Dialog.vue.d.ts +9 -0
- package/dist/components/shared/Menu.vue.d.ts +9 -0
- package/dist/components/shared/Overlay.vue.d.ts +9 -0
- package/dist/components/shared/Tooltip.vue.d.ts +9 -0
- package/dist/components/shared/Transformable.vue.d.ts +4 -5
- package/dist/composables/overlay.d.ts +11 -0
- package/dist/composables/strategy.d.ts +1 -1
- package/dist/index.js +322 -247
- package/dist/locale/en.d.ts +5 -1
- package/dist/locale/zh-Hans.d.ts +5 -1
- package/dist/mixins/0.config/base.d.ts +4 -1
- package/dist/mixins/0.context.d.ts +5 -1
- package/dist/mixins/4.0.text.d.ts +1 -1
- package/dist/mixins/4.2.element.d.ts +0 -1
- package/dist/plugins/menu.d.ts +2 -1
- package/dist/plugins/panels.d.ts +12 -0
- package/dist/typed-global.d.ts +16 -0
- package/dist/typed-plugins.d.ts +1 -1
- package/package.json +2 -2
- package/dist/mixins/0.element.d.ts +0 -15
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { Node as Node$1, Element2D, Timeline, Engine, Camera2D, DrawboardEffect, IN_BROWSER, clamp, assets, TimelineNode, Transform2D, DEG_TO_RAD, render, Animation } from "modern-canvas";
|
|
1
2
|
import { ref, computed, watch, markRaw, reactive, warn, shallowRef, onBeforeUnmount, onMounted, inject, provide, defineComponent, createVNode, mergeProps, createElementVNode, toValue, getCurrentInstance, onScopeDispose, createElementBlock, openBlock, Fragment, renderList, unref, normalizeStyle, normalizeClass, readonly, toRef, useId, onDeactivated, onActivated, useAttrs, createBlock, resolveDynamicComponent, useTemplateRef, renderSlot, Teleport, createCommentVNode, mergeModels, useModel, resolveComponent, withCtx, createTextVNode, toDisplayString, createSlots, normalizeProps, guardReactiveProps, onBeforeMount, withDirectives, vShow, vModelText, nextTick, withModifiers, isRef } from "vue";
|
|
2
3
|
import { useFileDialog, useEventListener, isClient, useResizeObserver as useResizeObserver$1, useLocalStorage, onClickOutside, useMouse, useDebounceFn } from "@vueuse/core";
|
|
3
|
-
import { Node as Node$1, Element2D, Timeline, Engine, Camera2D, DrawboardEffect, IN_BROWSER, clamp, assets, TimelineNode, Transform2D, DEG_TO_RAD, render, Animation } from "modern-canvas";
|
|
4
4
|
import { getObjectValueByPath, setObjectValueByPath, Observable, Reactivable, idGenerator, property, normalizeElement, normalizeTextContent } from "modern-idoc";
|
|
5
5
|
import { saveAs } from "file-saver";
|
|
6
6
|
import { Fonts } from "modern-font";
|
|
@@ -111,23 +111,26 @@ const _0_config_base = defineMixin((editor, options) => {
|
|
|
111
111
|
} = editor;
|
|
112
112
|
registerConfig("theme", "system");
|
|
113
113
|
registerConfig("viewMode", "edgeless");
|
|
114
|
+
registerConfig("watermark", void 0);
|
|
114
115
|
registerConfig("checkerboard", false);
|
|
116
|
+
registerConfig("checkerboardStyle", "grid");
|
|
115
117
|
registerConfig("pixelGrid", false);
|
|
118
|
+
registerConfig("pixelate", true);
|
|
116
119
|
registerConfig("camera", false);
|
|
117
120
|
registerConfig("ruler", false);
|
|
118
121
|
registerConfig("scrollbar", false);
|
|
119
122
|
registerConfig("layers", false);
|
|
120
123
|
registerConfig("timeline", false);
|
|
121
124
|
registerConfig("statusbar", false);
|
|
122
|
-
registerConfig("wheelZoom", false);
|
|
123
125
|
registerConfig("frameOutline", false);
|
|
124
126
|
registerConfig("frameGap", 48);
|
|
125
127
|
registerConfig("typographyStrategy", "autoHeight");
|
|
126
128
|
registerConfig("handleShape", "rect");
|
|
127
|
-
registerConfig("localDb", false);
|
|
128
129
|
registerConfig("screenCenterOffset", { left: 0, top: 0, bottom: 0, right: 0 });
|
|
130
|
+
registerConfig("localDb", false);
|
|
129
131
|
return () => {
|
|
130
132
|
const {
|
|
133
|
+
renderEngine,
|
|
131
134
|
camera,
|
|
132
135
|
drawboardEffect
|
|
133
136
|
} = editor;
|
|
@@ -136,6 +139,11 @@ const _0_config_base = defineMixin((editor, options) => {
|
|
|
136
139
|
config.value[key] = options[key];
|
|
137
140
|
}
|
|
138
141
|
});
|
|
142
|
+
watch(
|
|
143
|
+
() => config.value.pixelate,
|
|
144
|
+
(value) => renderEngine.value.pixelate = value,
|
|
145
|
+
{ immediate: true }
|
|
146
|
+
);
|
|
139
147
|
watch(
|
|
140
148
|
() => config.value.camera,
|
|
141
149
|
(enable) => {
|
|
@@ -143,14 +151,24 @@ const _0_config_base = defineMixin((editor, options) => {
|
|
|
143
151
|
},
|
|
144
152
|
{ immediate: true }
|
|
145
153
|
);
|
|
154
|
+
watch(
|
|
155
|
+
() => config.value.watermark,
|
|
156
|
+
(value) => drawboardEffect.value.watermark = value,
|
|
157
|
+
{ immediate: true }
|
|
158
|
+
);
|
|
146
159
|
watch(
|
|
147
160
|
() => config.value.checkerboard,
|
|
148
|
-
(
|
|
161
|
+
(value) => drawboardEffect.value.checkerboard = value,
|
|
162
|
+
{ immediate: true }
|
|
163
|
+
);
|
|
164
|
+
watch(
|
|
165
|
+
() => config.value.checkerboardStyle,
|
|
166
|
+
(value) => drawboardEffect.value.checkerboardStyle = value,
|
|
149
167
|
{ immediate: true }
|
|
150
168
|
);
|
|
151
169
|
watch(
|
|
152
170
|
() => config.value.pixelGrid,
|
|
153
|
-
(
|
|
171
|
+
(value) => drawboardEffect.value.pixelGrid = value,
|
|
154
172
|
{ immediate: true }
|
|
155
173
|
);
|
|
156
174
|
};
|
|
@@ -882,6 +900,13 @@ const _0_context = defineMixin((editor) => {
|
|
|
882
900
|
const root = computed(() => doc.value.root);
|
|
883
901
|
const nodes = ref([]);
|
|
884
902
|
const nodeIndexMap = reactive(/* @__PURE__ */ new Map());
|
|
903
|
+
const selection = ref([]);
|
|
904
|
+
const elementSelection = computed({
|
|
905
|
+
get: () => selection.value.filter((v) => v instanceof Element2D),
|
|
906
|
+
set: (val) => selection.value = val
|
|
907
|
+
});
|
|
908
|
+
const textSelection = ref();
|
|
909
|
+
const hoverElement = ref();
|
|
885
910
|
const drawboardPointer = ref();
|
|
886
911
|
const state = ref();
|
|
887
912
|
const stateContext = ref();
|
|
@@ -915,6 +940,10 @@ const _0_context = defineMixin((editor) => {
|
|
|
915
940
|
root,
|
|
916
941
|
nodes,
|
|
917
942
|
nodeIndexMap,
|
|
943
|
+
selection,
|
|
944
|
+
elementSelection,
|
|
945
|
+
textSelection,
|
|
946
|
+
hoverElement,
|
|
918
947
|
drawboardDom,
|
|
919
948
|
drawboardAabb,
|
|
920
949
|
state,
|
|
@@ -927,7 +956,8 @@ const _0_context = defineMixin((editor) => {
|
|
|
927
956
|
return () => {
|
|
928
957
|
const {
|
|
929
958
|
on,
|
|
930
|
-
root: root2
|
|
959
|
+
root: root2,
|
|
960
|
+
state: state2
|
|
931
961
|
} = editor;
|
|
932
962
|
function updateNodes(value) {
|
|
933
963
|
let node;
|
|
@@ -945,30 +975,10 @@ const _0_context = defineMixin((editor) => {
|
|
|
945
975
|
nodeIndexMap.set(node.id, nodes.value.length - 1);
|
|
946
976
|
}
|
|
947
977
|
on("setDoc", () => updateNodes());
|
|
948
|
-
};
|
|
949
|
-
});
|
|
950
|
-
const _0_element = defineMixin((editor) => {
|
|
951
|
-
const selection = ref([]);
|
|
952
|
-
const elementSelection = computed({
|
|
953
|
-
get: () => selection.value.filter((v) => v instanceof Element2D),
|
|
954
|
-
set: (val) => selection.value = val
|
|
955
|
-
});
|
|
956
|
-
const hoverElement = ref();
|
|
957
|
-
const textSelection = ref();
|
|
958
|
-
Object.assign(editor, {
|
|
959
|
-
selection,
|
|
960
|
-
elementSelection,
|
|
961
|
-
textSelection,
|
|
962
|
-
hoverElement
|
|
963
|
-
});
|
|
964
|
-
return () => {
|
|
965
|
-
const {
|
|
966
|
-
state
|
|
967
|
-
} = editor;
|
|
968
978
|
watch(selection, (value) => {
|
|
969
979
|
window.$$0 = value[0];
|
|
970
980
|
});
|
|
971
|
-
watch(
|
|
981
|
+
watch(state2, () => {
|
|
972
982
|
textSelection.value = void 0;
|
|
973
983
|
hoverElement.value = void 0;
|
|
974
984
|
});
|
|
@@ -1118,10 +1128,14 @@ const en = {
|
|
|
1118
1128
|
"view:pixelGrid": "Pixel grid",
|
|
1119
1129
|
"view:ruler": "Ruler",
|
|
1120
1130
|
"view:scrollbar": "Scrollbar",
|
|
1121
|
-
"view:layers": "Layers",
|
|
1122
1131
|
"view:timeline": "Timeline",
|
|
1123
1132
|
"view:statusbar": "Statusbar",
|
|
1124
1133
|
"view:frameOutline": "Frame outlines",
|
|
1134
|
+
"checkerboardStyle:grid": "Grid checkerboard",
|
|
1135
|
+
"checkerboardStyle:dot": "Dot checkerboard",
|
|
1136
|
+
"panels": "Panels",
|
|
1137
|
+
"panels:layers": "Open layers panel",
|
|
1138
|
+
"pixelate": "Pixelate",
|
|
1125
1139
|
"layers": "Layers",
|
|
1126
1140
|
"zoomIn": "Zoom in",
|
|
1127
1141
|
"zoomOut": "Zoom out",
|
|
@@ -1198,10 +1212,14 @@ const zhHans = {
|
|
|
1198
1212
|
"view:pixelGrid": "像素网格",
|
|
1199
1213
|
"view:ruler": "标尺",
|
|
1200
1214
|
"view:scrollbar": "滚动条",
|
|
1201
|
-
"view:layers": "图层",
|
|
1202
1215
|
"view:timeline": "时间线",
|
|
1203
1216
|
"view:statusbar": "状态栏",
|
|
1204
1217
|
"view:frameOutline": "框架轮廓",
|
|
1218
|
+
"checkerboardStyle:grid": "网格棋盘",
|
|
1219
|
+
"checkerboardStyle:dot": "点状棋盘",
|
|
1220
|
+
"panels": "面板",
|
|
1221
|
+
"panels:layers": "打开图层面板",
|
|
1222
|
+
"pixelate": "像素化",
|
|
1205
1223
|
"layers": "图层",
|
|
1206
1224
|
"zoomIn": "放大",
|
|
1207
1225
|
"zoomOut": "缩小",
|
|
@@ -1455,7 +1473,9 @@ function createTextElement(content, style) {
|
|
|
1455
1473
|
height: box.height
|
|
1456
1474
|
},
|
|
1457
1475
|
text: { content: normalizeTextContent(content) },
|
|
1458
|
-
meta: {
|
|
1476
|
+
meta: {
|
|
1477
|
+
inPptIs: "Shape"
|
|
1478
|
+
}
|
|
1459
1479
|
};
|
|
1460
1480
|
}
|
|
1461
1481
|
async function createImageElement(image) {
|
|
@@ -1465,7 +1485,10 @@ async function createImageElement(image) {
|
|
|
1465
1485
|
...await getImageSizeFromUrl(image)
|
|
1466
1486
|
},
|
|
1467
1487
|
foreground: { image },
|
|
1468
|
-
meta: {
|
|
1488
|
+
meta: {
|
|
1489
|
+
inPptIs: "Picture",
|
|
1490
|
+
lockAspectRatio: true
|
|
1491
|
+
}
|
|
1469
1492
|
};
|
|
1470
1493
|
}
|
|
1471
1494
|
function isClickInsideElement(event, targetDiv) {
|
|
@@ -2235,64 +2258,41 @@ const _3_view = defineMixin((editor) => {
|
|
|
2235
2258
|
});
|
|
2236
2259
|
const _4_0_text = defineMixin((editor) => {
|
|
2237
2260
|
const {
|
|
2238
|
-
config
|
|
2261
|
+
config,
|
|
2262
|
+
isElement
|
|
2239
2263
|
} = editor;
|
|
2240
2264
|
function textFontSizeToFit(element) {
|
|
2241
2265
|
function _handle(element2) {
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
chars.forEach((_char) => {
|
|
2246
|
-
const _pos = _char.lineBox.left + _char.lineBox.width;
|
|
2247
|
-
if (_pos > pos) {
|
|
2248
|
-
char = _char;
|
|
2249
|
-
pos = _pos;
|
|
2250
|
-
}
|
|
2251
|
-
});
|
|
2252
|
-
const style = {};
|
|
2253
|
-
const content = chars.filter((_char) => _char.lineBox.top === char?.lineBox.top).map((char2) => {
|
|
2254
|
-
Object.assign(
|
|
2255
|
-
style,
|
|
2256
|
-
{ ...char2.parent.style },
|
|
2257
|
-
{ ...char2.parent.parent.style }
|
|
2258
|
-
);
|
|
2259
|
-
return char2.content;
|
|
2260
|
-
}).join("");
|
|
2266
|
+
if (!element2.text.isValid()) {
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
2261
2269
|
const { boundingBox } = measureText({
|
|
2262
2270
|
style: {
|
|
2263
2271
|
...element2.style.toJSON(),
|
|
2264
2272
|
width: "auto"
|
|
2265
2273
|
},
|
|
2266
|
-
content:
|
|
2267
|
-
{
|
|
2268
|
-
fragments: [
|
|
2269
|
-
{ ...style, content }
|
|
2270
|
-
]
|
|
2271
|
-
}
|
|
2272
|
-
]
|
|
2274
|
+
content: element2.text.content
|
|
2273
2275
|
});
|
|
2274
2276
|
const fontSize = (element2.style.fontSize || 12) / 2;
|
|
2275
2277
|
const scale = (element2.style.width ?? 0) / (boundingBox.width + fontSize);
|
|
2276
|
-
function _scaleStyle(
|
|
2277
|
-
if (
|
|
2278
|
-
|
|
2279
|
-
if (
|
|
2280
|
-
|
|
2278
|
+
function _scaleStyle(style) {
|
|
2279
|
+
if (style.fontSize)
|
|
2280
|
+
style.fontSize = style.fontSize * scale;
|
|
2281
|
+
if (style.letterSpacing)
|
|
2282
|
+
style.letterSpacing = style.letterSpacing * scale;
|
|
2281
2283
|
}
|
|
2282
2284
|
_scaleStyle(element2.style);
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
_scaleStyle(f);
|
|
2288
|
-
});
|
|
2285
|
+
element2.text.content.forEach((p) => {
|
|
2286
|
+
_scaleStyle(p);
|
|
2287
|
+
p.fragments.forEach((f) => {
|
|
2288
|
+
_scaleStyle(f);
|
|
2289
2289
|
});
|
|
2290
|
-
}
|
|
2290
|
+
});
|
|
2291
2291
|
element2.requestRedraw();
|
|
2292
2292
|
}
|
|
2293
2293
|
_handle(element);
|
|
2294
2294
|
element.findOne((descendant) => {
|
|
2295
|
-
if (descendant
|
|
2295
|
+
if (isElement(descendant)) {
|
|
2296
2296
|
_handle(descendant);
|
|
2297
2297
|
}
|
|
2298
2298
|
return false;
|
|
@@ -2307,7 +2307,7 @@ const _4_0_text = defineMixin((editor) => {
|
|
|
2307
2307
|
return;
|
|
2308
2308
|
}
|
|
2309
2309
|
function _handle(element2) {
|
|
2310
|
-
if (!element2.text
|
|
2310
|
+
if (!element2.text.isValid()) {
|
|
2311
2311
|
return;
|
|
2312
2312
|
}
|
|
2313
2313
|
const style = element2.style.toJSON();
|
|
@@ -2331,7 +2331,7 @@ const _4_0_text = defineMixin((editor) => {
|
|
|
2331
2331
|
}
|
|
2332
2332
|
_handle(element);
|
|
2333
2333
|
element.findOne((descendant) => {
|
|
2334
|
-
if (descendant
|
|
2334
|
+
if (isElement(descendant)) {
|
|
2335
2335
|
_handle(descendant);
|
|
2336
2336
|
}
|
|
2337
2337
|
return false;
|
|
@@ -2571,23 +2571,6 @@ const _4_2_element = defineMixin((editor) => {
|
|
|
2571
2571
|
options.textToFit && textToFit(element);
|
|
2572
2572
|
options.textFontSizeToFit && textFontSizeToFit(element);
|
|
2573
2573
|
}
|
|
2574
|
-
function pointerActivateElement(element, event) {
|
|
2575
|
-
if (element && (event?.ctrlKey || event?.shiftKey || event?.metaKey)) {
|
|
2576
|
-
let elements;
|
|
2577
|
-
if (selection.value.length === 1) {
|
|
2578
|
-
elements = [selection.value[0], element];
|
|
2579
|
-
} else {
|
|
2580
|
-
if (selection.value.findIndex((v) => v.equal(element)) > -1) {
|
|
2581
|
-
elements = selection.value.filter((v) => v.equal(element));
|
|
2582
|
-
} else {
|
|
2583
|
-
elements = [...selection.value, element];
|
|
2584
|
-
}
|
|
2585
|
-
}
|
|
2586
|
-
selection.value = elements;
|
|
2587
|
-
} else {
|
|
2588
|
-
selection.value = element ? [element] : [];
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
2574
|
function selectArea(areaInDrawboard) {
|
|
2592
2575
|
const selected = root.value?.children.flatMap((node) => {
|
|
2593
2576
|
if (isFrame(node)) {
|
|
@@ -2606,7 +2589,6 @@ const _4_2_element = defineMixin((editor) => {
|
|
|
2606
2589
|
updateElement,
|
|
2607
2590
|
getElement,
|
|
2608
2591
|
resizeElement,
|
|
2609
|
-
pointerActivateElement,
|
|
2610
2592
|
selectArea
|
|
2611
2593
|
});
|
|
2612
2594
|
});
|
|
@@ -3093,7 +3075,6 @@ const mixins = [
|
|
|
3093
3075
|
_0_config,
|
|
3094
3076
|
_0_config_base,
|
|
3095
3077
|
_0_context,
|
|
3096
|
-
_0_element,
|
|
3097
3078
|
_0_font,
|
|
3098
3079
|
_0_helper,
|
|
3099
3080
|
_0_locale,
|
|
@@ -4865,7 +4846,8 @@ const _image = definePlugin((editor) => {
|
|
|
4865
4846
|
addElement,
|
|
4866
4847
|
to,
|
|
4867
4848
|
fonts,
|
|
4868
|
-
upload
|
|
4849
|
+
upload,
|
|
4850
|
+
drawboardEffect
|
|
4869
4851
|
} = editor;
|
|
4870
4852
|
const insertImage = async (url, options) => {
|
|
4871
4853
|
return addElement(await createImageElement(url), {
|
|
@@ -4892,7 +4874,17 @@ const _image = definePlugin((editor) => {
|
|
|
4892
4874
|
data: doc,
|
|
4893
4875
|
fonts,
|
|
4894
4876
|
width: doc.style.width,
|
|
4895
|
-
height: doc.style.height
|
|
4877
|
+
height: doc.style.height,
|
|
4878
|
+
onBefore: (engine) => {
|
|
4879
|
+
engine.root.append(
|
|
4880
|
+
new DrawboardEffect({
|
|
4881
|
+
internalMode: "back",
|
|
4882
|
+
effectMode: "before",
|
|
4883
|
+
...drawboardEffect.value.getProperties()
|
|
4884
|
+
})
|
|
4885
|
+
);
|
|
4886
|
+
console.log(drawboardEffect.value.getProperties());
|
|
4887
|
+
}
|
|
4896
4888
|
});
|
|
4897
4889
|
return await new Promise((resolve) => {
|
|
4898
4890
|
canvas.toBlob(
|
|
@@ -5140,32 +5132,56 @@ const _layerOrder = definePlugin((editor) => {
|
|
|
5140
5132
|
});
|
|
5141
5133
|
const _layerPosition = definePlugin((editor) => {
|
|
5142
5134
|
const {
|
|
5143
|
-
|
|
5135
|
+
isElement,
|
|
5136
|
+
rootAabb,
|
|
5144
5137
|
elementSelection,
|
|
5145
5138
|
getAabb
|
|
5146
5139
|
} = editor;
|
|
5147
5140
|
function align(direction) {
|
|
5148
|
-
const box = elementSelection.value.length === 1 ? currentFrameAabb.value : getAabb(elementSelection.value);
|
|
5149
5141
|
elementSelection.value.forEach((el) => {
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5142
|
+
if (el.parent && isElement(el.parent)) {
|
|
5143
|
+
const parentAabb = getAabb(el.parent);
|
|
5144
|
+
switch (direction) {
|
|
5145
|
+
case "left":
|
|
5146
|
+
el.style.left = 0;
|
|
5147
|
+
break;
|
|
5148
|
+
case "horizontal-center":
|
|
5149
|
+
el.style.left = (parentAabb.width - el.style.width) / 2;
|
|
5150
|
+
break;
|
|
5151
|
+
case "right":
|
|
5152
|
+
el.style.left = parentAabb.width - el.style.width;
|
|
5153
|
+
break;
|
|
5154
|
+
case "top":
|
|
5155
|
+
el.style.top = 0;
|
|
5156
|
+
break;
|
|
5157
|
+
case "vertical-center":
|
|
5158
|
+
el.style.top = (parentAabb.height - el.style.height) / 2;
|
|
5159
|
+
break;
|
|
5160
|
+
case "bottom":
|
|
5161
|
+
el.style.top = parentAabb.height - el.style.height;
|
|
5162
|
+
break;
|
|
5163
|
+
}
|
|
5164
|
+
} else {
|
|
5165
|
+
switch (direction) {
|
|
5166
|
+
case "left":
|
|
5167
|
+
el.style.left = rootAabb.value.left;
|
|
5168
|
+
break;
|
|
5169
|
+
case "horizontal-center":
|
|
5170
|
+
el.style.left = (rootAabb.value.left + rootAabb.value.width - el.style.width) / 2;
|
|
5171
|
+
break;
|
|
5172
|
+
case "right":
|
|
5173
|
+
el.style.left = rootAabb.value.left + rootAabb.value.width - el.style.width;
|
|
5174
|
+
break;
|
|
5175
|
+
case "top":
|
|
5176
|
+
el.style.top = rootAabb.value.top;
|
|
5177
|
+
break;
|
|
5178
|
+
case "vertical-center":
|
|
5179
|
+
el.style.top = (rootAabb.value.top + rootAabb.value.height - el.style.height) / 2;
|
|
5180
|
+
break;
|
|
5181
|
+
case "bottom":
|
|
5182
|
+
el.style.top = rootAabb.value.top + rootAabb.value.height - el.style.height;
|
|
5183
|
+
break;
|
|
5184
|
+
}
|
|
5169
5185
|
}
|
|
5170
5186
|
});
|
|
5171
5187
|
}
|
|
@@ -5282,20 +5298,55 @@ const _menu = definePlugin((editor, options) => {
|
|
|
5282
5298
|
{ key: "zoomToSelection", disabled: !hasSelected.value }
|
|
5283
5299
|
]
|
|
5284
5300
|
}));
|
|
5301
|
+
const panelsMenu = computed(() => ({
|
|
5302
|
+
key: "panels",
|
|
5303
|
+
children: [
|
|
5304
|
+
{ key: "panels:layers", checked: config.value.layers }
|
|
5305
|
+
]
|
|
5306
|
+
}));
|
|
5307
|
+
function setCheckerboard(value) {
|
|
5308
|
+
if (config.value.checkerboard && config.value.checkerboardStyle === value) {
|
|
5309
|
+
config.value.checkerboard = false;
|
|
5310
|
+
} else {
|
|
5311
|
+
config.value.checkerboard = true;
|
|
5312
|
+
config.value.checkerboardStyle = value;
|
|
5313
|
+
}
|
|
5314
|
+
}
|
|
5315
|
+
const checkerboardMenu = computed(() => ({
|
|
5316
|
+
key: "view:checkerboard",
|
|
5317
|
+
children: [
|
|
5318
|
+
{
|
|
5319
|
+
key: "checkerboardStyle:grid",
|
|
5320
|
+
checked: config.value.checkerboard && config.value.checkerboardStyle === "grid",
|
|
5321
|
+
handle: () => setCheckerboard("grid")
|
|
5322
|
+
},
|
|
5323
|
+
{
|
|
5324
|
+
key: "checkerboardStyle:dot",
|
|
5325
|
+
checked: config.value.checkerboard && config.value.checkerboardStyle === "dot",
|
|
5326
|
+
handle: () => setCheckerboard("dot")
|
|
5327
|
+
}
|
|
5328
|
+
]
|
|
5329
|
+
}));
|
|
5285
5330
|
const viewMenu = computed(() => ({
|
|
5286
5331
|
key: "view",
|
|
5287
5332
|
children: [
|
|
5288
|
-
|
|
5333
|
+
checkerboardMenu.value,
|
|
5289
5334
|
{ key: "view:pixelGrid", checked: config.value.pixelGrid },
|
|
5290
5335
|
{ key: "view:ruler", checked: config.value.ruler },
|
|
5291
5336
|
{ key: "view:scrollbar", checked: config.value.scrollbar },
|
|
5292
|
-
{ key: "view:layers", checked: config.value.layers },
|
|
5293
5337
|
{ key: "view:timeline", checked: config.value.timeline },
|
|
5294
5338
|
{ key: "view:statusbar", checked: config.value.statusbar },
|
|
5295
5339
|
{ key: "view:frameOutline", checked: config.value.frameOutline },
|
|
5296
5340
|
{ type: "divider" },
|
|
5341
|
+
{
|
|
5342
|
+
key: "pixelate",
|
|
5343
|
+
checked: config.value.pixelate,
|
|
5344
|
+
handle: () => config.value.pixelate = !config.value.pixelate
|
|
5345
|
+
},
|
|
5346
|
+
panelsMenu.value,
|
|
5347
|
+
{ type: "divider" },
|
|
5297
5348
|
...zoomViewMenu.value.children
|
|
5298
|
-
]
|
|
5349
|
+
].filter(Boolean)
|
|
5299
5350
|
}));
|
|
5300
5351
|
const objectMenu1 = computed(() => [
|
|
5301
5352
|
{ key: "groupSelection", disabled: !hasSelected.value },
|
|
@@ -5479,6 +5530,20 @@ const _open = definePlugin((editor) => {
|
|
|
5479
5530
|
]
|
|
5480
5531
|
};
|
|
5481
5532
|
});
|
|
5533
|
+
const _panels = definePlugin((editor) => {
|
|
5534
|
+
const {
|
|
5535
|
+
config
|
|
5536
|
+
} = editor;
|
|
5537
|
+
return {
|
|
5538
|
+
name: "mce:panels",
|
|
5539
|
+
commands: [
|
|
5540
|
+
{ command: "panels", handle: (panel) => config.value[panel] = !config.value[panel] }
|
|
5541
|
+
],
|
|
5542
|
+
hotkeys: [
|
|
5543
|
+
{ command: "panels:layers", key: "Alt+¡" }
|
|
5544
|
+
]
|
|
5545
|
+
};
|
|
5546
|
+
});
|
|
5482
5547
|
const _saveAs = definePlugin((editor) => {
|
|
5483
5548
|
const {
|
|
5484
5549
|
to,
|
|
@@ -5790,6 +5855,7 @@ const plugins = [
|
|
|
5790
5855
|
_move,
|
|
5791
5856
|
_new,
|
|
5792
5857
|
_open,
|
|
5858
|
+
_panels,
|
|
5793
5859
|
_saveAs,
|
|
5794
5860
|
_scroll,
|
|
5795
5861
|
_select,
|
|
@@ -6071,6 +6137,10 @@ const MceOverlaySymbol = Symbol.for("MceOverlaySymbol");
|
|
|
6071
6137
|
const makeMceOverlayProps = propsFactory({
|
|
6072
6138
|
location: String,
|
|
6073
6139
|
offset: Number,
|
|
6140
|
+
middlewares: {
|
|
6141
|
+
type: Object,
|
|
6142
|
+
default: () => ["offset", "flip", "shift"]
|
|
6143
|
+
},
|
|
6074
6144
|
target: Object,
|
|
6075
6145
|
attach: {
|
|
6076
6146
|
type: [String, Boolean, Object],
|
|
@@ -6120,14 +6190,10 @@ const makeMceStrategyProps = propsFactory({
|
|
|
6120
6190
|
hoverStrategy: Function
|
|
6121
6191
|
}, "makeMceStrategyProps");
|
|
6122
6192
|
const defaultResizeStrategy = (element) => {
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
return "diagonalAspectRatio";
|
|
6193
|
+
if (element.meta.lockAspectRatio) {
|
|
6194
|
+
return "aspectRatio";
|
|
6126
6195
|
}
|
|
6127
|
-
|
|
6128
|
-
return "diagonalAspectRatio";
|
|
6129
|
-
}
|
|
6130
|
-
return "free";
|
|
6196
|
+
return void 0;
|
|
6131
6197
|
};
|
|
6132
6198
|
const defaultActiveStrategy = (context) => {
|
|
6133
6199
|
const { element, oldElement, isExcluded } = context;
|
|
@@ -6587,14 +6653,15 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
|
|
|
6587
6653
|
});
|
|
6588
6654
|
const contentEl = useTemplateRef("contentElTpl");
|
|
6589
6655
|
const attach = computed(() => props.attach ?? overlayItem.attach?.value ?? "body");
|
|
6656
|
+
const middlewares = new Set(props.middlewares);
|
|
6590
6657
|
const { floatingStyles, update } = useFloating(target, contentEl, {
|
|
6591
6658
|
placement: computed(() => props.location),
|
|
6592
6659
|
whileElementsMounted: autoUpdate,
|
|
6593
6660
|
middleware: [
|
|
6594
|
-
offset(() => props.offset ?? 0),
|
|
6595
|
-
flip(),
|
|
6596
|
-
shift({ padding: 20 })
|
|
6597
|
-
]
|
|
6661
|
+
middlewares.has("offset") && offset(() => props.offset ?? 0),
|
|
6662
|
+
middlewares.has("flip") && flip(),
|
|
6663
|
+
middlewares.has("shift") && shift({ padding: 20 })
|
|
6664
|
+
].filter(Boolean)
|
|
6598
6665
|
});
|
|
6599
6666
|
const style = computed(() => {
|
|
6600
6667
|
return {
|
|
@@ -6686,7 +6753,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
|
|
|
6686
6753
|
const isActive = useModel(__props, "modelValue");
|
|
6687
6754
|
const opened = ref(-1);
|
|
6688
6755
|
const overlay = useTemplateRef("overlayTpl");
|
|
6689
|
-
const menuItemRefs =
|
|
6756
|
+
const menuItemRefs = ref([]);
|
|
6690
6757
|
const hasPrepend = computed(() => Boolean(props.items?.some((v) => "checked" in v)));
|
|
6691
6758
|
const uid = useId();
|
|
6692
6759
|
const parent = inject(MceMenuSymbol, null);
|
|
@@ -6723,10 +6790,16 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
|
|
|
6723
6790
|
} else {
|
|
6724
6791
|
isActive.value = false;
|
|
6725
6792
|
parent?.closeParents(e);
|
|
6726
|
-
item.handle
|
|
6727
|
-
|
|
6793
|
+
if (item.handle) {
|
|
6794
|
+
item.handle?.(e);
|
|
6795
|
+
} else {
|
|
6796
|
+
emit("click:item", item, e);
|
|
6797
|
+
}
|
|
6728
6798
|
}
|
|
6729
6799
|
}
|
|
6800
|
+
function onMouseenter(item, index) {
|
|
6801
|
+
opened.value = item.disabled ? -1 : index;
|
|
6802
|
+
}
|
|
6730
6803
|
function onMouseleave() {
|
|
6731
6804
|
if (props.items?.[opened.value]?.children?.length === void 0) {
|
|
6732
6805
|
opened.value = -1;
|
|
@@ -6765,14 +6838,14 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
|
|
|
6765
6838
|
item.type === "divider" ? (openBlock(), createElementBlock("div", {
|
|
6766
6839
|
key: 0,
|
|
6767
6840
|
ref_for: true,
|
|
6768
|
-
ref:
|
|
6841
|
+
ref: (el) => menuItemRefs.value[index] = el ?? void 0,
|
|
6769
6842
|
class: "mce-list__divider"
|
|
6770
6843
|
}, null, 512)) : (openBlock(), createElementBlock("div", {
|
|
6771
6844
|
key: 1,
|
|
6772
6845
|
ref_for: true,
|
|
6773
|
-
ref:
|
|
6846
|
+
ref: (el) => menuItemRefs.value[index] = el ?? void 0,
|
|
6774
6847
|
class: "mce-list__item",
|
|
6775
|
-
onMouseenter: ($event) => item
|
|
6848
|
+
onMouseenter: ($event) => onMouseenter(item, index)
|
|
6776
6849
|
}, [
|
|
6777
6850
|
createElementVNode("div", {
|
|
6778
6851
|
class: normalizeClass(["mce-list-item", [
|
|
@@ -6956,6 +7029,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
|
|
|
6956
7029
|
props: {
|
|
6957
7030
|
...makeMceOverlayProps({
|
|
6958
7031
|
location: "top-start",
|
|
7032
|
+
middlewares: ["offset", "shift"],
|
|
6959
7033
|
offset: 8
|
|
6960
7034
|
})
|
|
6961
7035
|
},
|
|
@@ -6981,6 +7055,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
|
|
|
6981
7055
|
ref: "overlayTpl",
|
|
6982
7056
|
class: "mce-floatbar",
|
|
6983
7057
|
location: props.location,
|
|
7058
|
+
middlewares: props.middlewares,
|
|
6984
7059
|
offset: unref(selection)[0] && unref(isFrame)(unref(selection)[0]) ? 32 : 8,
|
|
6985
7060
|
target: props.target,
|
|
6986
7061
|
attach: false,
|
|
@@ -6990,7 +7065,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
|
|
|
6990
7065
|
unref(selection).length > 0 ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
|
|
6991
7066
|
]),
|
|
6992
7067
|
_: 3
|
|
6993
|
-
}, 8, ["location", "offset", "target"]);
|
|
7068
|
+
}, 8, ["location", "middlewares", "offset", "target"]);
|
|
6994
7069
|
};
|
|
6995
7070
|
}
|
|
6996
7071
|
});
|
|
@@ -8032,11 +8107,11 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
8032
8107
|
props: {
|
|
8033
8108
|
tag: { default: "div" },
|
|
8034
8109
|
modelValue: {},
|
|
8035
|
-
|
|
8110
|
+
movable: { type: Boolean, default: true },
|
|
8036
8111
|
rotatable: { type: Boolean, default: true },
|
|
8037
8112
|
resizable: { type: Boolean, default: true },
|
|
8038
8113
|
threshold: { default: 0 },
|
|
8039
|
-
resizeStrategy: {
|
|
8114
|
+
resizeStrategy: {},
|
|
8040
8115
|
handleStrategy: { default: "default" },
|
|
8041
8116
|
handleShape: {},
|
|
8042
8117
|
color: { default: "black" },
|
|
@@ -8175,39 +8250,34 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
8175
8250
|
event?.preventDefault();
|
|
8176
8251
|
event?.stopPropagation();
|
|
8177
8252
|
const { left = 0, top = 0, width = 0, height = 0, rotate = 0 } = model.value;
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
const
|
|
8183
|
-
|
|
8184
|
-
const
|
|
8253
|
+
let aspectRatio = 0;
|
|
8254
|
+
if (width && height) {
|
|
8255
|
+
aspectRatio = width / height;
|
|
8256
|
+
}
|
|
8257
|
+
const handle = index === void 0 ? { type: "move", x: 0, y: 0, width: 0, height: 0 } : computedHandles.value[index];
|
|
8258
|
+
activeHandle.value = handle.type;
|
|
8259
|
+
const isMove = handle.type === "move";
|
|
8260
|
+
const isRotate = handle.type.startsWith("rotate");
|
|
8261
|
+
const isHorizontal = handle.type === "resize-left" || handle.type === "resize-right";
|
|
8262
|
+
const isHorizontalVertical = handle.type.split("-").length === 2;
|
|
8185
8263
|
const centerPoint = {
|
|
8186
8264
|
x: left + width / 2,
|
|
8187
8265
|
y: top + height / 2
|
|
8188
8266
|
};
|
|
8189
|
-
const
|
|
8190
|
-
x: left,
|
|
8191
|
-
y: top
|
|
8267
|
+
const startPoint = {
|
|
8268
|
+
x: left + handle.x + handle.width / 2,
|
|
8269
|
+
y: top + handle.y + handle.height / 2
|
|
8192
8270
|
};
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
const startingPoint = calcRotation(
|
|
8198
|
-
startingPointBefore,
|
|
8199
|
-
centerPoint,
|
|
8200
|
-
isMove ? 0 : rotate
|
|
8201
|
-
);
|
|
8202
|
-
const symmetricPoint = {
|
|
8203
|
-
x: centerPoint.x * 2 - startingPoint.x,
|
|
8204
|
-
y: centerPoint.y * 2 - startingPoint.y
|
|
8271
|
+
const rotatedStartPoint = rotatePoint(startPoint, centerPoint, rotate);
|
|
8272
|
+
const rotatedSymmetricPoint = {
|
|
8273
|
+
x: centerPoint.x * 2 - rotatedStartPoint.x,
|
|
8274
|
+
y: centerPoint.y * 2 - rotatedStartPoint.y
|
|
8205
8275
|
};
|
|
8206
|
-
const
|
|
8207
|
-
|
|
8208
|
-
|
|
8276
|
+
const startAngle = Math.atan2(
|
|
8277
|
+
rotatedStartPoint.y - centerPoint.y,
|
|
8278
|
+
rotatedStartPoint.x - centerPoint.x
|
|
8209
8279
|
) / (Math.PI / 180);
|
|
8210
|
-
let
|
|
8280
|
+
let startClientPoint = event ? { x: event.clientX, y: event.clientY } : void 0;
|
|
8211
8281
|
function startTransform() {
|
|
8212
8282
|
transforming.value = true;
|
|
8213
8283
|
emit("start", model.value);
|
|
@@ -8217,81 +8287,67 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
8217
8287
|
}
|
|
8218
8288
|
function onMove(event2) {
|
|
8219
8289
|
const updated = {};
|
|
8220
|
-
if (!
|
|
8221
|
-
|
|
8290
|
+
if (!startClientPoint) {
|
|
8291
|
+
startClientPoint = { x: event2.clientX, y: event2.clientY };
|
|
8222
8292
|
}
|
|
8223
|
-
const
|
|
8224
|
-
x: event2.clientX -
|
|
8225
|
-
y: event2.clientY -
|
|
8293
|
+
const offset2 = {
|
|
8294
|
+
x: event2.clientX - startClientPoint.x,
|
|
8295
|
+
y: event2.clientY - startClientPoint.y
|
|
8226
8296
|
};
|
|
8227
8297
|
if (!transforming.value) {
|
|
8228
|
-
if (Math.abs(
|
|
8298
|
+
if (Math.abs(offset2.x) < props.threshold && Math.abs(offset2.y) < props.threshold) {
|
|
8229
8299
|
return;
|
|
8230
8300
|
}
|
|
8231
8301
|
startTransform();
|
|
8232
8302
|
}
|
|
8233
|
-
const
|
|
8234
|
-
x:
|
|
8235
|
-
y:
|
|
8303
|
+
const rotatedCurrentPoint = {
|
|
8304
|
+
x: rotatedStartPoint.x + offset2.x,
|
|
8305
|
+
y: rotatedStartPoint.y + offset2.y
|
|
8236
8306
|
};
|
|
8237
8307
|
if (isMove) {
|
|
8238
|
-
if (
|
|
8239
|
-
|
|
8308
|
+
if (props.movable) {
|
|
8309
|
+
updated.left = startPoint.x + offset2.x;
|
|
8310
|
+
updated.top = startPoint.y + offset2.y;
|
|
8240
8311
|
}
|
|
8241
|
-
updated.left = cursorPoint.x;
|
|
8242
|
-
updated.top = cursorPoint.y;
|
|
8243
8312
|
} else if (isRotate) {
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8313
|
+
if (props.rotatable) {
|
|
8314
|
+
const endAngle = Math.atan2(
|
|
8315
|
+
rotatedCurrentPoint.y - centerPoint.y,
|
|
8316
|
+
rotatedCurrentPoint.x - centerPoint.x
|
|
8317
|
+
) / (Math.PI / 180);
|
|
8318
|
+
updated.rotate = (rotate + endAngle - startAngle + 360) % 360;
|
|
8319
|
+
}
|
|
8249
8320
|
} else if (isHorizontalVertical) {
|
|
8250
|
-
const
|
|
8251
|
-
const
|
|
8252
|
-
|
|
8253
|
-
|
|
8254
|
-
rotate
|
|
8255
|
-
);
|
|
8256
|
-
const newCenterPoint = {
|
|
8257
|
-
x: rotationAfter.x - (rotationAfter.x - symmetricPoint.x) / 2,
|
|
8258
|
-
y: rotationAfter.y + (symmetricPoint.y - rotationAfter.y) / 2
|
|
8259
|
-
};
|
|
8260
|
-
const hypotenuse = calcHypotenuse(rotationAfter, symmetricPoint);
|
|
8321
|
+
const currentPoint = rotatePoint(rotatedCurrentPoint, centerPoint, -rotate);
|
|
8322
|
+
const newCurrentPoint = isHorizontal ? { x: currentPoint.x, y: startPoint.y } : { x: startPoint.x, y: currentPoint.y };
|
|
8323
|
+
const newRotatedCurrentPoint = rotatePoint(newCurrentPoint, centerPoint, rotate);
|
|
8324
|
+
const hypotenuse = Math.abs(getDistance(newRotatedCurrentPoint, rotatedSymmetricPoint));
|
|
8261
8325
|
if (isHorizontal) {
|
|
8262
8326
|
updated.width = hypotenuse;
|
|
8263
|
-
if (
|
|
8327
|
+
if (props.resizeStrategy === "aspectRatio" && aspectRatio) {
|
|
8264
8328
|
updated.height = hypotenuse / aspectRatio;
|
|
8329
|
+
} else {
|
|
8330
|
+
updated.height = height;
|
|
8265
8331
|
}
|
|
8266
8332
|
} else {
|
|
8267
8333
|
updated.height = hypotenuse;
|
|
8268
|
-
if (
|
|
8334
|
+
if (props.resizeStrategy === "aspectRatio" && aspectRatio) {
|
|
8269
8335
|
updated.width = hypotenuse * aspectRatio;
|
|
8270
|
-
}
|
|
8271
|
-
}
|
|
8272
|
-
updated.left = newCenterPoint.x - (isHorizontal ? hypotenuse : width) / 2;
|
|
8273
|
-
updated.top = newCenterPoint.y - (isHorizontal ? height : hypotenuse) / 2;
|
|
8274
|
-
} else {
|
|
8275
|
-
if (aspectRatio && (props.resizeStrategy === "aspectRatio" || props.resizeStrategy === "diagonalAspectRatio")) {
|
|
8276
|
-
let flag = 1;
|
|
8277
|
-
switch (anchor.type) {
|
|
8278
|
-
case "resize-top-right":
|
|
8279
|
-
case "resize-bottom-left":
|
|
8280
|
-
flag = -1;
|
|
8281
|
-
break;
|
|
8282
|
-
}
|
|
8283
|
-
if (clientOffset.x > clientOffset.y) {
|
|
8284
|
-
cursorPoint.x = startingPoint.x + clientOffset.x;
|
|
8285
|
-
cursorPoint.y = startingPoint.y + flag * clientOffset.x / aspectRatio;
|
|
8286
8336
|
} else {
|
|
8287
|
-
|
|
8288
|
-
cursorPoint.y = startingPoint.y + clientOffset.y;
|
|
8337
|
+
updated.width = width;
|
|
8289
8338
|
}
|
|
8290
8339
|
}
|
|
8291
|
-
const newCenterPoint =
|
|
8340
|
+
const newCenterPoint = {
|
|
8341
|
+
x: newRotatedCurrentPoint.x - (newRotatedCurrentPoint.x - rotatedSymmetricPoint.x) / 2,
|
|
8342
|
+
y: newRotatedCurrentPoint.y + (rotatedSymmetricPoint.y - newRotatedCurrentPoint.y) / 2
|
|
8343
|
+
};
|
|
8344
|
+
updated.left = newCenterPoint.x - updated.width / 2;
|
|
8345
|
+
updated.top = newCenterPoint.y - updated.height / 2;
|
|
8346
|
+
} else {
|
|
8347
|
+
const newCenterPoint = getMidpoint(rotatedCurrentPoint, rotatedSymmetricPoint);
|
|
8292
8348
|
const points = [
|
|
8293
|
-
|
|
8294
|
-
|
|
8349
|
+
rotatePoint(rotatedCurrentPoint, newCenterPoint, -rotate),
|
|
8350
|
+
rotatePoint(rotatedSymmetricPoint, newCenterPoint, -rotate)
|
|
8295
8351
|
];
|
|
8296
8352
|
const [minX, maxX] = points[0].x > points[1].x ? [points[1].x, points[0].x] : [points[0].x, points[1].x];
|
|
8297
8353
|
const [minY, maxY] = points[0].y > points[1].y ? [points[1].y, points[0].y] : [points[0].y, points[1].y];
|
|
@@ -8299,6 +8355,13 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
8299
8355
|
updated.height = maxY - minY;
|
|
8300
8356
|
updated.left = minX;
|
|
8301
8357
|
updated.top = minY;
|
|
8358
|
+
if ((props.resizeStrategy === "aspectRatio" || props.resizeStrategy === "diagonalAspectRatio") && aspectRatio) {
|
|
8359
|
+
if (updated.width / updated.height > aspectRatio) {
|
|
8360
|
+
updated.width = updated.height * aspectRatio;
|
|
8361
|
+
} else {
|
|
8362
|
+
updated.height = updated.width / aspectRatio;
|
|
8363
|
+
}
|
|
8364
|
+
}
|
|
8302
8365
|
}
|
|
8303
8366
|
if ("width" in updated && updated.width <= 0 || "height" in updated && updated.height <= 0) {
|
|
8304
8367
|
return;
|
|
@@ -8332,7 +8395,7 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
8332
8395
|
return "move";
|
|
8333
8396
|
return `url("data:image/svg+xml,${cursors[type](model.value.rotate ?? 0)}") 16 16, pointer`;
|
|
8334
8397
|
}
|
|
8335
|
-
function
|
|
8398
|
+
function rotatePoint(point, origin, angle) {
|
|
8336
8399
|
const radian = angle * Math.PI / 180;
|
|
8337
8400
|
const cos = Math.cos(radian);
|
|
8338
8401
|
const sin = Math.sin(radian);
|
|
@@ -8341,14 +8404,16 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
8341
8404
|
y: (point.x - origin.x) * sin + (point.y - origin.y) * cos + origin.y
|
|
8342
8405
|
};
|
|
8343
8406
|
}
|
|
8344
|
-
function
|
|
8407
|
+
function getMidpoint(point1, point2) {
|
|
8345
8408
|
return {
|
|
8346
8409
|
x: (point2.x + point1.x) / 2,
|
|
8347
8410
|
y: (point2.y + point1.y) / 2
|
|
8348
8411
|
};
|
|
8349
8412
|
}
|
|
8350
|
-
function
|
|
8351
|
-
|
|
8413
|
+
function getDistance(point1, point2) {
|
|
8414
|
+
const dx = point2.x - point1.x;
|
|
8415
|
+
const dy = point2.y - point1.y;
|
|
8416
|
+
return (dx + dy >= 0 ? 1 : -1) * Math.sqrt(dx * dx + dy * dy);
|
|
8352
8417
|
}
|
|
8353
8418
|
onMounted(async () => {
|
|
8354
8419
|
const vm = getCurrentInstance();
|
|
@@ -8413,7 +8478,7 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
8413
8478
|
}, null, 4),
|
|
8414
8479
|
createElementVNode("g", _hoisted_2$5, [
|
|
8415
8480
|
(openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value.filter((v) => {
|
|
8416
|
-
return !(!__props.resizable && v.type.startsWith("resize") || !__props.rotatable && v.type.startsWith("rotate") || !__props.
|
|
8481
|
+
return !(!__props.resizable && v.type.startsWith("resize") || !__props.rotatable && v.type.startsWith("rotate") || !__props.movable && v.type === "move");
|
|
8417
8482
|
}), (handle, index) => {
|
|
8418
8483
|
return openBlock(), createElementBlock(Fragment, { key: index }, [
|
|
8419
8484
|
(__props.handleStrategy === "point" ? handle.type.startsWith("resize") : handle.type === "resize-top-left" || handle.type === "resize-top-right" || handle.type === "resize-bottom-left" || handle.type === "resize-bottom-right") ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
@@ -8540,8 +8605,8 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
|
8540
8605
|
const offsetBox = {
|
|
8541
8606
|
left: Math.round((val.left - oldBox.left) / zoom.x),
|
|
8542
8607
|
top: Math.round((val.top - oldBox.top) / zoom.y),
|
|
8543
|
-
width: Math.round((val.width - oldBox.width
|
|
8544
|
-
height: Math.round((val.height - oldBox.height
|
|
8608
|
+
width: Math.round(Math.max(1, val.width / zoom.x) - oldBox.width / zoom.x),
|
|
8609
|
+
height: Math.round(Math.max(1, val.height / zoom.y) - oldBox.height / zoom.y),
|
|
8545
8610
|
rotate: Math.round((val.rotate ?? 0) - (oldBox.rotate ?? 0))
|
|
8546
8611
|
};
|
|
8547
8612
|
const handle = transformable.value?.activeHandle ?? "move";
|
|
@@ -8620,7 +8685,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
|
8620
8685
|
modelValue: selectionObb.value,
|
|
8621
8686
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectionObb.value = $event),
|
|
8622
8687
|
visibility: unref(state) !== "selecting" ? "auto" : "none",
|
|
8623
|
-
|
|
8688
|
+
movable: unref(elementSelection)[0] && !unref(isLock)(unref(elementSelection)[0]),
|
|
8624
8689
|
"resize-strategy": props.resizeStrategy,
|
|
8625
8690
|
"handle-shape": unref(config).handleShape,
|
|
8626
8691
|
class: "mce-selection-obb",
|
|
@@ -8636,7 +8701,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
|
8636
8701
|
]),
|
|
8637
8702
|
key: "0"
|
|
8638
8703
|
} : void 0
|
|
8639
|
-
]), 1032, ["modelValue", "visibility", "
|
|
8704
|
+
]), 1032, ["modelValue", "visibility", "movable", "resize-strategy", "handle-shape", "border-style"])) : createCommentVNode("", true),
|
|
8640
8705
|
selectionObb.value.width && selectionObb.value.height && _ctx.$slots.default ? (openBlock(), createElementBlock("div", {
|
|
8641
8706
|
key: 2,
|
|
8642
8707
|
style: normalizeStyle([{ "position": "absolute" }, unref(boundingBoxToStyle)(selectionObb.value)])
|
|
@@ -9388,6 +9453,16 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9388
9453
|
const selector = useTemplateRef("selectorTpl");
|
|
9389
9454
|
const textEditor = useTemplateRef("textEditorTpl");
|
|
9390
9455
|
const selectedArea = ref({ left: 0, top: 0, width: 0, height: 0 });
|
|
9456
|
+
const resizeStrategy = computed(() => {
|
|
9457
|
+
const first = elementSelection.value[0];
|
|
9458
|
+
if (first) {
|
|
9459
|
+
if (first.text.isValid()) {
|
|
9460
|
+
return "diagonalAspectRatio";
|
|
9461
|
+
}
|
|
9462
|
+
return props.resizeStrategy(first);
|
|
9463
|
+
}
|
|
9464
|
+
return void 0;
|
|
9465
|
+
});
|
|
9391
9466
|
provideOverlay({
|
|
9392
9467
|
attach: computed(() => overlayContainer.value)
|
|
9393
9468
|
});
|
|
@@ -9438,28 +9513,28 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9438
9513
|
hoverElement.value = hovered;
|
|
9439
9514
|
setCursor(cursor);
|
|
9440
9515
|
}
|
|
9441
|
-
function onPointerdown(
|
|
9442
|
-
if (
|
|
9516
|
+
function onPointerdown(downEvent) {
|
|
9517
|
+
if (downEvent.srcElement !== drawboardDom.value && downEvent.srcElement.dataset?.pointerdown_to_drawboard === void 0 || camera.value.spaceKey || ![0, 2].includes(downEvent.button)) {
|
|
9443
9518
|
return;
|
|
9444
9519
|
}
|
|
9445
9520
|
const oldElement = elementSelection.value[0];
|
|
9446
|
-
const element =
|
|
9447
|
-
const start = { x:
|
|
9521
|
+
const element = downEvent.target;
|
|
9522
|
+
const start = { x: downEvent.clientX, y: downEvent.clientY };
|
|
9448
9523
|
let current = { ...start };
|
|
9449
9524
|
let dragging = false;
|
|
9450
9525
|
let isUp = false;
|
|
9451
9526
|
let selected = [];
|
|
9452
9527
|
let ctxState;
|
|
9453
|
-
const
|
|
9528
|
+
const inSelection = isPointInsideAabb({
|
|
9454
9529
|
x: start.x + -drawboardAabb.value.left,
|
|
9455
9530
|
y: start.y + -drawboardAabb.value.top
|
|
9456
9531
|
}, getAabbInDrawboard(elementSelection.value));
|
|
9457
|
-
if (
|
|
9458
|
-
if (!
|
|
9532
|
+
if (downEvent.button === 2) {
|
|
9533
|
+
if (!inSelection) {
|
|
9459
9534
|
const result = props.activeStrategy({
|
|
9460
9535
|
element,
|
|
9461
9536
|
oldElement,
|
|
9462
|
-
event,
|
|
9537
|
+
event: downEvent,
|
|
9463
9538
|
isExcluded
|
|
9464
9539
|
});
|
|
9465
9540
|
if (result && !(result instanceof Element2D)) {
|
|
@@ -9471,11 +9546,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9471
9546
|
}
|
|
9472
9547
|
return;
|
|
9473
9548
|
}
|
|
9474
|
-
function onDrag(
|
|
9549
|
+
function onDrag(event) {
|
|
9475
9550
|
const result = props.activeStrategy({
|
|
9476
9551
|
element,
|
|
9477
9552
|
oldElement,
|
|
9478
|
-
event
|
|
9553
|
+
event,
|
|
9479
9554
|
isExcluded
|
|
9480
9555
|
});
|
|
9481
9556
|
if (result && !(result instanceof Element2D)) {
|
|
@@ -9501,7 +9576,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9501
9576
|
const result = props.activeStrategy({
|
|
9502
9577
|
element,
|
|
9503
9578
|
oldElement,
|
|
9504
|
-
event,
|
|
9579
|
+
event: downEvent,
|
|
9505
9580
|
isExcluded: () => false
|
|
9506
9581
|
});
|
|
9507
9582
|
let _element;
|
|
@@ -9511,7 +9586,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9511
9586
|
} else {
|
|
9512
9587
|
_element = result;
|
|
9513
9588
|
}
|
|
9514
|
-
if (_element && (
|
|
9589
|
+
if (_element && (downEvent?.ctrlKey || downEvent?.shiftKey || downEvent?.metaKey)) {
|
|
9515
9590
|
if (elementSelection.value.findIndex((v) => v.equal(_element)) > -1) {
|
|
9516
9591
|
selected = elementSelection.value.filter((v) => !v.equal(_element));
|
|
9517
9592
|
} else {
|
|
@@ -9524,29 +9599,29 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9524
9599
|
function canStartDrag() {
|
|
9525
9600
|
return !dragging && (Math.abs(current.x - start.x) >= 3 || Math.abs(current.y - start.y) >= 3);
|
|
9526
9601
|
}
|
|
9527
|
-
function onEngineMove(
|
|
9528
|
-
if (
|
|
9602
|
+
function onEngineMove(moveEvent) {
|
|
9603
|
+
if (inSelection) {
|
|
9529
9604
|
if (canStartDrag()) {
|
|
9530
9605
|
dragging = true;
|
|
9531
|
-
exec("startTransform");
|
|
9606
|
+
exec("startTransform", downEvent);
|
|
9532
9607
|
}
|
|
9533
9608
|
} else {
|
|
9534
9609
|
if (element && !isFrame(element)) {
|
|
9535
9610
|
if (canStartDrag()) {
|
|
9536
9611
|
dragging = true;
|
|
9537
|
-
onDrag(
|
|
9612
|
+
onDrag(moveEvent);
|
|
9538
9613
|
nextTick(() => {
|
|
9539
9614
|
if (!isUp) {
|
|
9540
|
-
exec("startTransform");
|
|
9615
|
+
exec("startTransform", downEvent);
|
|
9541
9616
|
}
|
|
9542
9617
|
});
|
|
9543
9618
|
}
|
|
9544
9619
|
}
|
|
9545
9620
|
}
|
|
9546
9621
|
}
|
|
9547
|
-
function onMove(
|
|
9548
|
-
current = { x:
|
|
9549
|
-
if (!
|
|
9622
|
+
function onMove(moveEvent) {
|
|
9623
|
+
current = { x: moveEvent.clientX, y: moveEvent.clientY };
|
|
9624
|
+
if (!inSelection) {
|
|
9550
9625
|
if (!element || isFrame(element)) {
|
|
9551
9626
|
onSelectArea();
|
|
9552
9627
|
}
|
|
@@ -9571,7 +9646,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9571
9646
|
}
|
|
9572
9647
|
}
|
|
9573
9648
|
}
|
|
9574
|
-
onHover(
|
|
9649
|
+
onHover(downEvent);
|
|
9575
9650
|
}
|
|
9576
9651
|
renderEngine.value.off("pointermove", onEngineMove);
|
|
9577
9652
|
document.removeEventListener("pointermove", onMove);
|
|
@@ -9632,7 +9707,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
9632
9707
|
createVNode(_sfc_main$g, {
|
|
9633
9708
|
ref: "selectorTpl",
|
|
9634
9709
|
"selected-area": selectedArea.value,
|
|
9635
|
-
"resize-strategy":
|
|
9710
|
+
"resize-strategy": resizeStrategy.value
|
|
9636
9711
|
}, {
|
|
9637
9712
|
transformable: withCtx(({ box }) => [
|
|
9638
9713
|
renderSlot(_ctx.$slots, "transformer", { box })
|