@idraw/util 0.4.0-beta.1 → 0.4.0-beta.10
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/esm/index.d.ts +7 -5
- package/dist/esm/index.js +7 -5
- package/dist/esm/lib/canvas.d.ts +8 -3
- package/dist/esm/lib/canvas.js +27 -4
- package/dist/esm/lib/config.d.ts +5 -10
- package/dist/esm/lib/config.js +7 -8
- package/dist/esm/lib/context2d.d.ts +1 -0
- package/dist/esm/lib/context2d.js +3 -0
- package/dist/esm/lib/controller.js +28 -0
- package/dist/esm/lib/data.d.ts +6 -2
- package/dist/esm/lib/data.js +90 -1
- package/dist/esm/lib/element.d.ts +2 -0
- package/dist/esm/lib/element.js +75 -1
- package/dist/esm/lib/event.d.ts +3 -2
- package/dist/esm/lib/event.js +28 -11
- package/dist/esm/lib/file.d.ts +7 -2
- package/dist/esm/lib/file.js +26 -7
- package/dist/esm/lib/handle-element.js +34 -31
- package/dist/esm/lib/resize-element.d.ts +2 -0
- package/dist/esm/lib/resize-element.js +101 -0
- package/dist/esm/lib/store.d.ts +3 -4
- package/dist/esm/lib/store.js +26 -8
- package/dist/esm/lib/time.d.ts +1 -0
- package/dist/esm/lib/time.js +13 -1
- package/dist/esm/lib/view-box.js +3 -2
- package/dist/esm/lib/view-content.d.ts +10 -0
- package/dist/esm/lib/view-content.js +53 -0
- package/dist/index.global.js +487 -72
- package/dist/index.global.min.js +1 -1
- package/package.json +1 -1
package/dist/esm/lib/file.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
export function downloadImageFromCanvas(canvas, opts) {
|
|
2
|
-
const {
|
|
2
|
+
const { fileName, type = 'image/jpeg' } = opts;
|
|
3
3
|
const stream = canvas.toDataURL(type);
|
|
4
|
-
|
|
4
|
+
let downloadLink = document.createElement('a');
|
|
5
5
|
downloadLink.href = stream;
|
|
6
|
-
downloadLink.download =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
downloadLink.dispatchEvent(downloadClickEvent);
|
|
6
|
+
downloadLink.download = fileName;
|
|
7
|
+
downloadLink.click();
|
|
8
|
+
downloadLink = null;
|
|
10
9
|
}
|
|
11
10
|
export function pickFile(opts) {
|
|
12
|
-
const { success, error } = opts;
|
|
11
|
+
const { accept, success, error } = opts;
|
|
13
12
|
let input = document.createElement('input');
|
|
14
13
|
input.type = 'file';
|
|
14
|
+
if (accept) {
|
|
15
|
+
input.accept = accept;
|
|
16
|
+
}
|
|
15
17
|
input.addEventListener('change', function () {
|
|
16
18
|
var _a;
|
|
17
19
|
const file = (_a = input.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
@@ -64,3 +66,20 @@ export function parseFileToText(file) {
|
|
|
64
66
|
reader.readAsText(file);
|
|
65
67
|
});
|
|
66
68
|
}
|
|
69
|
+
export function parseTextToBlobURL(text) {
|
|
70
|
+
const bytes = new TextEncoder().encode(text);
|
|
71
|
+
const blob = new Blob([bytes], {
|
|
72
|
+
type: 'text/plain;charset=utf-8'
|
|
73
|
+
});
|
|
74
|
+
const blobURL = window.URL.createObjectURL(blob);
|
|
75
|
+
return blobURL;
|
|
76
|
+
}
|
|
77
|
+
export function downloadFileFromText(text, opts) {
|
|
78
|
+
const { fileName } = opts;
|
|
79
|
+
const blobURL = parseTextToBlobURL(text);
|
|
80
|
+
let downloadLink = document.createElement('a');
|
|
81
|
+
downloadLink.href = blobURL;
|
|
82
|
+
downloadLink.download = fileName;
|
|
83
|
+
downloadLink.click();
|
|
84
|
+
downloadLink = null;
|
|
85
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createUUID } from './uuid';
|
|
2
|
-
import {
|
|
2
|
+
import { defaultText, getDefaultElementRectDetail, getDefaultElementCircleDetail, getDefaultElementTextDetail, getDefaultElementSVGDetail, getDefaultElementImageDetail, getDefaultElementGroupDetail } from './config';
|
|
3
3
|
import { istype } from './istype';
|
|
4
4
|
import { findElementFromListByPosition, getElementPositionFromList } from './element';
|
|
5
|
+
import { deepResizeGroupElement } from './resize-element';
|
|
5
6
|
const defaultViewWidth = 200;
|
|
6
7
|
const defaultViewHeight = 200;
|
|
7
|
-
const defaultDetail = getDefaultElementDetailConfig();
|
|
8
8
|
function createElementSize(type, opts) {
|
|
9
9
|
let x = 0;
|
|
10
10
|
let y = 0;
|
|
@@ -14,29 +14,26 @@ function createElementSize(type, opts) {
|
|
|
14
14
|
const { viewScaleInfo, viewSizeInfo } = opts;
|
|
15
15
|
const { scale, offsetLeft, offsetTop } = viewScaleInfo;
|
|
16
16
|
const { width, height } = viewSizeInfo;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const limitViewWidth = width / 4;
|
|
18
|
+
const limitViewHeight = height / 4;
|
|
19
|
+
if (defaultViewWidth >= limitViewWidth) {
|
|
20
|
+
w = limitViewWidth / scale;
|
|
21
21
|
}
|
|
22
22
|
else {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (['circle', 'svg', 'image'].includes(type)) {
|
|
38
|
-
w = h = Math.max(w, h);
|
|
39
|
-
}
|
|
23
|
+
w = defaultViewWidth / scale;
|
|
24
|
+
}
|
|
25
|
+
if (defaultViewHeight >= limitViewHeight) {
|
|
26
|
+
h = limitViewHeight / scale;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
h = defaultViewHeight / scale;
|
|
30
|
+
}
|
|
31
|
+
if (['circle', 'svg', 'image'].includes(type)) {
|
|
32
|
+
w = h = Math.max(w, h);
|
|
33
|
+
}
|
|
34
|
+
else if (type === 'text') {
|
|
35
|
+
const fontSize = w / defaultText.length;
|
|
36
|
+
h = fontSize * 2;
|
|
40
37
|
}
|
|
41
38
|
x = (0 - offsetLeft + width / 2 - (w * scale) / 2) / scale;
|
|
42
39
|
y = (0 - offsetTop + height / 2 - (h * scale) / 2) / scale;
|
|
@@ -50,18 +47,16 @@ function createElementSize(type, opts) {
|
|
|
50
47
|
return elemSize;
|
|
51
48
|
}
|
|
52
49
|
export function createElement(type, baseElem, opts) {
|
|
53
|
-
const
|
|
50
|
+
const elementSize = createElementSize(type, opts);
|
|
54
51
|
let detail = {};
|
|
55
52
|
if (type === 'rect') {
|
|
56
53
|
detail = getDefaultElementRectDetail();
|
|
57
54
|
}
|
|
58
55
|
else if (type === 'circle') {
|
|
59
|
-
detail = getDefaultElementCircleDetail(
|
|
60
|
-
radius: elemSize.w
|
|
61
|
-
});
|
|
56
|
+
detail = getDefaultElementCircleDetail();
|
|
62
57
|
}
|
|
63
58
|
else if (type === 'text') {
|
|
64
|
-
detail = getDefaultElementTextDetail(
|
|
59
|
+
detail = getDefaultElementTextDetail(elementSize);
|
|
65
60
|
}
|
|
66
61
|
else if (type === 'svg') {
|
|
67
62
|
detail = getDefaultElementSVGDetail();
|
|
@@ -72,7 +67,7 @@ export function createElement(type, baseElem, opts) {
|
|
|
72
67
|
else if (type === 'group') {
|
|
73
68
|
detail = getDefaultElementGroupDetail();
|
|
74
69
|
}
|
|
75
|
-
const elem = Object.assign(Object.assign(Object.assign({},
|
|
70
|
+
const elem = Object.assign(Object.assign(Object.assign({}, elementSize), baseElem), { uuid: createUUID(), type, detail: Object.assign(Object.assign({}, detail), (baseElem.detail || {})) });
|
|
76
71
|
return elem;
|
|
77
72
|
}
|
|
78
73
|
export function insertElementToListByPosition(element, position, list) {
|
|
@@ -209,17 +204,25 @@ function mergeElement(originElem, updateContent) {
|
|
|
209
204
|
return originElem;
|
|
210
205
|
}
|
|
211
206
|
export function updateElementInList(uuid, updateContent, elements) {
|
|
212
|
-
var _a;
|
|
207
|
+
var _a, _b;
|
|
213
208
|
let targetElement = null;
|
|
214
209
|
for (let i = 0; i < elements.length; i++) {
|
|
215
210
|
const elem = elements[i];
|
|
216
211
|
if (elem.uuid === uuid) {
|
|
212
|
+
if (elem.type === 'group' && ((_a = elem.operations) === null || _a === void 0 ? void 0 : _a.deepResize) === true) {
|
|
213
|
+
if ((updateContent.w && updateContent.w > 0) || (updateContent.h && updateContent.h > 0)) {
|
|
214
|
+
deepResizeGroupElement(elem, {
|
|
215
|
+
w: updateContent.w,
|
|
216
|
+
h: updateContent.h
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
217
220
|
mergeElement(elem, updateContent);
|
|
218
221
|
targetElement = elem;
|
|
219
222
|
break;
|
|
220
223
|
}
|
|
221
224
|
else if (elem.type === 'group') {
|
|
222
|
-
targetElement = updateElementInList(uuid, updateContent, ((
|
|
225
|
+
targetElement = updateElementInList(uuid, updateContent, ((_b = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _b === void 0 ? void 0 : _b.children) || []);
|
|
223
226
|
}
|
|
224
227
|
}
|
|
225
228
|
return targetElement;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { formatNumber } from './number';
|
|
2
|
+
const doNum = (n) => {
|
|
3
|
+
return formatNumber(n, { decimalPlaces: 4 });
|
|
4
|
+
};
|
|
5
|
+
function resizeElementBaseDetail(elem, opts) {
|
|
6
|
+
const { detail } = elem;
|
|
7
|
+
const { xRatio, yRatio, maxRatio } = opts;
|
|
8
|
+
const middleRatio = (xRatio + yRatio) / 2;
|
|
9
|
+
const { borderWidth, borderRadius, borderDash, shadowOffsetX, shadowOffsetY, shadowBlur } = detail;
|
|
10
|
+
if (typeof borderWidth === 'number') {
|
|
11
|
+
detail.borderWidth = doNum(borderWidth * middleRatio);
|
|
12
|
+
}
|
|
13
|
+
else if (Array.isArray(detail.borderWidth)) {
|
|
14
|
+
const bw = borderWidth;
|
|
15
|
+
detail.borderWidth = [doNum(bw[0] * yRatio), doNum(bw[1] * xRatio), doNum(bw[2] * yRatio), doNum(bw[3] * xRatio)];
|
|
16
|
+
}
|
|
17
|
+
if (typeof borderRadius === 'number') {
|
|
18
|
+
detail.borderRadius = doNum(borderRadius * middleRatio);
|
|
19
|
+
}
|
|
20
|
+
else if (Array.isArray(detail.borderRadius)) {
|
|
21
|
+
const br = borderRadius;
|
|
22
|
+
detail.borderRadius = [br[0] * xRatio, br[1] * xRatio, br[2] * yRatio, br[3] * yRatio];
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(borderDash)) {
|
|
25
|
+
borderDash.forEach((dash, i) => {
|
|
26
|
+
detail.borderDash[i] = doNum(dash * maxRatio);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (typeof shadowOffsetX === 'number') {
|
|
30
|
+
detail.shadowOffsetX = doNum(shadowOffsetX * maxRatio);
|
|
31
|
+
}
|
|
32
|
+
if (typeof shadowOffsetY === 'number') {
|
|
33
|
+
detail.shadowOffsetX = doNum(shadowOffsetY * maxRatio);
|
|
34
|
+
}
|
|
35
|
+
if (typeof shadowBlur === 'number') {
|
|
36
|
+
detail.shadowOffsetX = doNum(shadowBlur * maxRatio);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function resizeElementBase(elem, opts) {
|
|
40
|
+
const { xRatio, yRatio } = opts;
|
|
41
|
+
const { x, y, w, h } = elem;
|
|
42
|
+
elem.x = doNum(x * xRatio);
|
|
43
|
+
elem.y = doNum(y * yRatio);
|
|
44
|
+
elem.w = doNum(w * xRatio);
|
|
45
|
+
elem.h = doNum(h * yRatio);
|
|
46
|
+
resizeElementBaseDetail(elem, opts);
|
|
47
|
+
}
|
|
48
|
+
function resizeTextElementDetail(elem, opts) {
|
|
49
|
+
const { minRatio, maxRatio } = opts;
|
|
50
|
+
const { fontSize, lineHeight } = elem.detail;
|
|
51
|
+
const ratio = (minRatio + maxRatio) / 2;
|
|
52
|
+
if (fontSize && fontSize > 0) {
|
|
53
|
+
elem.detail.fontSize = doNum(fontSize * ratio);
|
|
54
|
+
}
|
|
55
|
+
if (lineHeight && lineHeight > 0) {
|
|
56
|
+
elem.detail.lineHeight = doNum(lineHeight * ratio);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function resizeElement(elem, opts) {
|
|
60
|
+
const { type } = elem;
|
|
61
|
+
resizeElementBase(elem, opts);
|
|
62
|
+
if (type === 'circle') {
|
|
63
|
+
}
|
|
64
|
+
else if (type === 'text') {
|
|
65
|
+
resizeTextElementDetail(elem, opts);
|
|
66
|
+
}
|
|
67
|
+
else if (type === 'image') {
|
|
68
|
+
}
|
|
69
|
+
else if (type === 'svg') {
|
|
70
|
+
}
|
|
71
|
+
else if (type === 'html') {
|
|
72
|
+
}
|
|
73
|
+
else if (type === 'path') {
|
|
74
|
+
}
|
|
75
|
+
else if (type === 'group' && Array.isArray(elem.detail.children)) {
|
|
76
|
+
elem.detail.children.forEach((child) => {
|
|
77
|
+
resizeElement(child, opts);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function deepResizeGroupElement(elem, size) {
|
|
82
|
+
const resizeW = size.w && size.w > 0 ? size.w : elem.w;
|
|
83
|
+
const resizeH = size.h && size.h > 0 ? size.h : elem.h;
|
|
84
|
+
const xRatio = resizeW / elem.w;
|
|
85
|
+
const yRatio = resizeH / elem.h;
|
|
86
|
+
if (xRatio === yRatio && xRatio === 1) {
|
|
87
|
+
return elem;
|
|
88
|
+
}
|
|
89
|
+
const minRatio = Math.min(xRatio, yRatio);
|
|
90
|
+
const maxRatio = Math.max(xRatio, yRatio);
|
|
91
|
+
elem.w = resizeW;
|
|
92
|
+
elem.h = resizeH;
|
|
93
|
+
const opts = { xRatio, yRatio, minRatio, maxRatio };
|
|
94
|
+
if (elem.type === 'group' && Array.isArray(elem.detail.children)) {
|
|
95
|
+
elem.detail.children.forEach((child) => {
|
|
96
|
+
resizeElement(child, opts);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
resizeElementBaseDetail(elem, opts);
|
|
100
|
+
return elem;
|
|
101
|
+
}
|
package/dist/esm/lib/store.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export declare class Store<T extends Record<string | symbol, any>> {
|
|
2
|
-
private
|
|
3
|
-
private _backUpDefaultStorage;
|
|
1
|
+
export declare class Store<T extends Record<string | symbol, any> = Record<string | symbol, any>> {
|
|
2
|
+
#private;
|
|
4
3
|
constructor(opts: {
|
|
5
4
|
defaultStorage: T;
|
|
6
5
|
});
|
|
@@ -8,5 +7,5 @@ export declare class Store<T extends Record<string | symbol, any>> {
|
|
|
8
7
|
get<K extends keyof T>(name: K): T[K];
|
|
9
8
|
getSnapshot(): T;
|
|
10
9
|
clear(): void;
|
|
11
|
-
|
|
10
|
+
destroy(): void;
|
|
12
11
|
}
|
package/dist/esm/lib/store.js
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _Store_instances, _Store_temp, _Store_backUpDefaultStorage, _Store_createTempStorage;
|
|
1
13
|
import { deepClone } from './data';
|
|
2
14
|
export class Store {
|
|
3
15
|
constructor(opts) {
|
|
4
|
-
|
|
5
|
-
this
|
|
16
|
+
_Store_instances.add(this);
|
|
17
|
+
_Store_temp.set(this, void 0);
|
|
18
|
+
_Store_backUpDefaultStorage.set(this, void 0);
|
|
19
|
+
__classPrivateFieldSet(this, _Store_backUpDefaultStorage, deepClone(opts.defaultStorage), "f");
|
|
20
|
+
__classPrivateFieldSet(this, _Store_temp, __classPrivateFieldGet(this, _Store_instances, "m", _Store_createTempStorage).call(this), "f");
|
|
6
21
|
}
|
|
7
22
|
set(name, value) {
|
|
8
|
-
this
|
|
23
|
+
__classPrivateFieldGet(this, _Store_temp, "f")[name] = value;
|
|
9
24
|
}
|
|
10
25
|
get(name) {
|
|
11
|
-
return this
|
|
26
|
+
return __classPrivateFieldGet(this, _Store_temp, "f")[name];
|
|
12
27
|
}
|
|
13
28
|
getSnapshot() {
|
|
14
|
-
return deepClone(this
|
|
29
|
+
return deepClone(__classPrivateFieldGet(this, _Store_temp, "f"));
|
|
15
30
|
}
|
|
16
31
|
clear() {
|
|
17
|
-
this
|
|
32
|
+
__classPrivateFieldSet(this, _Store_temp, __classPrivateFieldGet(this, _Store_instances, "m", _Store_createTempStorage).call(this), "f");
|
|
18
33
|
}
|
|
19
|
-
|
|
20
|
-
|
|
34
|
+
destroy() {
|
|
35
|
+
__classPrivateFieldSet(this, _Store_temp, null, "f");
|
|
21
36
|
}
|
|
22
37
|
}
|
|
38
|
+
_Store_temp = new WeakMap(), _Store_backUpDefaultStorage = new WeakMap(), _Store_instances = new WeakSet(), _Store_createTempStorage = function _Store_createTempStorage() {
|
|
39
|
+
return deepClone(__classPrivateFieldGet(this, _Store_backUpDefaultStorage, "f"));
|
|
40
|
+
};
|
package/dist/esm/lib/time.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ type Middleware = (ctx: any, next: Middleware) => any;
|
|
|
2
2
|
export declare function compose(middleware: Middleware[]): (context: any, next?: Middleware) => any;
|
|
3
3
|
export declare function delay(time: number): Promise<void>;
|
|
4
4
|
export declare function throttle(fn: (...args: any[]) => any, timeout: number): (...args: any[]) => any;
|
|
5
|
+
export declare function debounce(fn: (...args: any[]) => any, timeout: number): (...args: any[]) => any;
|
|
5
6
|
export {};
|
package/dist/esm/lib/time.js
CHANGED
|
@@ -27,7 +27,7 @@ export function delay(time) {
|
|
|
27
27
|
export function throttle(fn, timeout) {
|
|
28
28
|
let timer = -1;
|
|
29
29
|
return function (...args) {
|
|
30
|
-
if (timer
|
|
30
|
+
if (timer >= 0) {
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
timer = setTimeout(() => {
|
|
@@ -36,3 +36,15 @@ export function throttle(fn, timeout) {
|
|
|
36
36
|
}, timeout);
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
+
export function debounce(fn, timeout) {
|
|
40
|
+
let timer = -1;
|
|
41
|
+
return function (...args) {
|
|
42
|
+
if (timer >= 0) {
|
|
43
|
+
window.clearTimeout(timer);
|
|
44
|
+
}
|
|
45
|
+
timer = setTimeout(() => {
|
|
46
|
+
fn(...args);
|
|
47
|
+
timer = -1;
|
|
48
|
+
}, timeout);
|
|
49
|
+
};
|
|
50
|
+
}
|
package/dist/esm/lib/view-box.js
CHANGED
|
@@ -3,8 +3,9 @@ const defaultElemConfig = getDefaultElementDetailConfig();
|
|
|
3
3
|
export function calcViewBoxSize(viewElem, opts) {
|
|
4
4
|
const { viewScaleInfo } = opts;
|
|
5
5
|
const { scale } = viewScaleInfo;
|
|
6
|
-
let { borderRadius
|
|
7
|
-
|
|
6
|
+
let { borderRadius } = viewElem.detail;
|
|
7
|
+
const { boxSizing = defaultElemConfig.boxSizing, borderWidth } = viewElem.detail;
|
|
8
|
+
if (Array.isArray(borderWidth)) {
|
|
8
9
|
borderRadius = 0;
|
|
9
10
|
}
|
|
10
11
|
let { x, y, w, h } = viewElem;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Data, ViewSizeInfo } from 'idraw';
|
|
2
|
+
interface ViewCenterContentResult {
|
|
3
|
+
offsetX: number;
|
|
4
|
+
offsetY: number;
|
|
5
|
+
scale: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function calcViewCenterContent(data: Data, opts: {
|
|
8
|
+
viewSizeInfo: ViewSizeInfo;
|
|
9
|
+
}): ViewCenterContentResult;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { rotateElementVertexes } from './rotate';
|
|
2
|
+
import { formatNumber } from './number';
|
|
3
|
+
export function calcViewCenterContent(data, opts) {
|
|
4
|
+
let offsetX = 0;
|
|
5
|
+
let offsetY = 0;
|
|
6
|
+
let scale = 0;
|
|
7
|
+
let contentX = 0;
|
|
8
|
+
let contentY = 0;
|
|
9
|
+
let contentW = 0;
|
|
10
|
+
let contentH = 0;
|
|
11
|
+
const { width, height } = opts.viewSizeInfo;
|
|
12
|
+
data.elements.forEach((elem) => {
|
|
13
|
+
const elemSize = {
|
|
14
|
+
x: elem.x,
|
|
15
|
+
y: elem.y,
|
|
16
|
+
w: elem.w,
|
|
17
|
+
h: elem.h,
|
|
18
|
+
angle: elem.angle
|
|
19
|
+
};
|
|
20
|
+
if (elemSize.angle && (elemSize.angle > 0 || elemSize.angle < 0)) {
|
|
21
|
+
const ves = rotateElementVertexes(elemSize);
|
|
22
|
+
if (ves.length === 4) {
|
|
23
|
+
const xList = [ves[0].x, ves[1].x, ves[2].x, ves[3].x];
|
|
24
|
+
const yList = [ves[0].y, ves[1].y, ves[2].y, ves[3].y];
|
|
25
|
+
elemSize.x = Math.min(...xList);
|
|
26
|
+
elemSize.y = Math.min(...yList);
|
|
27
|
+
elemSize.w = Math.abs(Math.max(...xList) - Math.min(...xList));
|
|
28
|
+
elemSize.h = Math.abs(Math.max(...yList) - Math.min(...yList));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const areaStartX = Math.min(elemSize.x, contentX);
|
|
32
|
+
const areaStartY = Math.min(elemSize.y, contentY);
|
|
33
|
+
const areaEndX = Math.max(elemSize.x + elemSize.w, contentX + contentW);
|
|
34
|
+
const areaEndY = Math.max(elemSize.y + elemSize.h, contentY + contentH);
|
|
35
|
+
contentX = areaStartX;
|
|
36
|
+
contentY = areaStartY;
|
|
37
|
+
contentW = Math.abs(areaEndX - areaStartX);
|
|
38
|
+
contentH = Math.abs(areaEndY - areaStartY);
|
|
39
|
+
});
|
|
40
|
+
if (contentW > 0 && contentH > 0) {
|
|
41
|
+
const scaleW = formatNumber(width / contentW, { decimalPlaces: 4 });
|
|
42
|
+
const scaleH = formatNumber(height / contentH, { decimalPlaces: 4 });
|
|
43
|
+
scale = Math.min(scaleW, scaleH, 1);
|
|
44
|
+
offsetX = (contentW * scale - width) / 2 / scale;
|
|
45
|
+
offsetY = (contentH * scale - height) / 2 / scale;
|
|
46
|
+
}
|
|
47
|
+
const result = {
|
|
48
|
+
offsetX: formatNumber(offsetX, { decimalPlaces: 0 }),
|
|
49
|
+
offsetY: formatNumber(offsetY, { decimalPlaces: 0 }),
|
|
50
|
+
scale
|
|
51
|
+
};
|
|
52
|
+
return result;
|
|
53
|
+
}
|