nhanh-pure-function 1.0.0 → 1.1.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/lib/Index.d.ts +3 -0
- package/lib/Index.js +3 -5
- package/lib/User.d.ts +72 -1
- package/lib/User.js +284 -37
- package/lib/Utility.d.ts +21 -6
- package/lib/Utility.js +42 -16
- package/package.json +1 -1
package/lib/Index.d.ts
ADDED
package/lib/Index.js
CHANGED
package/lib/User.d.ts
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
* @param {滚动标签} element
|
|
4
4
|
* @param {触底事件} callback
|
|
5
5
|
*/
|
|
6
|
-
export function _AddScrollBottomListener(
|
|
6
|
+
export function _AddScrollBottomListener(
|
|
7
|
+
element: HTMLElement,
|
|
8
|
+
callback: Function
|
|
9
|
+
): void;
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* 自动处理 currentPage * pageSize > total
|
|
@@ -183,3 +186,71 @@ export class _LoadingController {
|
|
|
183
186
|
// stopLoading方法的类型定义
|
|
184
187
|
stopLoading(invoker: any, key?: string): void;
|
|
185
188
|
}
|
|
189
|
+
|
|
190
|
+
type UiLibrary = "naiveUI" | "ElementPlus" | "Element";
|
|
191
|
+
/**
|
|
192
|
+
* 点击非指定dom(包含子级dom)时执行 callback
|
|
193
|
+
* @param clickableSelector 允许点击的 dom 选择器
|
|
194
|
+
* @param callback 满足条件时执行的回调
|
|
195
|
+
* @param uiLibrary 项目使用的 ui库 , 用于排除 ui库 创建的元素 , 避免点击 ui库 创建的元素时意外的执行 callback
|
|
196
|
+
*/
|
|
197
|
+
export function _CloseOnOutsideClick(
|
|
198
|
+
clickableSelector: string[],
|
|
199
|
+
callback: Function,
|
|
200
|
+
uiLibrary?: UiLibrary[]
|
|
201
|
+
): void;
|
|
202
|
+
|
|
203
|
+
/** 拖拽配置 */
|
|
204
|
+
type DragOption = {
|
|
205
|
+
/** 拖拽范围限制 */
|
|
206
|
+
limit?: {
|
|
207
|
+
max: {
|
|
208
|
+
top: number;
|
|
209
|
+
left: number;
|
|
210
|
+
};
|
|
211
|
+
min: {
|
|
212
|
+
top: number;
|
|
213
|
+
left: number;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
/** 指定的拖拽元素 */
|
|
217
|
+
dragDom?: HTMLElement;
|
|
218
|
+
};
|
|
219
|
+
/** 拖拽 */
|
|
220
|
+
export class Drag {
|
|
221
|
+
/**
|
|
222
|
+
* 初始化拖拽
|
|
223
|
+
* @param dom 被拖拽的元素
|
|
224
|
+
* @param option 拖拽配置
|
|
225
|
+
*/
|
|
226
|
+
init(dom: HTMLElement, option?: DragOption): void;
|
|
227
|
+
/** 结束拖拽 */
|
|
228
|
+
finish(): void;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** 更新后的位置信息 */
|
|
232
|
+
type UpdateValue = {
|
|
233
|
+
top: number;
|
|
234
|
+
left: number;
|
|
235
|
+
percentage?: {
|
|
236
|
+
top: number;
|
|
237
|
+
left: number;
|
|
238
|
+
};
|
|
239
|
+
};
|
|
240
|
+
/** 局部拖拽配置 */
|
|
241
|
+
type LocalDragOptions = {
|
|
242
|
+
limit?: DragOption["limit"];
|
|
243
|
+
update_move?: (value: UpdateValue) => void | undefined;
|
|
244
|
+
update_up?: (value: UpdateValue) => void | undefined;
|
|
245
|
+
};
|
|
246
|
+
/** 局部拖拽 计算位置距离/百分比 */
|
|
247
|
+
export class LocalDrag {
|
|
248
|
+
/**
|
|
249
|
+
* 初始化拖拽
|
|
250
|
+
* @param parentDom 被拖拽元素的祖先元素
|
|
251
|
+
* @param option 局部拖拽配置
|
|
252
|
+
*/
|
|
253
|
+
init(parentDom: HTMLElement, options: LocalDragOptions = {}): void;
|
|
254
|
+
/** 结束拖拽 */
|
|
255
|
+
finish(): void;
|
|
256
|
+
}
|
package/lib/User.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _IsObject, _IsWithinErrorMargin, _NotNull } from
|
|
1
|
+
import { _IsObject, _IsWithinErrorMargin, _NotNull } from "./Utility";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 添加滚动触底事件
|
|
@@ -6,8 +6,14 @@ import { _IsObject, _IsWithinErrorMargin, _NotNull } from './Utility';
|
|
|
6
6
|
* @param {触底事件} callback
|
|
7
7
|
*/
|
|
8
8
|
export function _AddScrollBottomListener(element, callback) {
|
|
9
|
-
element.addEventListener(
|
|
10
|
-
if (
|
|
9
|
+
element.addEventListener("scroll", function () {
|
|
10
|
+
if (
|
|
11
|
+
_IsWithinErrorMargin(
|
|
12
|
+
element.scrollTop + element.clientHeight,
|
|
13
|
+
element.scrollHeight,
|
|
14
|
+
2
|
|
15
|
+
)
|
|
16
|
+
) {
|
|
11
17
|
callback();
|
|
12
18
|
}
|
|
13
19
|
});
|
|
@@ -53,25 +59,25 @@ export function _FormatNumberWithUnit(number, config = {}) {
|
|
|
53
59
|
const { join, suffix, integer } = Object.assign(
|
|
54
60
|
{
|
|
55
61
|
join: true,
|
|
56
|
-
suffix:
|
|
57
|
-
integer: false
|
|
62
|
+
suffix: "",
|
|
63
|
+
integer: false,
|
|
58
64
|
},
|
|
59
65
|
config
|
|
60
66
|
);
|
|
61
67
|
|
|
62
68
|
function _join(value, suffix, plus = true) {
|
|
63
|
-
value = (plus ?
|
|
69
|
+
value = (plus ? "" : "-") + value;
|
|
64
70
|
if (join) return value + suffix;
|
|
65
71
|
else return [value, suffix];
|
|
66
72
|
}
|
|
67
73
|
|
|
68
|
-
if (typeof number ==
|
|
74
|
+
if (typeof number == "string") {
|
|
69
75
|
if (!/^\d+$/.test(number.trim())) {
|
|
70
|
-
console.error(
|
|
76
|
+
console.error("错误输入:", number);
|
|
71
77
|
return _join(0, suffix);
|
|
72
78
|
}
|
|
73
|
-
} else if (typeof number !=
|
|
74
|
-
console.error(
|
|
79
|
+
} else if (typeof number != "number") {
|
|
80
|
+
console.error("错误输入:", number);
|
|
75
81
|
return _join(0, suffix);
|
|
76
82
|
}
|
|
77
83
|
|
|
@@ -83,7 +89,21 @@ export function _FormatNumberWithUnit(number, config = {}) {
|
|
|
83
89
|
const plus = number >= 0;
|
|
84
90
|
number = Math.abs(number);
|
|
85
91
|
|
|
86
|
-
const units = [
|
|
92
|
+
const units = [
|
|
93
|
+
"",
|
|
94
|
+
"万",
|
|
95
|
+
"亿",
|
|
96
|
+
"兆",
|
|
97
|
+
"京",
|
|
98
|
+
"垓",
|
|
99
|
+
"秭",
|
|
100
|
+
"穰",
|
|
101
|
+
"沟",
|
|
102
|
+
"涧",
|
|
103
|
+
"正",
|
|
104
|
+
"载",
|
|
105
|
+
"极",
|
|
106
|
+
];
|
|
87
107
|
const digits = Math.floor(Math.log10(number) / 4); // 计算位数
|
|
88
108
|
|
|
89
109
|
// 不超过万位的数字直接返回
|
|
@@ -109,16 +129,17 @@ export function _FormatNumberWithUnit(number, config = {}) {
|
|
|
109
129
|
*/
|
|
110
130
|
export function _SetQuantifierAttribute(data, options = []) {
|
|
111
131
|
if (!_IsObject(data)) {
|
|
112
|
-
console.error(
|
|
132
|
+
console.error("异常输入:", data);
|
|
113
133
|
return data;
|
|
114
134
|
}
|
|
115
135
|
|
|
116
136
|
options.forEach((item) => {
|
|
117
|
-
if (typeof item ===
|
|
137
|
+
if (typeof item === "string") {
|
|
118
138
|
data[item] = _FormatNumberWithUnit(data[item]);
|
|
119
139
|
} else if (Array.isArray(item)) {
|
|
120
140
|
const [label, config] = data[item];
|
|
121
|
-
if (_NotNull(label) && _IsObject(config))
|
|
141
|
+
if (_NotNull(label) && _IsObject(config))
|
|
142
|
+
data[label] = _FormatNumberWithUnit(label, config);
|
|
122
143
|
}
|
|
123
144
|
});
|
|
124
145
|
return data;
|
|
@@ -132,11 +153,11 @@ export function _SetQuantifierAttribute(data, options = []) {
|
|
|
132
153
|
*/
|
|
133
154
|
export function _SetDefaultValue(data, options = {}) {
|
|
134
155
|
if (!_IsObject(data)) {
|
|
135
|
-
console.error(
|
|
156
|
+
console.error("异常输入:", data);
|
|
136
157
|
return data;
|
|
137
158
|
}
|
|
138
159
|
|
|
139
|
-
const { defaultValue =
|
|
160
|
+
const { defaultValue = "--", fieldsNotRequiringAction } = options;
|
|
140
161
|
|
|
141
162
|
for (const key in data) {
|
|
142
163
|
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
@@ -162,7 +183,7 @@ export function _SetDefaultValue(data, options = {}) {
|
|
|
162
183
|
*/
|
|
163
184
|
export function _SetDictionary(data, options = {}) {
|
|
164
185
|
if (!_IsObject(data)) {
|
|
165
|
-
console.error(
|
|
186
|
+
console.error("异常输入:", data);
|
|
166
187
|
return data;
|
|
167
188
|
}
|
|
168
189
|
|
|
@@ -170,7 +191,7 @@ export function _SetDictionary(data, options = {}) {
|
|
|
170
191
|
dictionaryLabel = [],
|
|
171
192
|
dictionaryLabelJoin = [],
|
|
172
193
|
dictionaryOptions,
|
|
173
|
-
defaultValue =
|
|
194
|
+
defaultValue = "--",
|
|
174
195
|
} = options;
|
|
175
196
|
|
|
176
197
|
if (dictionaryOptions) {
|
|
@@ -188,11 +209,11 @@ export function _SetDictionary(data, options = {}) {
|
|
|
188
209
|
}
|
|
189
210
|
});
|
|
190
211
|
dictionaryLabelJoin.forEach((label) => {
|
|
191
|
-
if (_NotNull(data[label]) && data[label] !=
|
|
212
|
+
if (_NotNull(data[label]) && data[label] != "") {
|
|
192
213
|
const options = dictionaryOptions[label];
|
|
193
214
|
if (options) {
|
|
194
|
-
const oldvalue = data[label].split(
|
|
195
|
-
data[label] =
|
|
215
|
+
const oldvalue = data[label].split(",");
|
|
216
|
+
data[label] = "";
|
|
196
217
|
oldvalue.forEach((_label) => {
|
|
197
218
|
data[label] += options[_label];
|
|
198
219
|
});
|
|
@@ -216,7 +237,7 @@ export function _SetDictionary(data, options = {}) {
|
|
|
216
237
|
*/
|
|
217
238
|
export function _SetPhoto(data, options = {}) {
|
|
218
239
|
if (!_IsObject(data)) {
|
|
219
|
-
console.error(
|
|
240
|
+
console.error("异常输入:", data);
|
|
220
241
|
return data;
|
|
221
242
|
}
|
|
222
243
|
|
|
@@ -226,8 +247,8 @@ export function _SetPhoto(data, options = {}) {
|
|
|
226
247
|
label.forEach((label) => {
|
|
227
248
|
const defaultValue = (defaultUrl && defaultUrl[label]) || [];
|
|
228
249
|
const value = data[label];
|
|
229
|
-
if (typeof value ===
|
|
230
|
-
data[label] = value.split(
|
|
250
|
+
if (typeof value === "string") {
|
|
251
|
+
data[label] = value.split(",").filter(Boolean);
|
|
231
252
|
} else {
|
|
232
253
|
data[label] = defaultValue;
|
|
233
254
|
}
|
|
@@ -245,7 +266,7 @@ export function _SetPhoto(data, options = {}) {
|
|
|
245
266
|
*/
|
|
246
267
|
export function _Exhibit_details(data, options = {}) {
|
|
247
268
|
if (!_IsObject(data)) {
|
|
248
|
-
console.error(
|
|
269
|
+
console.error("异常输入:", data);
|
|
249
270
|
return {};
|
|
250
271
|
}
|
|
251
272
|
|
|
@@ -263,19 +284,19 @@ export function _Exhibit_details(data, options = {}) {
|
|
|
263
284
|
|
|
264
285
|
filterLabel = [],
|
|
265
286
|
|
|
266
|
-
defaultValue =
|
|
287
|
+
defaultValue = "--",
|
|
267
288
|
} = options;
|
|
268
289
|
|
|
269
290
|
_SetDictionary(data, {
|
|
270
291
|
dictionaryLabel,
|
|
271
292
|
dictionaryLabelJoin,
|
|
272
293
|
dictionaryOptions,
|
|
273
|
-
defaultValue
|
|
294
|
+
defaultValue,
|
|
274
295
|
});
|
|
275
296
|
|
|
276
297
|
_SetPhoto(data, {
|
|
277
298
|
label: photoLabel,
|
|
278
|
-
defaultUrl: photoDefaultUrl
|
|
299
|
+
defaultUrl: photoDefaultUrl,
|
|
279
300
|
});
|
|
280
301
|
|
|
281
302
|
_SetQuantifierAttribute(data, quantifierLabel);
|
|
@@ -288,12 +309,12 @@ export function _Exhibit_details(data, options = {}) {
|
|
|
288
309
|
.concat(
|
|
289
310
|
quantifierLabel
|
|
290
311
|
.map((item) => {
|
|
291
|
-
if (typeof item ==
|
|
312
|
+
if (typeof item == "string") return item;
|
|
292
313
|
if (Array.isArray(item)) return item[0];
|
|
293
314
|
})
|
|
294
315
|
.filter(Boolean)
|
|
295
316
|
)
|
|
296
|
-
.concat(filterLabel)
|
|
317
|
+
.concat(filterLabel),
|
|
297
318
|
});
|
|
298
319
|
|
|
299
320
|
return data;
|
|
@@ -304,14 +325,14 @@ export class _LoadingController {
|
|
|
304
325
|
#controllersCollection = new Map();
|
|
305
326
|
constructor() {}
|
|
306
327
|
|
|
307
|
-
addController(key =
|
|
328
|
+
addController(key = "default", config) {
|
|
308
329
|
if (this.#controllersCollection.has(key))
|
|
309
|
-
throw new Error(
|
|
330
|
+
throw new Error("key为: " + key + " 的loading控制器已存在, 请重命名。");
|
|
310
331
|
|
|
311
332
|
const {
|
|
312
333
|
loadingState /** 更新/获取 loading 状态的方法 */,
|
|
313
334
|
delayTime = 200 /** 延迟时间 */,
|
|
314
|
-
minDisplayTime = 400 /** 最少显示时间
|
|
335
|
+
minDisplayTime = 400 /** 最少显示时间 */,
|
|
315
336
|
} = config;
|
|
316
337
|
this.#controllersCollection.set(key, {
|
|
317
338
|
invokers: new Set(),
|
|
@@ -319,7 +340,7 @@ export class _LoadingController {
|
|
|
319
340
|
startTime: 0,
|
|
320
341
|
loadingState,
|
|
321
342
|
delayTime,
|
|
322
|
-
minDisplayTime
|
|
343
|
+
minDisplayTime,
|
|
323
344
|
});
|
|
324
345
|
}
|
|
325
346
|
|
|
@@ -327,9 +348,10 @@ export class _LoadingController {
|
|
|
327
348
|
this.#controllersCollection.delete(key);
|
|
328
349
|
}
|
|
329
350
|
|
|
330
|
-
getController(key =
|
|
351
|
+
getController(key = "default") {
|
|
331
352
|
const controller = this.#controllersCollection.get(key);
|
|
332
|
-
if (!controller)
|
|
353
|
+
if (!controller)
|
|
354
|
+
throw new Error("还未添加key为: " + key + " 的loading控制器");
|
|
333
355
|
return controller;
|
|
334
356
|
}
|
|
335
357
|
|
|
@@ -378,10 +400,235 @@ export class _LoadingController {
|
|
|
378
400
|
if (displayTime >= minDisplayTime) {
|
|
379
401
|
this.resetController(key);
|
|
380
402
|
} else {
|
|
381
|
-
setTimeout(
|
|
403
|
+
setTimeout(
|
|
404
|
+
() => this.stopLoading(invoker, key),
|
|
405
|
+
displayTime - minDisplayTime
|
|
406
|
+
);
|
|
382
407
|
}
|
|
383
408
|
} else {
|
|
384
409
|
invokers.delete(invoker);
|
|
385
410
|
}
|
|
386
411
|
}
|
|
387
412
|
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* 点击非指定dom(包含子级dom)时执行 callback
|
|
416
|
+
* @param clickableSelector 允许点击的 dom 选择器
|
|
417
|
+
* @param callback 满足条件时执行的回调
|
|
418
|
+
* @param uiLibrary 项目使用的 ui库 , 用于排除 ui库 创建的元素 , 避免点击 ui库 创建的元素时意外的执行 callback
|
|
419
|
+
*/
|
|
420
|
+
export function _CloseOnOutsideClick(
|
|
421
|
+
clickableSelector,
|
|
422
|
+
callback,
|
|
423
|
+
uiLibrary = ["naiveUI", "ElementPlus", "Element"]
|
|
424
|
+
) {
|
|
425
|
+
function mousedown(event) {
|
|
426
|
+
const target = event.target;
|
|
427
|
+
const UI = (function (obj) {
|
|
428
|
+
const arr = [];
|
|
429
|
+
for (const key in obj) {
|
|
430
|
+
if (Object.hasOwnProperty.call(obj, key)) {
|
|
431
|
+
if (uiLibrary.includes(key)) arr.concat(obj[key]);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return arr;
|
|
435
|
+
})({
|
|
436
|
+
naiveUI: [".v-binder-follower-container"],
|
|
437
|
+
ElementPlus: ["el-popper"],
|
|
438
|
+
Element: ["el-popper"],
|
|
439
|
+
});
|
|
440
|
+
const isClickable = clickableSelector
|
|
441
|
+
.concat(UI)
|
|
442
|
+
.some((className) => Boolean(target?.closest(className)));
|
|
443
|
+
|
|
444
|
+
if (!isClickable) {
|
|
445
|
+
callback();
|
|
446
|
+
document.removeEventListener("mousedown", mousedown);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
requestAnimationFrame(() =>
|
|
450
|
+
document.addEventListener("mousedown", mousedown)
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/** 拖拽dom */
|
|
455
|
+
export class Drag {
|
|
456
|
+
#dom = null;
|
|
457
|
+
#isAllowed = false;
|
|
458
|
+
#eventFunction = {};
|
|
459
|
+
#pageX = 0;
|
|
460
|
+
#pageY = 0;
|
|
461
|
+
#top = 0;
|
|
462
|
+
#left = 0;
|
|
463
|
+
#limit;
|
|
464
|
+
#dragDom;
|
|
465
|
+
|
|
466
|
+
init(dom, option) {
|
|
467
|
+
this.#dom = dom;
|
|
468
|
+
this.#limit = option?.limit;
|
|
469
|
+
this.#dragDom = option?.dragDom;
|
|
470
|
+
this.#eventFunction = {
|
|
471
|
+
mousedown: this.mousedown.bind(this),
|
|
472
|
+
mousemove: this.mousemove.bind(this),
|
|
473
|
+
mouseup: this.mouseup.bind(this),
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
this.bindOrUnbindEvent("bind");
|
|
477
|
+
}
|
|
478
|
+
finish() {
|
|
479
|
+
this.bindOrUnbindEvent("unbind");
|
|
480
|
+
}
|
|
481
|
+
bindOrUnbindEvent(type) {
|
|
482
|
+
const EventType =
|
|
483
|
+
type === "bind" ? "addEventListener" : "removeEventListener";
|
|
484
|
+
if (!this.#dom) return console.error("No DOM");
|
|
485
|
+
|
|
486
|
+
this.#dom[EventType]("mousedown", this.#eventFunction.mousedown);
|
|
487
|
+
document[EventType]("mousemove", this.#eventFunction.mousemove);
|
|
488
|
+
document[EventType]("mouseup", this.#eventFunction.mouseup);
|
|
489
|
+
}
|
|
490
|
+
alterLocation() {
|
|
491
|
+
if (!this.#dom) return console.error("No DOM");
|
|
492
|
+
if (this.#limit) {
|
|
493
|
+
this.#top = Math.min(this.#top, this.#limit.max.top);
|
|
494
|
+
this.#top = Math.max(this.#top, this.#limit.min.top);
|
|
495
|
+
this.#left = Math.min(this.#left, this.#limit.max.left);
|
|
496
|
+
this.#left = Math.max(this.#left, this.#limit.min.left);
|
|
497
|
+
}
|
|
498
|
+
this.#dom.style.setProperty("--top", this.#top + "px");
|
|
499
|
+
this.#dom.style.setProperty("--left", this.#left + "px");
|
|
500
|
+
}
|
|
501
|
+
mousedown(event) {
|
|
502
|
+
if (!this.#dom) return console.error("No DOM");
|
|
503
|
+
if (this.#dragDom && event.target != this.#dragDom) return;
|
|
504
|
+
document.body.classList.add("no-select");
|
|
505
|
+
|
|
506
|
+
this.#isAllowed = true;
|
|
507
|
+
const clientRect = this.#dom.getBoundingClientRect();
|
|
508
|
+
|
|
509
|
+
const { pageX, pageY } = event;
|
|
510
|
+
this.#pageX = pageX;
|
|
511
|
+
this.#pageY = pageY;
|
|
512
|
+
this.#top = clientRect.y;
|
|
513
|
+
this.#left = clientRect.x;
|
|
514
|
+
}
|
|
515
|
+
mousemove(event) {
|
|
516
|
+
const { pageX, pageY } = event;
|
|
517
|
+
if (this.#isAllowed) {
|
|
518
|
+
this.#top += pageY - this.#pageY;
|
|
519
|
+
this.#left += pageX - this.#pageX;
|
|
520
|
+
this.#pageX = pageX;
|
|
521
|
+
this.#pageY = pageY;
|
|
522
|
+
|
|
523
|
+
this.alterLocation();
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
mouseup() {
|
|
527
|
+
if (this.#isAllowed) {
|
|
528
|
+
this.#isAllowed = false;
|
|
529
|
+
document.body.classList.remove("no-select");
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/** 局部拖拽 计算位置距离/百分比 */
|
|
535
|
+
export class LocalDrag {
|
|
536
|
+
#parentDom = null;
|
|
537
|
+
#isAllowed = false;
|
|
538
|
+
#eventFunction = {};
|
|
539
|
+
#clientRectX = 0;
|
|
540
|
+
#clientRectY = 0;
|
|
541
|
+
#top = 0;
|
|
542
|
+
#left = 0;
|
|
543
|
+
#limit;
|
|
544
|
+
#update_move;
|
|
545
|
+
#update_up;
|
|
546
|
+
|
|
547
|
+
init(parentDom, options = {}) {
|
|
548
|
+
this.#parentDom = parentDom;
|
|
549
|
+
this.#limit = options.limit;
|
|
550
|
+
this.#update_move = options.update_move;
|
|
551
|
+
this.#update_up = options.update_up;
|
|
552
|
+
this.#eventFunction = {
|
|
553
|
+
mousedown: this.mousedown.bind(this),
|
|
554
|
+
mousemove: this.mousemove.bind(this),
|
|
555
|
+
mouseup: this.mouseup.bind(this),
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
this.bindOrUnbindEvent("bind");
|
|
559
|
+
}
|
|
560
|
+
finish() {
|
|
561
|
+
this.bindOrUnbindEvent("unbind");
|
|
562
|
+
}
|
|
563
|
+
bindOrUnbindEvent(type) {
|
|
564
|
+
const EventType =
|
|
565
|
+
type === "bind" ? "addEventListener" : "removeEventListener";
|
|
566
|
+
if (!this.#parentDom) return window.customize_error("No DOM");
|
|
567
|
+
|
|
568
|
+
this.#parentDom[EventType]("mousedown", this.#eventFunction.mousedown);
|
|
569
|
+
document[EventType]("mousemove", this.#eventFunction.mousemove);
|
|
570
|
+
document[EventType]("mouseup", this.#eventFunction.mouseup);
|
|
571
|
+
}
|
|
572
|
+
updateValue() {
|
|
573
|
+
const value = {
|
|
574
|
+
top: this.#top,
|
|
575
|
+
left: this.#left,
|
|
576
|
+
};
|
|
577
|
+
if (this.#limit) {
|
|
578
|
+
const v = (type) =>
|
|
579
|
+
this.#limit
|
|
580
|
+
? (value[type] - this.#limit.min[type]) /
|
|
581
|
+
(this.#limit.max[type] - this.#limit.min[type])
|
|
582
|
+
: 0;
|
|
583
|
+
|
|
584
|
+
value.percentage = {
|
|
585
|
+
top: v("top") || 0,
|
|
586
|
+
left: v("left") || 0,
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
return value;
|
|
590
|
+
}
|
|
591
|
+
alterLocation() {
|
|
592
|
+
if (!this.#parentDom) return window.customize_error("No DOM");
|
|
593
|
+
if (this.#limit) {
|
|
594
|
+
this.#top = Math.min(this.#top, this.#limit.max.top);
|
|
595
|
+
this.#top = Math.max(this.#top, this.#limit.min.top);
|
|
596
|
+
this.#left = Math.min(this.#left, this.#limit.max.left);
|
|
597
|
+
this.#left = Math.max(this.#left, this.#limit.min.left);
|
|
598
|
+
}
|
|
599
|
+
if (this.#update_move) this.#update_move(this.updateValue());
|
|
600
|
+
|
|
601
|
+
this.#parentDom.style.setProperty("--top", this.#top + "px");
|
|
602
|
+
this.#parentDom.style.setProperty("--left", this.#left + "px");
|
|
603
|
+
}
|
|
604
|
+
mousedown(event) {
|
|
605
|
+
if (!this.#parentDom) return window.customize_error("No DOM");
|
|
606
|
+
document.body.classList.add("no-select");
|
|
607
|
+
|
|
608
|
+
this.#isAllowed = true;
|
|
609
|
+
const clientRect = this.#parentDom.getBoundingClientRect();
|
|
610
|
+
this.#clientRectY = clientRect.y;
|
|
611
|
+
this.#clientRectX = clientRect.x;
|
|
612
|
+
|
|
613
|
+
const { pageX, pageY } = event;
|
|
614
|
+
this.#top = pageY - this.#clientRectY;
|
|
615
|
+
this.#left = pageX - this.#clientRectX;
|
|
616
|
+
|
|
617
|
+
this.alterLocation();
|
|
618
|
+
}
|
|
619
|
+
mousemove(event) {
|
|
620
|
+
const { pageX, pageY } = event;
|
|
621
|
+
if (this.#isAllowed) {
|
|
622
|
+
this.#top = pageY - this.#clientRectY;
|
|
623
|
+
this.#left = pageX - this.#clientRectX;
|
|
624
|
+
this.alterLocation();
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
mouseup() {
|
|
628
|
+
if (this.#isAllowed) {
|
|
629
|
+
this.#isAllowed = false;
|
|
630
|
+
document.body.classList.remove("no-select");
|
|
631
|
+
if (this.#update_up) this.#update_up(this.updateValue());
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
package/lib/Utility.d.ts
CHANGED
|
@@ -104,27 +104,30 @@ export function _ReadFile(src: string): Promise<string>;
|
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
106
|
* 下载文件
|
|
107
|
-
* @param {
|
|
108
|
-
* @param {
|
|
107
|
+
* @param {string} href 文件路径
|
|
108
|
+
* @param {string} fileName 导出文件名
|
|
109
109
|
*/
|
|
110
110
|
export function _DownloadFile(href: string, fileName?: string): void;
|
|
111
111
|
|
|
112
112
|
/**
|
|
113
113
|
* 获取帧率
|
|
114
|
-
* @param {
|
|
114
|
+
* @param {(fps , frameTime)=>void} callback callback( 帧率 , 每帧时间 )
|
|
115
115
|
* @param {Number} referenceNode 参考节点数量
|
|
116
116
|
*/
|
|
117
117
|
export function _GetFrameRate(
|
|
118
|
-
callback:
|
|
118
|
+
callback: (fps: number, frameTime: number) => void,
|
|
119
119
|
referenceNode: number = 10
|
|
120
120
|
): void;
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
123
|
* 进度
|
|
124
|
-
* @param {
|
|
124
|
+
* @param {(schedule)=>void} callback callback( 进度百分比 )
|
|
125
125
|
* @param {Number} TIME 总时长
|
|
126
126
|
*/
|
|
127
|
-
export function _Schedule(
|
|
127
|
+
export function _Schedule(
|
|
128
|
+
callback: (schedule: number) => void,
|
|
129
|
+
TIME: number = 500
|
|
130
|
+
): void;
|
|
128
131
|
|
|
129
132
|
/**
|
|
130
133
|
* 格式化数字,给数字加上千位分隔符。
|
|
@@ -150,3 +153,15 @@ export function _ConvertToCamelCase(
|
|
|
150
153
|
str: string,
|
|
151
154
|
isRemoveDelimiter?: boolean
|
|
152
155
|
): string;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 创建文件并下载
|
|
159
|
+
* @param {BlobPart[]} content 文件内容
|
|
160
|
+
* @param {string} fileName 文件名称
|
|
161
|
+
* @param {BlobPropertyBag} options Blob 配置
|
|
162
|
+
*/
|
|
163
|
+
export function _CreateAndDownloadFile(
|
|
164
|
+
content: BlobPart[],
|
|
165
|
+
fileName: string,
|
|
166
|
+
options?: BlobPropertyBag
|
|
167
|
+
): void;
|
package/lib/Utility.js
CHANGED
|
@@ -228,32 +228,32 @@ export function _DownloadFile(href, fileName) {
|
|
|
228
228
|
|
|
229
229
|
/**
|
|
230
230
|
* 获取帧率
|
|
231
|
-
* @param {
|
|
231
|
+
* @param {(fps , frameTime)=>void} callback callback( 帧率 , 每帧时间 )
|
|
232
232
|
* @param {Number} referenceNode 参考节点数量
|
|
233
233
|
*/
|
|
234
234
|
export function _GetFrameRate(callback, referenceNode = 10) {
|
|
235
235
|
let t,
|
|
236
|
-
|
|
237
|
-
function loop(
|
|
238
|
-
if (
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
236
|
+
l = referenceNode;
|
|
237
|
+
function loop() {
|
|
238
|
+
if (l > 0) {
|
|
239
|
+
l--;
|
|
240
|
+
requestAnimationFrame(loop);
|
|
241
|
+
} else {
|
|
242
|
+
const time = new Date() - t;
|
|
243
|
+
const frameTime = time / referenceNode;
|
|
244
|
+
const fps = 1000 / frameTime;
|
|
245
|
+
callback(Number(fps.toFixed(2)), Number(frameTime.toFixed(2)));
|
|
247
246
|
}
|
|
248
|
-
t = time;
|
|
249
|
-
requestAnimationFrame(loop);
|
|
250
247
|
}
|
|
251
|
-
requestAnimationFrame(
|
|
248
|
+
requestAnimationFrame(() => {
|
|
249
|
+
t = new Date() - 0;
|
|
250
|
+
loop();
|
|
251
|
+
});
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
/**
|
|
255
255
|
* 进度
|
|
256
|
-
* @param {
|
|
256
|
+
* @param {(schedule)=>void} callback callback( 进度百分比 )
|
|
257
257
|
* @param {Number} TIME 总时长
|
|
258
258
|
*/
|
|
259
259
|
export function _Schedule(callback, TIME = 500) {
|
|
@@ -302,3 +302,29 @@ export function _ConvertToCamelCase(str, isRemoveDelimiter) {
|
|
|
302
302
|
if (isRemoveDelimiter) return str.replace(/[^a-zA-Z]+/g, "");
|
|
303
303
|
return str;
|
|
304
304
|
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* 创建文件并下载
|
|
308
|
+
* @param {BlobPart[]} content 文件内容
|
|
309
|
+
* @param {string} fileName 文件名称
|
|
310
|
+
* @param {BlobPropertyBag} options Blob 配置
|
|
311
|
+
*/
|
|
312
|
+
export function _CreateAndDownloadFile(content, fileName, options) {
|
|
313
|
+
if (!options) {
|
|
314
|
+
let type = fileName.replace(/^[^.]+./, "");
|
|
315
|
+
type = type == fileName ? "text/plain" : "application/" + type;
|
|
316
|
+
options = { type };
|
|
317
|
+
}
|
|
318
|
+
const bolb = new Blob(content, options);
|
|
319
|
+
// 创建一个 URL,该 URL 可以用于在浏览器中引用 Blob 对象(例如,在 <a> 标签的 href 属性中)
|
|
320
|
+
const url = URL.createObjectURL(bolb);
|
|
321
|
+
// 你可以创建一个链接来下载这个 Blob 对象
|
|
322
|
+
const downloadLink = document.createElement("a");
|
|
323
|
+
downloadLink.href = url;
|
|
324
|
+
downloadLink.download = fileName; // 设置下载文件的名称
|
|
325
|
+
document.body.appendChild(downloadLink); // 添加到文档中
|
|
326
|
+
downloadLink.click(); // 模拟点击以开始下载
|
|
327
|
+
document.body.removeChild(downloadLink); // 然后从文档中移除
|
|
328
|
+
// 最后,别忘了撤销 Blob 对象的 URL,以释放资源
|
|
329
|
+
URL.revokeObjectURL(url);
|
|
330
|
+
}
|