@plait/common 0.75.0-next.9 → 0.76.0
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/core/element-ref.d.ts +1 -0
- package/esm2022/core/element-ref.mjs +3 -2
- package/esm2022/core/group.component.mjs +3 -3
- package/esm2022/generators/active.generator.mjs +12 -9
- package/esm2022/generators/generator.mjs +20 -14
- package/esm2022/image/image.generator.mjs +5 -5
- package/esm2022/plugins/with-group.mjs +22 -22
- package/esm2022/text/text-measure.mjs +31 -3
- package/fesm2022/plait-common.mjs +86 -49
- package/fesm2022/plait-common.mjs.map +1 -1
- package/generators/active.generator.d.ts +3 -2
- package/generators/generator.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Node } from 'slate';
|
|
2
2
|
import { getLineHeightByFontSize } from '../utils/text';
|
|
3
|
+
import { IS_WINDOWS } from '@plait/core';
|
|
3
4
|
export function measureElement(element, options, containerMaxWidth = 10000) {
|
|
4
5
|
const canvas = document.createElement('canvas');
|
|
5
6
|
const ctx = canvas.getContext('2d');
|
|
@@ -30,8 +31,35 @@ export function measureElement(element, options, containerMaxWidth = 10000) {
|
|
|
30
31
|
lineTexts.forEach((text, index) => {
|
|
31
32
|
const font = getFont(text, { fontFamily: options.fontFamily, fontSize: options.fontSize });
|
|
32
33
|
ctx.font = font;
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
// Windows 平台下的特殊处理
|
|
35
|
+
if (IS_WINDOWS) {
|
|
36
|
+
let adjustedWidth = 0;
|
|
37
|
+
// 逐字符处理
|
|
38
|
+
for (let i = 0; i < text.text.length; i++) {
|
|
39
|
+
const char = text.text[i];
|
|
40
|
+
const charMetrics = ctx.measureText(char);
|
|
41
|
+
// 判断是否为汉字(通过 Unicode 范围)
|
|
42
|
+
if (/[\u4e00-\u9fa5]/.test(char)) {
|
|
43
|
+
adjustedWidth += charMetrics.width;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// 非汉字字符的宽度调整
|
|
47
|
+
if (/[a-zA-Z]/.test(char)) {
|
|
48
|
+
adjustedWidth += charMetrics.width + 1.5; // 字母
|
|
49
|
+
}
|
|
50
|
+
else if (/[0-9]/.test(char)) {
|
|
51
|
+
adjustedWidth += charMetrics.width + 1.5; // 数字
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
adjustedWidth += charMetrics.width + 0.8; // 其他符号
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
lineWidth += adjustedWidth;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
lineWidth += ctx.measureText(text.text).width;
|
|
62
|
+
}
|
|
35
63
|
const isLast = index === lineTexts.length - 1;
|
|
36
64
|
// skip when text is empty and is not last text of line
|
|
37
65
|
if (text['font-size'] && (isLast || text.text !== '')) {
|
|
@@ -58,4 +86,4 @@ export function measureElement(element, options, containerMaxWidth = 10000) {
|
|
|
58
86
|
const getFont = (text, options) => {
|
|
59
87
|
return `${text.italic ? 'italic ' : ''} ${text.bold ? 'bold ' : ''} ${text['font-size'] || options.fontSize}px ${options.fontFamily} `;
|
|
60
88
|
};
|
|
61
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1tZWFzdXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tbW9uL3NyYy90ZXh0L3RleHQtbWVhc3VyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRTdCLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV4RCxNQUFNLFVBQVUsY0FBYyxDQUMxQixPQUF5QixFQUN6QixPQUdDLEVBQ0Qsb0JBQTRCLEtBQUs7SUFFakMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNoRCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBNkIsQ0FBQztJQUNoRSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sS0FBSyxHQUFtQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ25DLEtBQUssTUFBTSxTQUFTLElBQUksV0FBVyxFQUFFLENBQUM7UUFDbEMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQztRQUN6QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLGlCQUF5QixFQUFFLEtBQWEsRUFBRSxFQUFFO1lBQzNELE1BQU0sV0FBVyxHQUFHLEVBQUUsR0FBRyxJQUFJLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLENBQUM7WUFDekQsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ2QsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFN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XG5pbXBvcnQgeyBDdXN0b21UZXh0LCBQYXJhZ3JhcGhFbGVtZW50IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRMaW5lSGVpZ2h0QnlGb250U2l6ZSB9IGZyb20gJy4uL3V0aWxzL3RleHQnO1xuXG5leHBvcnQgZnVuY3Rpb24gbWVhc3VyZUVsZW1lbnQoXG4gICAgZWxlbWVudDogUGFyYWdyYXBoRWxlbWVudCxcbiAgICBvcHRpb25zOiB7XG4gICAgICAgIGZvbnRTaXplOiBudW1iZXI7XG4gICAgICAgIGZvbnRGYW1pbHk6IHN0cmluZztcbiAgICB9LFxuICAgIGNvbnRhaW5lck1heFdpZHRoOiBudW1iZXIgPSAxMDAwMFxuKSB7XG4gICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJykgYXMgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEO1xuICAgIGNvbnN0IHRleHRFbnRyaWVzID0gTm9kZS50ZXh0cyhlbGVtZW50KTtcbiAgICBjb25zdCBsaW5lczogQ3VzdG9tVGV4dFtdW10gPSBbW11dO1xuICAgIGZvciAoY29uc3QgdGV4dEVudHJ5IG9mIHRleHRFbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IFt0ZXh0XSA9IHRleHRFbnRyeTtcbiAgICAgICAgY29uc3QgdGV4dFN0cmluZyA9IE5vZGUuc3RyaW5nKHRleHQpO1xuICAgICAgICBjb25zdCB0ZXh0QXJyYXkgPSB0ZXh0U3RyaW5nLnNwbGl0KCdcXG4nKTtcbiAgICAgICAgdGV4dEFycmF5LmZvckVhY2goKHNlZ21lbnRUZXh0U3RyaW5nOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNlZ21lbnRUZXh0ID0geyAuLi50ZXh0LCB0ZXh0OiBzZWdtZW50VGV4dFN0cmluZyB9O1xuICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudExpbmUgPSBsaW5lc1tsaW5lcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICBjdXJyZW50TGluZS5wdXNoKHNlZ21lbnRUZXh0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TGluZTogQ3VzdG9tVGV4dFtdID0gW107XG4gICAgICAgICAgICAgICAgbmV3TGluZS5wdXNoKHNlZ21lbnRUZXh0KTtcbiAgICAgICAgICAgICAgICBsaW5lcy5wdXNoKG5ld0xpbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbGV0IHdpZHRoID0gMDtcbiAgICBsZXQgaGVpZ2h0ID0gMDtcbiAgICBsaW5lcy5mb3JFYWNoKChsaW5lVGV4dHM6IEN1c3RvbVRleHRbXSwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBsZXQgbGluZVdpZHRoID0gMDtcbiAgICAgICAgbGV0IG1heExpbmVIZWlnaHQgPSBnZXRMaW5lSGVpZ2h0QnlGb250U2l6ZShvcHRpb25zLmZvbnRTaXplKTtcbiAgICAgICAgbGluZVRleHRzLmZvckVhY2goKHRleHQ6IEN1c3RvbVRleHQsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZvbnQgPSBnZXRGb250KHRleHQsIHsgZm9udEZhbWlseTogb3B0aW9ucy5mb250RmFtaWx5LCBmb250U2l6ZTogb3B0aW9ucy5mb250U2l6ZSB9KTtcbiAgICAgICAgICAgIGN0eC5mb250ID0gZm9udDtcbiAgICAgICAgICAgIGNvbnN0IHRleHRNZXRyaWNzID0gY3R4Lm1lYXN1cmVUZXh0KHRleHQudGV4dCk7XG4gICAgICAgICAgICBsaW5lV2lkdGggKz0gdGV4dE1ldHJpY3Mud2lkdGg7XG4gICAgICAgICAgICBjb25zdCBpc0xhc3QgPSBpbmRleCA9PT0gbGluZVRleHRzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICAvLyBza2lwIHdoZW4gdGV4dCBpcyBlbXB0eSBhbmQgaXMgbm90IGxhc3QgdGV4dCBvZiBsaW5lXG4gICAgICAgICAgICBpZiAodGV4dFsnZm9udC1zaXplJ10gJiYgKGlzTGFzdCB8fCB0ZXh0LnRleHQgIT09ICcnKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSBnZXRMaW5lSGVpZ2h0QnlGb250U2l6ZShwYXJzZUZsb2F0KHRleHRbJ2ZvbnQtc2l6ZSddKSk7XG4gICAgICAgICAgICAgICAgaWYgKGxpbmVIZWlnaHQgPiBtYXhMaW5lSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIG1heExpbmVIZWlnaHQgPSBsaW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChsaW5lV2lkdGggPD0gY29udGFpbmVyTWF4V2lkdGgpIHtcbiAgICAgICAgICAgIGlmIChsaW5lV2lkdGggPiB3aWR0aCkge1xuICAgICAgICAgICAgICAgIHdpZHRoID0gbGluZVdpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGVpZ2h0ICs9IG1heExpbmVIZWlnaHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3aWR0aCA9IGNvbnRhaW5lck1heFdpZHRoO1xuICAgICAgICAgICAgY29uc3QgbGluZVdyYXBOdW1iZXIgPSBNYXRoLmNlaWwobGluZVdpZHRoIC8gY29udGFpbmVyTWF4V2lkdGgpO1xuICAgICAgICAgICAgaGVpZ2h0ICs9IG1heExpbmVIZWlnaHQgKiBsaW5lV3JhcE51bWJlcjtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB7IHdpZHRoLCBoZWlnaHQgfTtcbn1cblxuY29uc3QgZ2V0Rm9udCA9IChcbiAgICB0ZXh0OiBDdXN0b21UZXh0LFxuICAgIG9wdGlvbnM6IHtcbiAgICAgICAgZm9udFNpemU6IG51bWJlcjtcbiAgICAgICAgZm9udEZhbWlseTogc3RyaW5nO1xuICAgIH1cbikgPT4ge1xuICAgIHJldHVybiBgJHt0ZXh0Lml0YWxpYyA/ICdpdGFsaWMgJyA6ICcnfSAke3RleHQuYm9sZCA/ICdib2xkICcgOiAnJ30gJHt0ZXh0Wydmb250LXNpemUnXSB8fCBvcHRpb25zLmZvbnRTaXplfXB4ICR7b3B0aW9ucy5mb250RmFtaWx5fSBgO1xufTtcbiJdfQ==
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1tZWFzdXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tbW9uL3NyYy90ZXh0L3RleHQtbWVhc3VyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRTdCLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXpDLE1BQU0sVUFBVSxjQUFjLENBQzFCLE9BQXlCLEVBQ3pCLE9BR0MsRUFDRCxvQkFBNEIsS0FBSztJQUVqQyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2hELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUE2QixDQUFDO0lBQ2hFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEMsTUFBTSxLQUFLLEdBQW1CLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkMsS0FBSyxNQUFNLFNBQVMsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNsQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDO1FBQ3pCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsaUJBQXlCLEVBQUUsS0FBYSxFQUFFLEVBQUU7WUFDM0QsTUFBTSxXQUFXLEdBQUcsRUFBRSxHQUFHLElBQUksRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQztZQUN6RCxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFD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VSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFFLElBQUksVUFBVSxHQUFHLGFBQWEsRUFBRSxDQUFDO29CQUM3QixhQUFhLEdBQUcsVUFBVSxDQUFDO2dCQUMvQixDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxTQUFTLElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUNqQyxJQUFJLFNBQVMsR0FBRyxLQUFLLEVBQUUsQ0FBQztnQkFDcEIsS0FBSyxHQUFHLFNBQVMsQ0FBQztZQUN0QixDQUFDO1lBQ0QsTUFBTSxJQUFJLGFBQWEsQ0FBQztRQUM1QixDQUFDO2FBQU0sQ0FBQztZQUNKLEtBQUssR0FBRyxpQkFBaUIsQ0FBQztZQUMxQixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sSUFBSSxhQUFhLEdBQUcsY0FBYyxDQUFDO1FBQzdDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDN0IsQ0FBQztBQUVELE1BQU0sT0FBTyxHQUFHLENBQ1osSUFBZ0IsRUFDaEIsT0FHQyxFQUNILEVBQUU7SUFDQSxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLE1BQU0sT0FBTyxDQUFDLFVBQVUsR0FBRyxDQUFDO0FBQzNJLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5vZGUgfSBmcm9tICdzbGF0ZSc7XG5pbXBvcnQgeyBDdXN0b21UZXh0LCBQYXJhZ3JhcGhFbGVtZW50IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRMaW5lSGVpZ2h0QnlGb250U2l6ZSB9IGZyb20gJy4uL3V0aWxzL3RleHQnO1xuaW1wb3J0IHsgSVNfV0lORE9XUyB9IGZyb20gJ0BwbGFpdC9jb3JlJztcblxuZXhwb3J0IGZ1bmN0aW9uIG1lYXN1cmVFbGVtZW50KFxuICAgIGVsZW1lbnQ6IFBhcmFncmFwaEVsZW1lbnQsXG4gICAgb3B0aW9uczoge1xuICAgICAgICBmb250U2l6ZTogbnVtYmVyO1xuICAgICAgICBmb250RmFtaWx5OiBzdHJpbmc7XG4gICAgfSxcbiAgICBjb250YWluZXJNYXhXaWR0aDogbnVtYmVyID0gMTAwMDBcbikge1xuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpIGFzIENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcbiAgICBjb25zdCB0ZXh0RW50cmllcyA9IE5vZGUudGV4dHMoZWxlbWVudCk7XG4gICAgY29uc3QgbGluZXM6IEN1c3RvbVRleHRbXVtdID0gW1tdXTtcbiAgICBmb3IgKGNvbnN0IHRleHRFbnRyeSBvZiB0ZXh0RW50cmllcykge1xuICAgICAgICBjb25zdCBbdGV4dF0gPSB0ZXh0RW50cnk7XG4gICAgICAgIGNvbnN0IHRleHRTdHJpbmcgPSBOb2RlLnN0cmluZyh0ZXh0KTtcbiAgICAgICAgY29uc3QgdGV4dEFycmF5ID0gdGV4dFN0cmluZy5zcGxpdCgnXFxuJyk7XG4gICAgICAgIHRleHRBcnJheS5mb3JFYWNoKChzZWdtZW50VGV4dFN0cmluZzogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzZWdtZW50VGV4dCA9IHsgLi4udGV4dCwgdGV4dDogc2VnbWVudFRleHRTdHJpbmcgfTtcbiAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRMaW5lID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgY3VycmVudExpbmUucHVzaChzZWdtZW50VGV4dCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld0xpbmU6IEN1c3RvbVRleHRbXSA9IFtdO1xuICAgICAgICAgICAgICAgIG5ld0xpbmUucHVzaChzZWdtZW50VGV4dCk7XG4gICAgICAgICAgICAgICAgbGluZXMucHVzaChuZXdMaW5lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGxldCB3aWR0aCA9IDA7XG4gICAgbGV0IGhlaWdodCA9IDA7XG4gICAgbGluZXMuZm9yRWFjaCgobGluZVRleHRzOiBDdXN0b21UZXh0W10sIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGxpbmVXaWR0aCA9IDA7XG4gICAgICAgIGxldCBtYXhMaW5lSGVpZ2h0ID0gZ2V0TGluZUhlaWdodEJ5Rm9udFNpemUob3B0aW9ucy5mb250U2l6ZSk7XG4gICAgICAgIGxpbmVUZXh0cy5mb3JFYWNoKCh0ZXh0OiBDdXN0b21UZXh0LCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmb250ID0gZ2V0Rm9udCh0ZXh0LCB7IGZvbnRGYW1pbHk6IG9wdGlvbnMuZm9udEZhbWlseSwgZm9udFNpemU6IG9wdGlvbnMuZm9udFNpemUgfSk7XG4gICAgICAgICAgICBjdHguZm9udCA9IGZvbnQ7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIFdpbmRvd3Mg5bmz5Y+w5LiL55qE54m55q6K5aSE55CGXG4gICAgICAgICAgICBpZiAoSVNfV0lORE9XUykge1xuICAgICAgICAgICAgICAgIGxldCBhZGp1c3RlZFdpZHRoID0gMDtcbiAgICAgICAgICAgICAgICAvLyDpgJDlrZfnrKblpITnkIZcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHQudGV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyID0gdGV4dC50ZXh0W2ldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyTWV0cmljcyA9IGN0eC5tZWFzdXJlVGV4dChjaGFyKTtcbiAgICAgICAgICAgICAgICAgICAgLy8g5Yik5pat5piv5ZCm5Li65rGJ5a2X77yI6YCa6L+HIFVuaWNvZGUg6IyD5Zu077yJXG4gICAgICAgICAgICAgICAgICAgIGlmICgvW1xcdTRlMDAtXFx1OWZhNV0vLnRlc3QoY2hhcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkanVzdGVkV2lkdGggKz0gY2hhck1ldHJpY3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDpnZ7msYnlrZflrZfnrKbnmoTlrr3luqbosIPmlbRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgvW2EtekEtWl0vLnRlc3QoY2hhcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGp1c3RlZFdpZHRoICs9IGNoYXJNZXRyaWNzLndpZHRoICsgMS41OyAvLyDlrZfmr41cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoL1swLTldLy50ZXN0KGNoYXIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRqdXN0ZWRXaWR0aCArPSBjaGFyTWV0cmljcy53aWR0aCArIDEuNTsgLy8g5pWw5a2XXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkanVzdGVkV2lkdGggKz0gY2hhck1ldHJpY3Mud2lkdGggKyAwLjg7IC8vIOWFtuS7luespuWPt1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aCArPSBhZGp1c3RlZFdpZHRoO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGggKz0gY3R4Lm1lYXN1cmVUZXh0KHRleHQudGV4dCkud2lkdGg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlzTGFzdCA9IGluZGV4ID09PSBsaW5lVGV4dHMubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIC8vIHNraXAgd2hlbiB0ZXh0IGlzIGVtcHR5IGFuZCBpcyBub3QgbGFzdCB0ZXh0IG9mIGxpbmVcbiAgICAgICAgICAgIGlmICh0ZXh0Wydmb250LXNpemUnXSAmJiAoaXNMYXN0IHx8IHRleHQudGV4dCAhPT0gJycpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbGluZUhlaWdodCA9IGdldExpbmVIZWlnaHRCeUZvbnRTaXplKHBhcnNlRmxvYXQodGV4dFsnZm9udC1zaXplJ10pKTtcbiAgICAgICAgICAgICAgICBpZiAobGluZUhlaWdodCA+IG1heExpbmVIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF4TGluZUhlaWdodCA9IGxpbmVIZWlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGxpbmVXaWR0aCA8PSBjb250YWluZXJNYXhXaWR0aCkge1xuICAgICAgICAgICAgaWYgKGxpbmVXaWR0aCA+IHdpZHRoKSB7XG4gICAgICAgICAgICAgICAgd2lkdGggPSBsaW5lV2lkdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoZWlnaHQgKz0gbWF4TGluZUhlaWdodDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdpZHRoID0gY29udGFpbmVyTWF4V2lkdGg7XG4gICAgICAgICAgICBjb25zdCBsaW5lV3JhcE51bWJlciA9IE1hdGguY2VpbChsaW5lV2lkdGggLyBjb250YWluZXJNYXhXaWR0aCk7XG4gICAgICAgICAgICBoZWlnaHQgKz0gbWF4TGluZUhlaWdodCAqIGxpbmVXcmFwTnVtYmVyO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCB9O1xufVxuXG5jb25zdCBnZXRGb250ID0gKFxuICAgIHRleHQ6IEN1c3RvbVRleHQsXG4gICAgb3B0aW9uczoge1xuICAgICAgICBmb250U2l6ZTogbnVtYmVyO1xuICAgICAgICBmb250RmFtaWx5OiBzdHJpbmc7XG4gICAgfVxuKSA9PiB7XG4gICAgcmV0dXJuIGAke3RleHQuaXRhbGljID8gJ2l0YWxpYyAnIDogJyd9ICR7dGV4dC5ib2xkID8gJ2JvbGQgJyA6ICcnfSAke3RleHRbJ2ZvbnQtc2l6ZSddIHx8IG9wdGlvbnMuZm9udFNpemV9cHggJHtvcHRpb25zLmZvbnRGYW1pbHl9IGA7XG59O1xuIl19
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlaitGroupElement, getSelectionAngle, getElementsInGroup, setAngleForG,
|
|
1
|
+
import { RectangleClient, toActiveRectangleFromViewBoxRectangle, PlaitGroupElement, getSelectionAngle, getElementsInGroup, setAngleForG, drawCircle, PlaitBoard, RESIZE_HANDLE_CLASS_NAME, DEFAULT_COLOR, createG, setStrokeLinecap, drawRectangle, ACTIVE_STROKE_WIDTH, SELECTION_RECTANGLE_CLASS_NAME, ResizeCursorClass, RESIZE_CURSORS, setDragging, rotatePoints, isSelectionMoving, getSelectedElements, distanceBetweenPointAndPoint, Point, Direction, hotkeys, PlaitElement, createDebugGenerator, idCreator, Transforms, createForeignObject, updateForeignObject, getHighestSelectedElements, getRectangleByElements, MERGING, PlaitPointerType, isMainPointer, toViewBoxPoint, toHostPoint, PRESS_AND_MOVE_BUFFER, isDragging, throttleRAF, getRectangleByGroup, ElementFlavour, isSelectedElementOrGroup, Selection, isMovingElements, getHitElementsBySelection, createGroupRectangleG, getSelectedGroups, getHighestSelectedGroups, getSelectedIsolatedElements, getSelectedIsolatedElementsCanAddToGroup, getGroupByElement, IS_WINDOWS, updateForeignObjectWidth, IS_TEXT_EDITABLE } from '@plait/core';
|
|
2
2
|
import { isKeyHotkey } from 'is-hotkey';
|
|
3
3
|
import { Node, Operation, Transforms as Transforms$1, Range, Editor } from 'slate';
|
|
4
4
|
import { fromEvent, timer } from 'rxjs';
|
|
@@ -65,18 +65,24 @@ class Generator {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
this.g = g;
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
const rectangle = this.board.getRectangle(element);
|
|
69
|
+
if (!rectangle) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
let centerPoint = RectangleClient.getCenterPoint(rectangle);
|
|
73
|
+
if (this.options?.active) {
|
|
74
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(this.board, rectangle);
|
|
75
|
+
centerPoint = RectangleClient.getCenterPoint(activeRectangle);
|
|
76
|
+
}
|
|
77
|
+
let angle;
|
|
78
|
+
if (PlaitGroupElement.isGroup(element)) {
|
|
79
|
+
angle = getSelectionAngle(getElementsInGroup(this.board, element, true));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
angle = element.angle;
|
|
83
|
+
}
|
|
84
|
+
if (angle) {
|
|
85
|
+
setAngleForG(g, centerPoint, angle);
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
else {
|
|
@@ -147,10 +153,13 @@ const drawRotateHandle = (board, rectangle) => {
|
|
|
147
153
|
return handleG;
|
|
148
154
|
};
|
|
149
155
|
|
|
156
|
+
const createActiveGenerator = (board, options) => {
|
|
157
|
+
return new ActiveGenerator(board, { ...options, active: true });
|
|
158
|
+
};
|
|
150
159
|
class ActiveGenerator extends Generator {
|
|
151
160
|
static { this.key = 'active-generator'; }
|
|
152
161
|
constructor(board, options) {
|
|
153
|
-
super(board, options);
|
|
162
|
+
super(board, { ...options, active: true });
|
|
154
163
|
this.board = board;
|
|
155
164
|
this.options = options;
|
|
156
165
|
this.hasResizeHandle = false;
|
|
@@ -165,12 +174,12 @@ class ActiveGenerator extends Generator {
|
|
|
165
174
|
}
|
|
166
175
|
draw(element, data) {
|
|
167
176
|
const activeG = createG();
|
|
168
|
-
const
|
|
169
|
-
const delta = this.options.getStrokeWidth();
|
|
170
|
-
const
|
|
171
|
-
const strokeG = drawRectangle(this.board,
|
|
177
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(this.board, this.options.getRectangle(element));
|
|
178
|
+
const delta = this.options.getStrokeWidth() * this.board.viewport.zoom;
|
|
179
|
+
const activeRectangleWithDelta = RectangleClient.inflate(activeRectangle, delta);
|
|
180
|
+
const strokeG = drawRectangle(this.board, activeRectangleWithDelta, {
|
|
172
181
|
stroke: PRIMARY_COLOR,
|
|
173
|
-
strokeWidth:
|
|
182
|
+
strokeWidth: ACTIVE_STROKE_WIDTH
|
|
174
183
|
});
|
|
175
184
|
activeG.append(strokeG);
|
|
176
185
|
strokeG.classList.add(SELECTION_RECTANGLE_CLASS_NAME);
|
|
@@ -178,7 +187,7 @@ class ActiveGenerator extends Generator {
|
|
|
178
187
|
if (this.options.hasResizeHandle()) {
|
|
179
188
|
this.hasResizeHandle = true;
|
|
180
189
|
// draw resize handle
|
|
181
|
-
RectangleClient.getCornerPoints(
|
|
190
|
+
RectangleClient.getCornerPoints(activeRectangleWithDelta).forEach((corner) => {
|
|
182
191
|
const cornerHandleG = drawHandle(this.board, corner);
|
|
183
192
|
activeG.append(cornerHandleG);
|
|
184
193
|
});
|
|
@@ -1362,7 +1371,7 @@ class ImageGenerator extends Generator {
|
|
|
1362
1371
|
}
|
|
1363
1372
|
};
|
|
1364
1373
|
this.imageComponentRef = this.board.renderImage(this.foreignObject, props);
|
|
1365
|
-
this.activeGenerator =
|
|
1374
|
+
this.activeGenerator = createActiveGenerator(this.board, {
|
|
1366
1375
|
getStrokeWidth: () => {
|
|
1367
1376
|
const selectedElements = getSelectedElements(this.board);
|
|
1368
1377
|
if (!(selectedElements.length === 1 && !isSelectionMoving(this.board))) {
|
|
@@ -1409,12 +1418,12 @@ class ImageGenerator extends Generator {
|
|
|
1409
1418
|
if (currentForeignObject && current.angle) {
|
|
1410
1419
|
setAngleForG(this.g, RectangleClient.getCenterPoint(currentForeignObject), current.angle);
|
|
1411
1420
|
}
|
|
1412
|
-
const activeG = PlaitBoard.
|
|
1421
|
+
const activeG = PlaitBoard.getActiveHost(this.board);
|
|
1413
1422
|
this.activeGenerator.processDrawing(current, activeG, { selected: this.isFocus });
|
|
1414
1423
|
}
|
|
1415
1424
|
setFocus(element, isFocus) {
|
|
1416
1425
|
this.isFocus = isFocus;
|
|
1417
|
-
const activeG = PlaitBoard.
|
|
1426
|
+
const activeG = PlaitBoard.getActiveHost(this.board);
|
|
1418
1427
|
this.activeGenerator.processDrawing(element, activeG, { selected: isFocus });
|
|
1419
1428
|
const props = {
|
|
1420
1429
|
isFocus
|
|
@@ -1727,6 +1736,7 @@ class PlaitCommonElementRef {
|
|
|
1727
1736
|
constructor() {
|
|
1728
1737
|
this.textManages = [];
|
|
1729
1738
|
this.generatorMap = new Map();
|
|
1739
|
+
this.updateActiveSection = () => { };
|
|
1730
1740
|
}
|
|
1731
1741
|
addGenerator(key, generator) {
|
|
1732
1742
|
this.generatorMap.set(key, generator);
|
|
@@ -1747,7 +1757,7 @@ class PlaitCommonElementRef {
|
|
|
1747
1757
|
return this.textManages;
|
|
1748
1758
|
}
|
|
1749
1759
|
destroyTextManage() {
|
|
1750
|
-
this.textManages.forEach(textManage => {
|
|
1760
|
+
this.textManages.forEach((textManage) => {
|
|
1751
1761
|
textManage.destroy();
|
|
1752
1762
|
});
|
|
1753
1763
|
this.textManages = [];
|
|
@@ -1765,7 +1775,7 @@ class GroupComponent extends CommonElementFlavour {
|
|
|
1765
1775
|
super();
|
|
1766
1776
|
}
|
|
1767
1777
|
initializeGenerator() {
|
|
1768
|
-
this.activeGenerator =
|
|
1778
|
+
this.activeGenerator = createActiveGenerator(this.board, {
|
|
1769
1779
|
getRectangle: (element) => {
|
|
1770
1780
|
return getRectangleByGroup(this.board, element);
|
|
1771
1781
|
},
|
|
@@ -1818,7 +1828,7 @@ function withGroup(board) {
|
|
|
1818
1828
|
const hitElements = getHitElementsBySelection(board, selection);
|
|
1819
1829
|
if (hitElements.length) {
|
|
1820
1830
|
groupRectangleG = createGroupRectangleG(board, hitElements);
|
|
1821
|
-
groupRectangleG && PlaitBoard.
|
|
1831
|
+
groupRectangleG && PlaitBoard.getElementTopHost(board).append(groupRectangleG);
|
|
1822
1832
|
}
|
|
1823
1833
|
}
|
|
1824
1834
|
});
|
|
@@ -1839,13 +1849,13 @@ function withGroup(board) {
|
|
|
1839
1849
|
elements = new Array(clipboardData?.elements?.length);
|
|
1840
1850
|
const groups = getHighestSelectedGroups(board, clipboardData?.elements);
|
|
1841
1851
|
const selectedIsolatedElements = getSelectedIsolatedElements(board, clipboardData?.elements);
|
|
1842
|
-
selectedIsolatedElements.forEach(item => {
|
|
1843
|
-
const index = clipboardData.elements.map(element => element.id).indexOf(item.id);
|
|
1852
|
+
selectedIsolatedElements.forEach((item) => {
|
|
1853
|
+
const index = clipboardData.elements.map((element) => element.id).indexOf(item.id);
|
|
1844
1854
|
elements.splice(index, 1, !item.groupId ? item : updateGroupId(item, undefined));
|
|
1845
1855
|
});
|
|
1846
1856
|
if (groups.length) {
|
|
1847
|
-
groups.forEach(item => {
|
|
1848
|
-
const index = clipboardData.elements.map(element => element.id).indexOf(item.id);
|
|
1857
|
+
groups.forEach((item) => {
|
|
1858
|
+
const index = clipboardData.elements.map((element) => element.id).indexOf(item.id);
|
|
1849
1859
|
const newGroup = { ...updateGroupId(item, undefined), id: idCreator() };
|
|
1850
1860
|
elements.splice(index, 1, newGroup);
|
|
1851
1861
|
updateElementsGroupId(item, clipboardData.elements, newGroup.id, elements);
|
|
@@ -1854,8 +1864,8 @@ function withGroup(board) {
|
|
|
1854
1864
|
clipboardData.elements = elements;
|
|
1855
1865
|
}
|
|
1856
1866
|
insertFragment(clipboardData, targetPoint, operationType);
|
|
1857
|
-
const groupElements = elements?.filter(value => PlaitGroupElement.isGroup(value));
|
|
1858
|
-
groupElements.forEach(element => {
|
|
1867
|
+
const groupElements = elements?.filter((value) => PlaitGroupElement.isGroup(value));
|
|
1868
|
+
groupElements.forEach((element) => {
|
|
1859
1869
|
Transforms.insertNode(board, element, [board.children.length]);
|
|
1860
1870
|
});
|
|
1861
1871
|
};
|
|
@@ -1903,10 +1913,10 @@ const updateGroupId = (element, groupId) => {
|
|
|
1903
1913
|
};
|
|
1904
1914
|
};
|
|
1905
1915
|
const updateElementsGroupId = (group, clipboardDataElements, newGroupId, elements) => {
|
|
1906
|
-
const elementsInGroup = clipboardDataElements.filter(item => item.groupId === group.id);
|
|
1916
|
+
const elementsInGroup = clipboardDataElements.filter((item) => item.groupId === group.id);
|
|
1907
1917
|
if (elementsInGroup.length) {
|
|
1908
|
-
elementsInGroup.forEach(item => {
|
|
1909
|
-
const index = clipboardDataElements.map(item => item.id).indexOf(item.id);
|
|
1918
|
+
elementsInGroup.forEach((item) => {
|
|
1919
|
+
const index = clipboardDataElements.map((item) => item.id).indexOf(item.id);
|
|
1910
1920
|
if (PlaitGroupElement.isGroup(item)) {
|
|
1911
1921
|
const newGroup = { ...updateGroupId(item, newGroupId), id: idCreator() };
|
|
1912
1922
|
elements.splice(index, 1, newGroup);
|
|
@@ -1925,11 +1935,11 @@ const getRemoveGroups = (board) => {
|
|
|
1925
1935
|
const highestSelectedGroups = getHighestSelectedGroups(board);
|
|
1926
1936
|
const selectedIsolatedElements = getSelectedIsolatedElementsCanAddToGroup(board);
|
|
1927
1937
|
const removeNodes = [...highestSelectedGroups, ...selectedIsolatedElements];
|
|
1928
|
-
removeNodes.forEach(item => {
|
|
1938
|
+
removeNodes.forEach((item) => {
|
|
1929
1939
|
const hitElementGroups = getGroupByElement(board, item, true);
|
|
1930
1940
|
if (hitElementGroups.length) {
|
|
1931
1941
|
const elementsInGroup = getElementsInGroup(board, hitElementGroups[0], false, true);
|
|
1932
|
-
const siblingElements = elementsInGroup.filter(element => ![...removeNodes, ...removeGroups].map(item => item.id).includes(element.id));
|
|
1942
|
+
const siblingElements = elementsInGroup.filter((element) => ![...removeNodes, ...removeGroups].map((item) => item.id).includes(element.id));
|
|
1933
1943
|
if (siblingElements.length === 1 || siblingElements.length === 0) {
|
|
1934
1944
|
if (!removeGroups.includes(hitElementGroups[0])) {
|
|
1935
1945
|
removeGroups.push(hitElementGroups[0]);
|
|
@@ -1942,9 +1952,9 @@ const getRemoveGroups = (board) => {
|
|
|
1942
1952
|
]);
|
|
1943
1953
|
let index = hitElementGroups.length;
|
|
1944
1954
|
if (aboveGroup) {
|
|
1945
|
-
index = hitElementGroups.findIndex(item => item.id === aboveGroup.id);
|
|
1955
|
+
index = hitElementGroups.findIndex((item) => item.id === aboveGroup.id);
|
|
1946
1956
|
}
|
|
1947
|
-
[...hitElementGroups.slice(1, index)].forEach(item => {
|
|
1957
|
+
[...hitElementGroups.slice(1, index)].forEach((item) => {
|
|
1948
1958
|
if (!removeGroups.includes(item)) {
|
|
1949
1959
|
removeGroups.push(item);
|
|
1950
1960
|
}
|
|
@@ -1960,7 +1970,7 @@ const findAboveGroupWithAnotherElement = (board, groups, excludeNodes) => {
|
|
|
1960
1970
|
let group = null;
|
|
1961
1971
|
for (let i = 0; i < groups.length; i++) {
|
|
1962
1972
|
const elementsInGroup = getElementsInGroup(board, groups[i], false, true);
|
|
1963
|
-
const siblingElements = elementsInGroup.filter(element => !excludeNodes.map(item => item.id).includes(element.id));
|
|
1973
|
+
const siblingElements = elementsInGroup.filter((element) => !excludeNodes.map((item) => item.id).includes(element.id));
|
|
1964
1974
|
if (siblingElements.length > 0) {
|
|
1965
1975
|
group = groups[i];
|
|
1966
1976
|
break;
|
|
@@ -1971,16 +1981,16 @@ const findAboveGroupWithAnotherElement = (board, groups, excludeNodes) => {
|
|
|
1971
1981
|
const updateSiblingElementGroupId = (board, removeGroups) => {
|
|
1972
1982
|
const selectedIsolatedElements = getSelectedIsolatedElementsCanAddToGroup(board);
|
|
1973
1983
|
const highestSelectedGroups = getHighestSelectedGroups(board);
|
|
1974
|
-
const isolatedElementsInGroup = selectedIsolatedElements.filter(item => item.groupId);
|
|
1975
|
-
[...highestSelectedGroups, ...isolatedElementsInGroup].forEach(item => {
|
|
1984
|
+
const isolatedElementsInGroup = selectedIsolatedElements.filter((item) => item.groupId);
|
|
1985
|
+
[...highestSelectedGroups, ...isolatedElementsInGroup].forEach((item) => {
|
|
1976
1986
|
const hitElementGroups = getGroupByElement(board, item, true);
|
|
1977
1987
|
if (hitElementGroups.length) {
|
|
1978
1988
|
const elementsInGroup = getElementsInGroup(board, hitElementGroups[0], false, true);
|
|
1979
|
-
const siblingElements = elementsInGroup.filter(element => element.id !== item.id);
|
|
1989
|
+
const siblingElements = elementsInGroup.filter((element) => element.id !== item.id);
|
|
1980
1990
|
if (siblingElements.length === 1) {
|
|
1981
|
-
const removeGroupIds = removeGroups.map(item => item.id);
|
|
1982
|
-
if (hitElementGroups.some(group => removeGroupIds.includes(group.id))) {
|
|
1983
|
-
const group = hitElementGroups.find(group => !removeGroupIds.includes(group.id));
|
|
1991
|
+
const removeGroupIds = removeGroups.map((item) => item.id);
|
|
1992
|
+
if (hitElementGroups.some((group) => removeGroupIds.includes(group.id))) {
|
|
1993
|
+
const group = hitElementGroups.find((group) => !removeGroupIds.includes(group.id));
|
|
1984
1994
|
const path = PlaitBoard.findPath(board, siblingElements[0]);
|
|
1985
1995
|
Transforms.setNode(board, { groupId: group?.id || undefined }, path);
|
|
1986
1996
|
}
|
|
@@ -2028,8 +2038,35 @@ function measureElement(element, options, containerMaxWidth = 10000) {
|
|
|
2028
2038
|
lineTexts.forEach((text, index) => {
|
|
2029
2039
|
const font = getFont(text, { fontFamily: options.fontFamily, fontSize: options.fontSize });
|
|
2030
2040
|
ctx.font = font;
|
|
2031
|
-
|
|
2032
|
-
|
|
2041
|
+
// Windows 平台下的特殊处理
|
|
2042
|
+
if (IS_WINDOWS) {
|
|
2043
|
+
let adjustedWidth = 0;
|
|
2044
|
+
// 逐字符处理
|
|
2045
|
+
for (let i = 0; i < text.text.length; i++) {
|
|
2046
|
+
const char = text.text[i];
|
|
2047
|
+
const charMetrics = ctx.measureText(char);
|
|
2048
|
+
// 判断是否为汉字(通过 Unicode 范围)
|
|
2049
|
+
if (/[\u4e00-\u9fa5]/.test(char)) {
|
|
2050
|
+
adjustedWidth += charMetrics.width;
|
|
2051
|
+
}
|
|
2052
|
+
else {
|
|
2053
|
+
// 非汉字字符的宽度调整
|
|
2054
|
+
if (/[a-zA-Z]/.test(char)) {
|
|
2055
|
+
adjustedWidth += charMetrics.width + 1.5; // 字母
|
|
2056
|
+
}
|
|
2057
|
+
else if (/[0-9]/.test(char)) {
|
|
2058
|
+
adjustedWidth += charMetrics.width + 1.5; // 数字
|
|
2059
|
+
}
|
|
2060
|
+
else {
|
|
2061
|
+
adjustedWidth += charMetrics.width + 0.8; // 其他符号
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
lineWidth += adjustedWidth;
|
|
2066
|
+
}
|
|
2067
|
+
else {
|
|
2068
|
+
lineWidth += ctx.measureText(text.text).width;
|
|
2069
|
+
}
|
|
2033
2070
|
const isLast = index === lineTexts.length - 1;
|
|
2034
2071
|
// skip when text is empty and is not last text of line
|
|
2035
2072
|
if (text['font-size'] && (isLast || text.text !== '')) {
|
|
@@ -2231,5 +2268,5 @@ const withImage = (board) => {
|
|
|
2231
2268
|
* Generated bundle index. Do not edit.
|
|
2232
2269
|
*/
|
|
2233
2270
|
|
|
2234
|
-
export { AStar, ActiveGenerator, AlignTransform, Alignment, BASE, BoardCreationMode, CommonElementFlavour, DEFAULT_FILL, DEFAULT_FONT_FAMILY, DEFAULT_ROUTE_MARGIN, FOREIGN_OBJECT_IMAGE_CLASS_NAME, Generator, GroupComponent, IS_RESIZING, IS_ROTATING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PlaitCommonElementRef, PointGraph, PointNode, PriorityQueue, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, ResizeHandle, StrokeStyle, TRANSPARENT, TextManage, WithCommonPluginKey, WithTextPluginKey, acceptImageTypes, addElementOfFocusedImage, addResizing, addRotating, alignBottom, alignHorizontalCenter, alignLeft, alignRight, alignTop, alignVerticalCenter, animate, buildClipboardData, buildCompositionData, buildImage, buildText, calculatePolylineLength, createGraph, distributeHorizontal, distributeVertical, drawFillPrimaryHandle, drawHandle, drawPrimaryHandle, drawRotateHandle, findFirstTextEditor, generateElbowLineRoute, getCreationMode, getCrossingPointsBetweenPointAndSegment, getDirectionBetweenPointAndPoint, getDirectionByPointOfRectangle, getDirectionByVector, getDirectionFactor, getDirectionFactorByDirectionComponent, getEditingTextEditor, getElementArea, getElementOfFocusedImage, getElementsText, getExtendPoint, getFirstTextEditor, getFirstTextManage, getGraphPoints, getIndexByResizeHandle, getLineHeightByFontSize, getMemorizedLatest, getNextPoint, getOppositeDirection, getPointByVectorComponent, getPointByVectorDirectionComponent, getPointOnPolyline, getPoints, getRatioByPoint, getRectangleResizeHandleRefs, getResizeHandleByIndex, getResizeHandlePointByIndex, getRotatedResizeCursorClassByAngle, getSourceAndTargetOuterRectangle, getStrokeLineDash, getSymmetricHandleIndex, getTextEditors, getTextEditorsByElement, getTextManages, getTimestamp, getUnitVectorByPointAndPoint, hasAfterDraw, hasMoreThanOnePoint, hasResizeHandle, insertClipboardData, isCornerHandle, isDelete, isDndMode, isDrawingMode, isEdgeHandle, isEnterHotkey, isExpandHotkey, isFilled, isPointOnSegment, isResizing, isResizingByCondition, isRotating, isSourceAndTargetIntersect, isSpaceHotkey, isTabHotkey, isVirtualKey, linear, measureElement, memorizeLatest, normalizeShapePoints, reduceRouteMargin, removeDuplicatePoints, removeElementOfFocusedImage, removeResizing, removeRotating, resetPointsAfterResize, rotateVector, rotateVectorAnti90, routeAdjust, selectImage, setCreationMode, setProperty, simplifyOrthogonalPoints, sortElementsByArea, withGroup, withImage, withResize, withText };
|
|
2271
|
+
export { AStar, ActiveGenerator, AlignTransform, Alignment, BASE, BoardCreationMode, CommonElementFlavour, DEFAULT_FILL, DEFAULT_FONT_FAMILY, DEFAULT_ROUTE_MARGIN, FOREIGN_OBJECT_IMAGE_CLASS_NAME, Generator, GroupComponent, IS_RESIZING, IS_ROTATING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PlaitCommonElementRef, PointGraph, PointNode, PriorityQueue, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, ResizeHandle, StrokeStyle, TRANSPARENT, TextManage, WithCommonPluginKey, WithTextPluginKey, acceptImageTypes, addElementOfFocusedImage, addResizing, addRotating, alignBottom, alignHorizontalCenter, alignLeft, alignRight, alignTop, alignVerticalCenter, animate, buildClipboardData, buildCompositionData, buildImage, buildText, calculatePolylineLength, createActiveGenerator, createGraph, distributeHorizontal, distributeVertical, drawFillPrimaryHandle, drawHandle, drawPrimaryHandle, drawRotateHandle, findFirstTextEditor, generateElbowLineRoute, getCreationMode, getCrossingPointsBetweenPointAndSegment, getDirectionBetweenPointAndPoint, getDirectionByPointOfRectangle, getDirectionByVector, getDirectionFactor, getDirectionFactorByDirectionComponent, getEditingTextEditor, getElementArea, getElementOfFocusedImage, getElementsText, getExtendPoint, getFirstTextEditor, getFirstTextManage, getGraphPoints, getIndexByResizeHandle, getLineHeightByFontSize, getMemorizedLatest, getNextPoint, getOppositeDirection, getPointByVectorComponent, getPointByVectorDirectionComponent, getPointOnPolyline, getPoints, getRatioByPoint, getRectangleResizeHandleRefs, getResizeHandleByIndex, getResizeHandlePointByIndex, getRotatedResizeCursorClassByAngle, getSourceAndTargetOuterRectangle, getStrokeLineDash, getSymmetricHandleIndex, getTextEditors, getTextEditorsByElement, getTextManages, getTimestamp, getUnitVectorByPointAndPoint, hasAfterDraw, hasMoreThanOnePoint, hasResizeHandle, insertClipboardData, isCornerHandle, isDelete, isDndMode, isDrawingMode, isEdgeHandle, isEnterHotkey, isExpandHotkey, isFilled, isPointOnSegment, isResizing, isResizingByCondition, isRotating, isSourceAndTargetIntersect, isSpaceHotkey, isTabHotkey, isVirtualKey, linear, measureElement, memorizeLatest, normalizeShapePoints, reduceRouteMargin, removeDuplicatePoints, removeElementOfFocusedImage, removeResizing, removeRotating, resetPointsAfterResize, rotateVector, rotateVectorAnti90, routeAdjust, selectImage, setCreationMode, setProperty, simplifyOrthogonalPoints, sortElementsByArea, withGroup, withImage, withResize, withText };
|
|
2235
2272
|
//# sourceMappingURL=plait-common.mjs.map
|