uiik 1.3.0-alpha → 1.3.0-beta.1

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/index.esm.js CHANGED
@@ -1,15 +1,15 @@
1
1
  /**
2
- * uiik v1.3.0-alpha
2
+ * uiik v1.3.0-beta.1
3
3
  * A UI interactions kit includes draggable, splittable, rotatable, selectable, etc.
4
4
  * https://github.com/holyhigh2/uiik
5
5
  * c) 2021-2023 @holyhigh2 may be freely distributed under the MIT license
6
6
  */
7
- import { isDefined, isArrayLike, isString, isElement, isEmpty, isArray, isNumber, isFunction, isBoolean, isUndefined } from 'myfx/is';
7
+ import { isDefined, isString, isNumber, isArrayLike, isElement, isEmpty, isArray, isFunction, isBoolean, isUndefined } from 'myfx/is';
8
8
  import { find, map, toArray, each, reject, includes, some, flatMap, size } from 'myfx/collection';
9
9
  import { get, assign, merge } from 'myfx/object';
10
- import { split, test } from 'myfx/string';
10
+ import { closest } from 'myfx/tree';
11
+ import { lowerCase, split, test } from 'myfx/string';
11
12
  import { compact, findIndex } from 'myfx/array';
12
- import 'myfx';
13
13
  import { alphaId } from 'myfx/utils';
14
14
 
15
15
  /******************************************************************************
@@ -45,8 +45,8 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
45
45
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
46
46
  };
47
47
 
48
+ /* eslint-disable max-len */
48
49
  const UtMap = new WeakMap();
49
- const EXP_MATRIX$1 = /matrix\((?<a>[\d-.]+)\s*,\s*(?<b>[\d-.]+)\s*,\s*(?<c>[\d-.]+)\s*,\s*(?<d>[\d-.]+)\s*,\s*(?<x>[\d-.]+)\s*,\s*(?<y>[\d-.]+)\)/gim;
50
50
  class UiiTransformer {
51
51
  constructor(el) {
52
52
  this.angle = 0;
@@ -55,7 +55,7 @@ class UiiTransformer {
55
55
  UtMap.set(el, this);
56
56
  }
57
57
  normalize(el) {
58
- let { x, y } = normalize(el);
58
+ let { x, y } = normalize(el || this.el);
59
59
  this.x = x;
60
60
  this.y = y;
61
61
  return this;
@@ -73,10 +73,19 @@ class UiiTransformer {
73
73
  this.y = y;
74
74
  moveTo(this.el, this.x, this.y);
75
75
  }
76
+ rotateTo(deg, cx, cy) {
77
+ this.angle = deg;
78
+ rotateTo(this.el, deg, cx, cy);
79
+ }
76
80
  }
81
+ /**
82
+ * 统一化处理,所有外边距都处理为translate
83
+ * @param el
84
+ */
77
85
  function normalize(el) {
78
86
  const style = window.getComputedStyle(el);
79
87
  let x = 0, y = 0;
88
+ //1. convert left/top (include margins)
80
89
  if (el instanceof HTMLElement) {
81
90
  x = (parseFloat(style.left) || 0) + (parseFloat(style.marginLeft) || 0);
82
91
  y = (parseFloat(style.top) || 0) + (parseFloat(style.marginTop) || 0);
@@ -85,22 +94,28 @@ function normalize(el) {
85
94
  el.style.setProperty("margin", "0", "important");
86
95
  }
87
96
  else {
88
- x = parseFloat(style.x || style.cx) || 0;
89
- y = parseFloat(style.y || style.cy) || 0;
97
+ x =
98
+ parseFloat(get(el, "x.baseVal.value") || get(el, "cx.baseVal.value")) ||
99
+ 0;
100
+ y =
101
+ parseFloat(get(el, "y.baseVal.value") || get(el, "cy.baseVal.value")) ||
102
+ 0;
90
103
  el.removeAttribute("x");
91
104
  el.removeAttribute("y");
92
105
  el.removeAttribute("cx");
93
106
  el.removeAttribute("cy");
94
107
  }
95
- EXP_MATRIX$1.lastIndex = 0;
96
- const rs = EXP_MATRIX$1.exec(window.getComputedStyle(el).transform);
97
- if (rs && rs.groups) {
98
- x += parseFloat(rs.groups.x) || 0;
99
- y += parseFloat(rs.groups.y) || 0;
100
- }
108
+ //2. merge transform
109
+ const { x: tx, y: ty } = getTranslate(el);
110
+ x += tx || 0;
111
+ y += ty || 0;
101
112
  moveTo(el, x, y);
102
113
  return { x, y };
103
114
  }
115
+ /**
116
+ * 返回一个包装后的变形对象,可执行变形操作
117
+ * @param el
118
+ */
104
119
  function wrapper(el) {
105
120
  let ut = UtMap.get(el);
106
121
  if (ut)
@@ -108,12 +123,18 @@ function wrapper(el) {
108
123
  return new UiiTransformer(el);
109
124
  }
110
125
  function transformMove(transofrmStr, x, y, unit = false) {
111
- return (`translate(${x}${unit ? "px" : ""},${y}${unit ? "px" : ""})` +
112
- transofrmStr.replace(/translate\([^)]+?\)/, ""));
126
+ return (`translate(${x}${unit ? "px" : ""},${y}${unit ? "px" : ""}) ` +
127
+ transofrmStr.replace(/translate\([^)]+?\)/, "").trim());
113
128
  }
129
+ /**
130
+ * 获取元素当前transform中的位移数据
131
+ * @param el HTMLElement|SVGGraphicsElement
132
+ * @returns {x,y}
133
+ */
114
134
  function getTranslate(el) {
115
135
  let xVal = NaN, yVal = NaN;
116
136
  let transformStr = "";
137
+ //svg
117
138
  if (el instanceof SVGGraphicsElement) {
118
139
  transformStr = el.getAttribute("transform") || "";
119
140
  }
@@ -141,7 +162,14 @@ function getTranslate(el) {
141
162
  }
142
163
  return { x: xVal, y: yVal };
143
164
  }
165
+ /**
166
+ * 自动检测HTML元素或SVG元素并设置对应移动属性
167
+ * @param el HTMLElement|SVGGraphicsElement
168
+ * @param x value of px
169
+ * @param y value of px
170
+ */
144
171
  function moveTo(el, x, y) {
172
+ //svg
145
173
  if (el instanceof SVGGraphicsElement) {
146
174
  el.setAttribute("transform", transformMove(el.getAttribute("transform") || "", x, y));
147
175
  }
@@ -152,8 +180,15 @@ function moveTo(el, x, y) {
152
180
  }
153
181
  const EXP_GET_TRANSLATE = /translate\(\s*(?<x>[\d.-]+)\D*,\s*(?<y>[\d.-]+)\D*\)/gim;
154
182
  const EXP_GET_TRANSLATE_XY = /translate(?<dir>X|Y)\(\s*(?<v>[\d.-]+)\D*\)/gim;
183
+ /**
184
+ * 自动检测HTML元素或SVG元素并设置对应移动属性
185
+ * @param el HTMLElement|SVGGraphicsElement
186
+ * @param x value of px
187
+ * @param y value of px
188
+ */
155
189
  function moveBy(el, x, y) {
156
190
  const xy = getTranslate(el);
191
+ //svg
157
192
  if (el instanceof SVGGraphicsElement) {
158
193
  el.setAttribute("transform", transformMove(el.getAttribute("transform") || "", xy.x + x, xy.y + y));
159
194
  }
@@ -163,11 +198,13 @@ function moveBy(el, x, y) {
163
198
  }
164
199
  }
165
200
  function rotateTo(el, deg, cx, cy) {
201
+ //svg
166
202
  if (el instanceof SVGGraphicsElement) {
167
203
  let transformStr = el.getAttribute("transform") || "";
168
204
  let originPos = isDefined(cx) && isDefined(cy);
169
205
  let origin = "";
170
206
  if (originPos) {
207
+ //origin offset
171
208
  if (el.x instanceof SVGAnimatedLength) {
172
209
  cx += el.x.animVal.value;
173
210
  cy += el.y.animVal.value;
@@ -185,15 +222,30 @@ function rotateTo(el, deg, cx, cy) {
185
222
  else {
186
223
  let style = el.style;
187
224
  style.transform =
188
- style.transform.replace(/rotate\([^)]+?\)/, "").replace(/rotateZ\([^)]+?\)/, "") +
225
+ style.transform
226
+ .replace(/rotate\([^)]+?\)/, "")
227
+ .replace(/rotateZ\([^)]+?\)/, "") +
189
228
  " rotateZ(" +
190
229
  deg +
191
230
  "deg)";
192
231
  }
193
232
  }
194
233
 
234
+ /* eslint-disable max-len */
235
+ /**
236
+ * 一角度对应的弧度
237
+ */
195
238
  const ONE_ANG = Math.PI / 180;
239
+ /**
240
+ * 一弧度对应的角度
241
+ */
196
242
  const ONE_RAD = 180 / Math.PI;
243
+ /**
244
+ * 获取child相对于parent的位置信息。含border宽度
245
+ *
246
+ * todo
247
+ * @returns {x,y,w,h}
248
+ */
197
249
  function getBox(child, parent) {
198
250
  const rect = child.getBoundingClientRect();
199
251
  const rs = { x: 0, y: 0, w: rect.width, h: rect.height };
@@ -203,7 +255,7 @@ function getBox(child, parent) {
203
255
  child.ownerSVGElement ||
204
256
  child.parentElement ||
205
257
  document.body;
206
- const parentRect = parent.getBoundingClientRect();
258
+ const parentRect = parent.getBoundingClientRect(); //bcr包含padding,不包含borderWidth
207
259
  const parentStyle = window.getComputedStyle(parent);
208
260
  const parentBorderLeft = parseFloat(parentStyle.borderLeftWidth);
209
261
  const parentBorderTop = parseFloat(parentStyle.borderTopWidth);
@@ -216,6 +268,11 @@ function getBox(child, parent) {
216
268
  }
217
269
  return rs;
218
270
  }
271
+ /**
272
+ * 获取事件目标与点击点之间的偏移
273
+ * @param e
274
+ * @returns [offx,offy]
275
+ */
219
276
  function getPointOffset(e, pos) {
220
277
  let ox = e.offsetX || 0, oy = e.offsetY || 0;
221
278
  if (e.target instanceof SVGElement) {
@@ -227,6 +284,9 @@ function getPointOffset(e, pos) {
227
284
  function isSVGEl(el) {
228
285
  return el instanceof SVGElement;
229
286
  }
287
+ /**
288
+ * 边缘检测最小内部边距
289
+ */
230
290
  const EDGE_THRESHOLD = 5;
231
291
  const DRAGGING_RULE = "body * { pointer-events: none; }";
232
292
  let lockSheet;
@@ -259,6 +319,10 @@ function restoreCursor() {
259
319
  document.body.style.cursor = cursor.body;
260
320
  document.documentElement.style.cursor = cursor.html;
261
321
  }
322
+ /**
323
+ * 获取元素样式/属性中的x/y
324
+ * @param el
325
+ */
262
326
  function getStyleXy(el) {
263
327
  const style = window.getComputedStyle(el);
264
328
  let x = 0, y = 0;
@@ -272,7 +336,23 @@ function getStyleXy(el) {
272
336
  }
273
337
  return { x, y };
274
338
  }
339
+ /**
340
+ * 获取元素样式/属性中的w/h
341
+ * @param el
342
+ */
343
+ function getStyleSize(el, cStyle) {
344
+ if (!cStyle)
345
+ cStyle = window.getComputedStyle(el);
346
+ const w = parseFloat(cStyle.width);
347
+ const h = parseFloat(cStyle.height);
348
+ return { w, h };
349
+ }
275
350
  const EXP_MATRIX = /matrix\((?<a>[\d.-]+)\s*,\s*(?<b>[\d.-]+)\s*,\s*(?<c>[\d.-]+)\s*,\s*(?<d>[\d.-]+)\s*,\s*(?<x>[\d.-]+)\s*,\s*(?<y>[\d.-]+)\s*\)/;
351
+ /**
352
+ * 获取matrix中的scale/angle
353
+ * @param elCStyle
354
+ * @returns
355
+ */
276
356
  function getMatrixInfo(elCStyle) {
277
357
  let a = 1, b = 0, x = 0, y = 0;
278
358
  let e = undefined, f = undefined;
@@ -307,6 +387,14 @@ function getMatrixInfo(elCStyle) {
307
387
  rs.angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
308
388
  return rs;
309
389
  }
390
+ /**
391
+ * 获取当前鼠标相对于指定元素el的坐标
392
+ * @param event 点击事件
393
+ * @param el 元素
394
+ * @param elRect 元素的DOMRect
395
+ * @param elCStyle 元素的计算样式
396
+ * @returns
397
+ */
310
398
  function getPointInContainer(event, el, elRect, elCStyle, matrixInfo) {
311
399
  if (!elRect) {
312
400
  elRect = el.getBoundingClientRect();
@@ -328,6 +416,11 @@ function getPointInContainer(event, el, elRect, elCStyle, matrixInfo) {
328
416
  el.scrollTop * scale;
329
417
  return { x: x / scale, y: y / scale };
330
418
  }
419
+ /**
420
+ * 获取元素el在容器container中的相对boundingBox
421
+ * @param el
422
+ * @param container
423
+ */
331
424
  function getRectInContainer(el, container) {
332
425
  const elRect = el.getBoundingClientRect();
333
426
  const containerRect = container.getBoundingClientRect();
@@ -349,12 +442,21 @@ function getRectInContainer(el, container) {
349
442
  h: elRect.height / scale,
350
443
  };
351
444
  }
352
- function getCenterXy(el) {
445
+ /**
446
+ * 获取指定元素的圆心坐标
447
+ * @param el
448
+ * @param left
449
+ * @param top
450
+ * @returns
451
+ */
452
+ function getCenterXy(el, ox, oy) {
353
453
  const cStyle = window.getComputedStyle(el);
454
+ //origin
354
455
  const center = cStyle.transformOrigin;
355
456
  const centerPair = center.split(" ");
356
- const ox = parseFloat(centerPair[0]);
357
- const oy = parseFloat(centerPair[1]);
457
+ ox = ox || parseFloat(centerPair[0]);
458
+ oy = oy || parseFloat(centerPair[1]);
459
+ //left & top
358
460
  const shadowDom = el.cloneNode();
359
461
  rotateTo(shadowDom, 0);
360
462
  const parentEl = el.parentElement;
@@ -366,9 +468,83 @@ function getCenterXy(el) {
366
468
  parentEl.removeChild(shadowDom);
367
469
  }
368
470
  return { sx: startX, sy: startY, x: startX + ox, y: startY + oy, ox, oy };
471
+ }
472
+ function getCenterXySVG(el, ox, oy) {
473
+ const { x, y } = getTranslate(el);
474
+ return { sx: x, sy: y, x: x + ox, y: y + oy, ox, oy };
475
+ }
476
+ /**
477
+ * 获取元素当前顶点
478
+ * @param el
479
+ * @param ox 相对于图形左上角的圆心偏移,支持数字/百分比,仅对SVG元素有效,对于非SVG元素使用transform-origin属性
480
+ * @param oy
481
+ */
482
+ function getVertex(el, ox, oy) {
483
+ const cStyle = window.getComputedStyle(el);
484
+ const w = parseFloat(cStyle.width);
485
+ const h = parseFloat(cStyle.height);
486
+ const { originX, originY } = parseOxy(ox, oy, w, h);
487
+ const { x, y, sx, sy } = el instanceof SVGGraphicsElement ? getCenterXySVG(el, originX, originY) : getCenterXy(el);
488
+ const { angle } = getMatrixInfo(cStyle);
489
+ return calcVertex(w, h, x, y, sx, sy, angle * ONE_ANG);
490
+ }
491
+ /**
492
+ * 计算指定矩形旋转后的顶点坐标
493
+ * @param w 宽
494
+ * @param h 高
495
+ * @param cx 圆心
496
+ * @param cy
497
+ * @param sx
498
+ * @param sy
499
+ * @param radian 旋转角 弧度值
500
+ * @returns
501
+ */
502
+ function calcVertex(w, h, cx, cy, sx, sy, radian) {
503
+ let originVertex = [
504
+ { x: 0, y: 0 },
505
+ { x: w, y: 0 },
506
+ { x: 0, y: h },
507
+ { x: w, y: h },
508
+ ];
509
+ return map(originVertex, ({ x, y }) => {
510
+ const nx = (x - cx + sx) * Math.cos(radian) -
511
+ (y - cy + sy) * Math.sin(radian);
512
+ const ny = (x - cx + sx) * Math.sin(radian) +
513
+ (y - cy + sy) * Math.cos(radian);
514
+ return { x: cx + nx, y: cy + ny };
515
+ });
516
+ }
517
+ /**
518
+ * 解析ox/y
519
+ * @param ox 如果不是number或string,originX为0
520
+ * @param oy 如果不是number或string,originY为0
521
+ * @param w
522
+ * @param h
523
+ * @returns {originX,originY}
524
+ */
525
+ function parseOxy(ox, oy, w, h) {
526
+ let originX = 0, originY = 0;
527
+ if (isString(ox)) {
528
+ //percent
529
+ originX = (parseFloat(ox) / 100) * w;
530
+ }
531
+ else if (isNumber(ox)) {
532
+ originX = ox;
533
+ }
534
+ if (isString(oy)) {
535
+ //percent
536
+ originY = (parseFloat(oy) / 100) * h;
537
+ }
538
+ else if (isNumber(oy)) {
539
+ originY = oy;
540
+ }
541
+ return { originX, originY };
369
542
  }
370
543
 
371
544
  var _Uii_listeners;
545
+ /**
546
+ * A Base class for all Uii classes
547
+ */
372
548
  class Uii {
373
549
  constructor(ele, opts) {
374
550
  this.enabled = true;
@@ -396,12 +572,16 @@ class Uii {
396
572
  this.ele = isArrayLike(el) ? toArray(el) : [el];
397
573
  }
398
574
  }
575
+ /**
576
+ * 销毁uii对象,包括卸载事件、清空元素等
577
+ */
399
578
  destroy() {
400
579
  each(__classPrivateFieldGet(this, _Uii_listeners, "f"), (ev) => {
401
580
  ev[0].removeEventListener(ev[1], ev[2], ev[3]);
402
581
  });
403
582
  __classPrivateFieldSet(this, _Uii_listeners, [], "f");
404
583
  }
584
+ //通用指针事件处理接口
405
585
  addPointerDown(el, pointerDown, opts) {
406
586
  const onPointerDown = pointerDown;
407
587
  const threshold = opts.threshold || 0;
@@ -411,7 +591,9 @@ class Uii {
411
591
  let t = e.target;
412
592
  if (!t)
413
593
  return;
594
+ //uiik options
414
595
  const hasCursor = !isEmpty(get(uiiOptions, 'cursor.active'));
596
+ //提取通用信息
415
597
  const currentStyle = el.style;
416
598
  const currentCStyle = window.getComputedStyle(el);
417
599
  const currentRect = el.getBoundingClientRect();
@@ -424,7 +606,7 @@ class Uii {
424
606
  let onPointerStart;
425
607
  let onPointerMove;
426
608
  let onPointerEnd;
427
- onPointerDown({
609
+ const toBreak = !!onPointerDown({
428
610
  onPointerMove: (pm) => { onPointerMove = pm; },
429
611
  onPointerStart: (ps) => { onPointerStart = ps; },
430
612
  onPointerEnd: (pe) => { onPointerEnd = pe; },
@@ -432,6 +614,11 @@ class Uii {
432
614
  pointX: e.clientX, pointY: e.clientY, target: t,
433
615
  currentTarget: el, currentStyle, currentCStyle, currentRect
434
616
  });
617
+ if (toBreak) {
618
+ e.preventDefault();
619
+ return false;
620
+ }
621
+ //函数
435
622
  const pointerMove = (ev) => {
436
623
  const offX = ev.clientX - originPosX;
437
624
  const offY = ev.clientY - originPosY;
@@ -444,7 +631,7 @@ class Uii {
444
631
  if (hasCursor) {
445
632
  setCursor(uiiOptions.cursor.active);
446
633
  }
447
- onPointerMove && onPointerStart({ ev });
634
+ onPointerStart && onPointerStart({ ev });
448
635
  }
449
636
  else {
450
637
  ev.preventDefault();
@@ -474,6 +661,13 @@ class Uii {
474
661
  return false;
475
662
  }, true);
476
663
  }
664
+ /**
665
+ * 注册事件,以便在{@link destroy}方法中卸载
666
+ * @param el dom元素
667
+ * @param event 事件名
668
+ * @param hook 回调函数
669
+ * @param useCapture 默认false
670
+ */
477
671
  registerEvent(el, event, hook, useCapture = false) {
478
672
  const wrapper = ((ev) => {
479
673
  if (!this.enabled)
@@ -483,26 +677,52 @@ class Uii {
483
677
  el.addEventListener(event, wrapper, useCapture);
484
678
  __classPrivateFieldGet(this, _Uii_listeners, "f").push([el, event, wrapper, useCapture]);
485
679
  }
680
+ /**
681
+ * 禁用uii实例,禁用后的dom不会响应事件
682
+ */
486
683
  disable() {
487
684
  this.enabled = false;
488
685
  }
686
+ /**
687
+ * 启用uii实例
688
+ */
489
689
  enable() {
490
690
  this.enabled = true;
491
691
  }
692
+ /**
693
+ * 获取uii实例选项对象
694
+ */
492
695
  getOptions() {
493
696
  return this.opts;
494
697
  }
698
+ /**
699
+ * 获取指定名称的选项值
700
+ * @param name
701
+ * @returns
702
+ */
495
703
  getOption(name) {
496
704
  return this.opts[name];
497
705
  }
706
+ /**
707
+ * 设置多个选项值。触发`onOptionChanged`
708
+ * @param options
709
+ */
498
710
  setOptions(options) {
499
711
  assign(this.opts, options);
500
712
  this.onOptionChanged(this.opts);
501
713
  }
714
+ /**
715
+ * 设置指定name的选项值。触发`onOptionChanged`
716
+ * @param name
717
+ * @param value
718
+ */
502
719
  setOption(name, value) {
503
720
  this.opts[name] = value;
504
721
  this.onOptionChanged(this.opts);
505
722
  }
723
+ /**
724
+ * @internal
725
+ */
506
726
  onOptionChanged(opts) { }
507
727
  }
508
728
  _Uii_listeners = new WeakMap();
@@ -522,6 +742,17 @@ function getRootEl(el, root) {
522
742
  }
523
743
  return rs;
524
744
  }
745
+ /**
746
+ * 用于表示一个或多个分割器的定义
747
+ * > 可用CSS接口
748
+ * - .uii-splittable
749
+ * - .uii-splittable-handle
750
+ * - .uii-splittable-handle-ghost
751
+ * - .uii-splittable-handle-active
752
+ * - .uii-splittable-v
753
+ * - .uii-splittable-h
754
+ * @public
755
+ */
525
756
  class Splittable extends Uii {
526
757
  constructor(container, opts) {
527
758
  super(container, assign({
@@ -533,6 +764,7 @@ class Splittable extends Uii {
533
764
  }, opts));
534
765
  _Splittable_instances.add(this);
535
766
  each(this.ele, con => {
767
+ //detect container position
536
768
  const pos = window.getComputedStyle(con).position;
537
769
  if (pos === "static") {
538
770
  con.style.position = "relative";
@@ -631,10 +863,11 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
631
863
  const updateStart = !oneSideMode || oneSideMode === 'start';
632
864
  const updateEnd = !oneSideMode || oneSideMode === 'end';
633
865
  this.addPointerDown(handle, ({ currentTarget, onPointerStart, onPointerMove, onPointerEnd }) => {
866
+ // 1. 获取原始高度/宽度;设置宽度/高度
634
867
  let originSize = 0;
635
868
  let originSize1 = 0;
636
869
  let splitterSize = 1;
637
- let blockSize = 0;
870
+ let blockSize = 0; // 分割区size
638
871
  switch (dir) {
639
872
  case 'v':
640
873
  originSize = dom1.offsetHeight;
@@ -650,9 +883,11 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
650
883
  blockSize = splitterSize + originSize + originSize1;
651
884
  const dom1Style = dom1.style;
652
885
  const dom2Style = dom2.style;
886
+ //ghost
653
887
  const ghost = opts.ghost;
654
888
  const ghostClass = opts.ghostClass;
655
889
  let ghostNode = null;
890
+ // 初始化sticked位置
656
891
  let sticked = 'none';
657
892
  if (originSize < minSize1 / 2) {
658
893
  sticked = 'start';
@@ -662,6 +897,7 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
662
897
  }
663
898
  let startPos = dir === 'v' ? dom1.offsetTop : dom1.offsetLeft;
664
899
  let ds1, anotherSize;
900
+ //bind events
665
901
  onPointerStart(function (args) {
666
902
  const { ev } = args;
667
903
  currentTarget.classList.add(CLASS_SPLITTABLE_HANDLE_ACTIVE);
@@ -695,6 +931,7 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
695
931
  else if (ds1 < minSize1) {
696
932
  ds1 = minSize1;
697
933
  if (sticked == 'start' && sticky1) {
934
+ // 重置状态
698
935
  doSticky = true;
699
936
  sticked = 'none';
700
937
  }
@@ -710,6 +947,7 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
710
947
  else if (blockSize - ds1 - splitterSize < minSize2) {
711
948
  ds1 = blockSize - minSize2 - splitterSize;
712
949
  if (sticked == 'end' && sticky2) {
950
+ // 重置状态
713
951
  doSticky = true;
714
952
  sticked = 'none';
715
953
  }
@@ -721,7 +959,6 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
721
959
  }
722
960
  else {
723
961
  ghostNode.style.left = startPos + ds1 - handleSize / 2 + 'px';
724
- console.log(ghostNode.style.left);
725
962
  }
726
963
  }
727
964
  else {
@@ -735,6 +972,7 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
735
972
  if (doSticky) {
736
973
  onSticky && onSticky({ size1: ds1, size2: anotherSize, position: sticked }, ev);
737
974
  }
975
+ //update handle
738
976
  if (dir === 'v') {
739
977
  currentStyle.top = dom2.offsetTop - handleSize / 2 + 'px';
740
978
  }
@@ -766,6 +1004,7 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
766
1004
  if (updateEnd) {
767
1005
  dom2Style.setProperty(updateProp, anotherSize + 'px', 'important');
768
1006
  }
1007
+ //update handle
769
1008
  if (dir === 'v') {
770
1009
  currentStyle.top = startPos + ds1 - handleSize / 2 + 'px';
771
1010
  }
@@ -781,15 +1020,30 @@ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Sp
781
1020
  lockPage: true
782
1021
  });
783
1022
  };
1023
+ /**
1024
+ * Add one or more splittors into the container
1025
+ * @param container css selector or html element
1026
+ * @param opts SplittableOptions
1027
+ * @returns
1028
+ */
784
1029
  function newSplittable(container, opts) {
785
1030
  return new Splittable(container, opts);
786
1031
  }
787
1032
 
1033
+ /* eslint-disable max-len */
788
1034
  const THRESHOLD$3 = 2;
789
1035
  const CLASS_RESIZABLE_HANDLE = "uii-resizable-handle";
790
1036
  const CLASS_RESIZABLE_HANDLE_DIR = "uii-resizable-handle-";
791
1037
  const CLASS_RESIZABLE_HANDLE_ACTIVE = "uii-resizable-handle-active";
792
1038
  const EXP_DIR = new RegExp(CLASS_RESIZABLE_HANDLE_DIR + "(?<dir>[nesw]+)");
1039
+ /**
1040
+ * 用于表示一个或多个可改变尺寸元素的定义
1041
+ * > 可用CSS接口
1042
+ * - .uii-resizable-handle
1043
+ * - .uii-resizable-handle-[n/s/e/w/ne/nw/se/sw]
1044
+ * - .uii-resizable-handle-active
1045
+ * @public
1046
+ */
793
1047
  class Resizable extends Uii {
794
1048
  constructor(els, opts) {
795
1049
  super(els, assign({
@@ -800,6 +1054,14 @@ class Resizable extends Uii {
800
1054
  offset: 0,
801
1055
  }, opts));
802
1056
  each(this.ele, (el) => {
1057
+ let tmp = el;
1058
+ if (tmp._uiik_resizable) {
1059
+ tmp._uiik_resizable.destroy();
1060
+ return false;
1061
+ }
1062
+ });
1063
+ each(this.ele, (el) => {
1064
+ el._uiik_resizable = this;
803
1065
  this.initHandle(el);
804
1066
  });
805
1067
  }
@@ -810,16 +1072,22 @@ class Resizable extends Uii {
810
1072
  const onClone = opts.onClone;
811
1073
  const uiik = this;
812
1074
  this.addPointerDown(handle, ({ ev, onPointerStart, onPointerMove, onPointerEnd }) => {
1075
+ //检测
813
1076
  const onPointerDown = opts.onPointerDown;
814
1077
  if (onPointerDown && onPointerDown(ev) === false)
815
- return;
1078
+ return true;
1079
+ let container = panel instanceof SVGGraphicsElement
1080
+ ? closest(panel, (ele) => lowerCase(ele.tagName) === "svg", "parentNode")
1081
+ : panel.parentElement;
1082
+ let setOrigin = !(panel instanceof SVGGraphicsElement);
1083
+ // 获取panel当前信息
816
1084
  let matrixInfo = getMatrixInfo(panel);
817
- const offset = getRectInContainer(panel, panel.parentElement);
818
- const offsetParentRect = panel.parentElement.getBoundingClientRect();
819
- const offsetParentCStyle = window.getComputedStyle(panel.parentElement);
820
- const panelCStyle = window.getComputedStyle(panel);
821
- const originW = parseFloat(panelCStyle.width);
822
- const originH = parseFloat(panelCStyle.height);
1085
+ const offset = getRectInContainer(panel, container);
1086
+ const offsetParentRect = container.getBoundingClientRect();
1087
+ const offsetParentCStyle = window.getComputedStyle(container);
1088
+ const { w, h } = getStyleSize(panel);
1089
+ const originW = w;
1090
+ const originH = h;
823
1091
  const originX = offset.x;
824
1092
  const originY = offset.y;
825
1093
  let changeW = false;
@@ -860,6 +1128,7 @@ class Resizable extends Uii {
860
1128
  toTransformOrigin = "0 0";
861
1129
  break;
862
1130
  }
1131
+ // boundary
863
1132
  let minWidth;
864
1133
  let minHeight;
865
1134
  let maxWidth;
@@ -880,9 +1149,11 @@ class Resizable extends Uii {
880
1149
  maxWidth = opts.maxSize;
881
1150
  maxHeight = opts.maxSize;
882
1151
  }
1152
+ //ghost
883
1153
  const ghost = opts.ghost;
884
1154
  const ghostClass = opts.ghostClass;
885
1155
  let ghostNode = null;
1156
+ //aspectRatio
886
1157
  const aspectRatio = opts.aspectRatio;
887
1158
  const panelStyle = panel.style;
888
1159
  let style = panelStyle;
@@ -891,11 +1162,15 @@ class Resizable extends Uii {
891
1162
  let transformer;
892
1163
  let lastX = 0, lastY = 0;
893
1164
  let originalTransformOrigin = "";
894
- let originVertex;
895
1165
  let vertexBeforeTransform;
896
1166
  let currentVertex;
897
1167
  let refPoint;
1168
+ //slope
898
1169
  let k1;
1170
+ let startOx = 0;
1171
+ let startOy = 0;
1172
+ let sX = 0, sY = 0;
1173
+ //bind events
899
1174
  onPointerStart(function (args) {
900
1175
  var _a;
901
1176
  const { ev } = args;
@@ -925,22 +1200,21 @@ class Resizable extends Uii {
925
1200
  else {
926
1201
  transformer = wrapper(panel);
927
1202
  }
928
- const { x, y, sx, sy } = getCenterXy(panel);
1203
+ const cStyle = window.getComputedStyle(panel);
1204
+ const w = parseFloat(cStyle.width);
1205
+ const h = parseFloat(cStyle.height);
1206
+ const { originX, originY } = parseOxy(opts.ox, opts.oy, w, h);
1207
+ startOx = originX;
1208
+ startOy = originY;
1209
+ const { x, y, sx, sy } = panel instanceof SVGGraphicsElement
1210
+ ? getCenterXySVG(panel, startOx, startOy)
1211
+ : getCenterXy(panel);
929
1212
  let centerX = x, centerY = y;
930
1213
  const deg = matrixInfo.angle * ONE_ANG;
931
- originVertex = [
932
- { x: 0, y: 0 },
933
- { x: originW, y: 0 },
934
- { x: 0, y: originH },
935
- { x: originW, y: originH },
936
- ];
937
- currentVertex = vertexBeforeTransform = map(originVertex, ({ x, y }) => {
938
- const nx = (x - centerX + sx) * Math.cos(deg) -
939
- (y - centerY + sy) * Math.sin(deg);
940
- const ny = (x - centerX + sx) * Math.sin(deg) +
941
- (y - centerY + sy) * Math.cos(deg);
942
- return { x: centerX + nx, y: centerY + ny };
943
- });
1214
+ currentVertex =
1215
+ vertexBeforeTransform =
1216
+ calcVertex(originW, originH, centerX, centerY, sx, sy, deg);
1217
+ //计算参考点及斜率
944
1218
  switch (dir) {
945
1219
  case "s":
946
1220
  case "e":
@@ -959,28 +1233,41 @@ class Resizable extends Uii {
959
1233
  refPoint = currentVertex[2];
960
1234
  break;
961
1235
  }
1236
+ //水平斜率
962
1237
  k1 =
963
1238
  (currentVertex[1].y - refPoint.y) /
964
- (currentVertex[1].x - refPoint.x);
1239
+ (currentVertex[1].x - refPoint.x); //w
1240
+ //change trans origin
965
1241
  style.transition = "none";
966
1242
  originalTransformOrigin = style.transformOrigin;
967
- if (toTransformOrigin) {
968
- style.transformOrigin = toTransformOrigin;
1243
+ if (setOrigin) {
1244
+ if (toTransformOrigin) {
1245
+ style.transformOrigin = toTransformOrigin;
1246
+ }
1247
+ else {
1248
+ style.transformOrigin = `${centerX - transformer.x}px ${centerY - transformer.y}px`;
1249
+ }
969
1250
  }
970
- else {
971
- style.transformOrigin = `${centerX - transformer.x}px ${centerY - transformer.y}px`;
1251
+ if (panel instanceof SVGGraphicsElement) {
1252
+ sX = matrixInfo.x - currentVertex[0].x;
1253
+ sY = matrixInfo.y - currentVertex[0].y;
972
1254
  }
973
1255
  onStart && onStart.call(uiik, { w: originW, h: originH }, ev);
974
1256
  });
975
1257
  onPointerMove((args) => {
976
1258
  const { ev } = args;
977
- const currentXy = getPointInContainer(ev, panel.parentElement, offsetParentRect, offsetParentCStyle);
1259
+ //获取当前位置坐标
1260
+ const currentXy = getPointInContainer(ev, container, offsetParentRect, offsetParentCStyle);
978
1261
  let newX = currentXy.x;
979
1262
  let newY = currentXy.y;
1263
+ ////////////////////////////////////////// 计算边长
1264
+ //1. calc angle
980
1265
  let angle = Math.atan2(newY - refPoint.y, newX - refPoint.x) * ONE_RAD -
981
1266
  matrixInfo.angle;
1267
+ //2. hypotenuse length
982
1268
  let hyLen = Math.sqrt((newX - refPoint.x) * (newX - refPoint.x) +
983
1269
  (newY - refPoint.y) * (newY - refPoint.y));
1270
+ //3. h&v projection length
984
1271
  let pl1 = Math.abs(k1 === Infinity
985
1272
  ? newY - refPoint.y
986
1273
  : hyLen * Math.cos(angle * ONE_ANG));
@@ -1006,6 +1293,7 @@ class Resizable extends Uii {
1006
1293
  angl =
1007
1294
  Math.atan2(currentVertex[0].y - currentVertex[2].y, currentVertex[0].x - currentVertex[2].x) * ONE_RAD;
1008
1295
  let plh;
1296
+ //1&2 quad
1009
1297
  if (angl === 90) {
1010
1298
  h = newY - currentVertex[2].y;
1011
1299
  x = currentVertex[2].x;
@@ -1027,6 +1315,7 @@ class Resizable extends Uii {
1027
1315
  angl =
1028
1316
  Math.atan2(currentVertex[0].y - currentVertex[1].y, currentVertex[0].x - currentVertex[1].x) * ONE_RAD;
1029
1317
  let plw;
1318
+ //1&4 quad
1030
1319
  if (angl === 0) {
1031
1320
  w = newX - currentVertex[1].x;
1032
1321
  x = newX;
@@ -1046,6 +1335,7 @@ class Resizable extends Uii {
1046
1335
  case "nw":
1047
1336
  w = pl1;
1048
1337
  h = pl2;
1338
+ //获取顺时针旋转后的直角坐标
1049
1339
  x = newX;
1050
1340
  y = newY;
1051
1341
  if (matrixInfo.angle === 180) {
@@ -1059,6 +1349,7 @@ class Resizable extends Uii {
1059
1349
  angl =
1060
1350
  Math.atan2(currentVertex[0].y - currentVertex[1].y, currentVertex[0].x - currentVertex[1].x) * ONE_RAD;
1061
1351
  let plw1;
1352
+ //1&4 quad
1062
1353
  if (angl === 0) {
1063
1354
  x = newX;
1064
1355
  y = currentVertex[0].y;
@@ -1085,6 +1376,7 @@ class Resizable extends Uii {
1085
1376
  y = currentVertex[0].y;
1086
1377
  }
1087
1378
  else if (currentVertex[1].x > currentVertex[0].x) {
1379
+ //1&2 quad
1088
1380
  plne = h * Math.cos((180 - angl) * ONE_ANG);
1089
1381
  x = currentVertex[2].x - plne;
1090
1382
  y = currentVertex[2].y - Math.sqrt(h * h - plne * plne);
@@ -1125,24 +1417,39 @@ class Resizable extends Uii {
1125
1417
  }
1126
1418
  else {
1127
1419
  if (changeW) {
1128
- style.width = w + "px";
1420
+ resize(transformer, style, w);
1129
1421
  }
1130
1422
  if (changeH) {
1131
- style.height = h + "px";
1423
+ resize(transformer, style, undefined, h);
1132
1424
  }
1133
1425
  }
1134
1426
  if (changeY) {
1135
- transformer.moveToY(y);
1427
+ transformer.moveToY(y + sY);
1136
1428
  }
1137
1429
  if (changeX) {
1138
- transformer.moveToX(x);
1430
+ transformer.moveToX(x + sX);
1139
1431
  }
1140
1432
  lastX = x;
1141
1433
  lastY = y;
1142
1434
  currentW = w;
1143
1435
  currentH = h;
1144
- onResize &&
1145
- onResize.call(uiik, { w, h, ow: w - originW, oh: h - originH }, ev);
1436
+ if (onResize && onResize.call) {
1437
+ const { x, y, sx, sy } = panel instanceof SVGGraphicsElement
1438
+ ? getCenterXySVG(panel, startOx, startOy)
1439
+ : getCenterXy(panel);
1440
+ onResize.call(uiik, {
1441
+ w,
1442
+ h,
1443
+ ow: w - originW,
1444
+ oh: h - originH,
1445
+ target: panel,
1446
+ cx: x,
1447
+ cy: y,
1448
+ sx: sx,
1449
+ sy: sy,
1450
+ deg: matrixInfo.angle,
1451
+ }, ev);
1452
+ }
1146
1453
  });
1147
1454
  onPointerEnd((args) => {
1148
1455
  var _a, _b;
@@ -1153,25 +1460,38 @@ class Resizable extends Uii {
1153
1460
  panelStyle.left = ghostNode.style.left;
1154
1461
  panelStyle.top = ghostNode.style.top;
1155
1462
  moveTo(panel, lastX / matrixInfo.scale, lastY / matrixInfo.scale);
1156
- panelStyle.width = ghostNode.style.width;
1157
- panelStyle.height = ghostNode.style.height;
1463
+ resize(transformer, panelStyle, parseFloat(ghostNode.style.width), parseFloat(ghostNode.style.height));
1464
+ // panelStyle.width = ghostNode.style.width;
1465
+ // panelStyle.height = ghostNode.style.height;
1158
1466
  }
1159
1467
  panel.style.transformOrigin = originalTransformOrigin;
1160
- const { x, y, sx, sy } = getCenterXy(panel);
1468
+ const { x, y, sx, sy, ox, oy } = panel instanceof SVGGraphicsElement
1469
+ ? getCenterXySVG(panel, startOx, startOy)
1470
+ : getCenterXy(panel);
1161
1471
  let centerX = x, centerY = y;
1162
1472
  const deg = matrixInfo.angle * ONE_ANG;
1163
- const currentVertex = map(originVertex, ({ x, y }) => {
1164
- const nx = (x - centerX + sx) * Math.cos(deg) -
1165
- (y - centerY + sy) * Math.sin(deg);
1166
- const ny = (x - centerX + sx) * Math.sin(deg) +
1167
- (y - centerY + sy) * Math.cos(deg);
1168
- return { x: centerX + nx, y: centerY + ny };
1169
- });
1170
- if (changeX || changeY) {
1171
- transformer.moveTo(transformer.x - (currentVertex[0].x - lastX), transformer.y - (currentVertex[0].y - lastY));
1473
+ const currentVertex = calcVertex(currentW, currentH, centerX, centerY, sx, sy, deg);
1474
+ //修正偏移
1475
+ if (panel instanceof SVGGraphicsElement) {
1476
+ //更新rotate圆心
1477
+ if (matrixInfo.angle != 0) {
1478
+ const { originX, originY } = parseOxy(opts.ox, opts.oy, currentW, currentH);
1479
+ rotateTo(transformer.el, matrixInfo.angle, originX, originY);
1480
+ let { x, y, sx, sy } = getCenterXySVG(panel, originX, originY);
1481
+ let currentVertex2 = calcVertex(currentW, currentH, x, y, sx, sy, deg);
1482
+ //复原translate
1483
+ transformer.moveTo(transformer.x - (currentVertex2[0].x - currentVertex[0].x), transformer.y - (currentVertex2[0].y - currentVertex[0].y));
1484
+ }
1172
1485
  }
1173
1486
  else {
1174
- transformer.moveTo(transformer.x - (currentVertex[0].x - vertexBeforeTransform[0].x), transformer.y - (currentVertex[0].y - vertexBeforeTransform[0].y));
1487
+ if (changeX || changeY) {
1488
+ transformer.moveTo(transformer.x - (currentVertex[0].x - lastX), transformer.y - (currentVertex[0].y - lastY));
1489
+ }
1490
+ else {
1491
+ transformer.moveTo(transformer.x -
1492
+ (currentVertex[0].x - vertexBeforeTransform[0].x), transformer.y -
1493
+ (currentVertex[0].y - vertexBeforeTransform[0].y));
1494
+ }
1175
1495
  }
1176
1496
  handle.classList.remove(CLASS_RESIZABLE_HANDLE_ACTIVE);
1177
1497
  onEnd && onEnd.call(uiik, { w: currentW, h: currentH }, ev);
@@ -1197,6 +1517,7 @@ class Resizable extends Uii {
1197
1517
  }
1198
1518
  handles = isArrayLike(handles) ? handles : [handles];
1199
1519
  each(handles, (h) => {
1520
+ //get dir from handle
1200
1521
  const className = h.getAttribute("class") || "";
1201
1522
  const matchRs = className.match(EXP_DIR);
1202
1523
  let dir = "se";
@@ -1211,6 +1532,27 @@ class Resizable extends Uii {
1211
1532
  });
1212
1533
  }
1213
1534
  }
1535
+ function resize(transformer, style, w, h) {
1536
+ //svg
1537
+ if (transformer.el instanceof SVGGraphicsElement) {
1538
+ if (isDefined(w))
1539
+ transformer.el.setAttribute("width", w + "");
1540
+ if (isDefined(h))
1541
+ transformer.el.setAttribute("height", h + "");
1542
+ }
1543
+ else {
1544
+ if (isDefined(w))
1545
+ style.width = w + "px";
1546
+ if (isDefined(h))
1547
+ style.height = h + "px";
1548
+ }
1549
+ }
1550
+ /**
1551
+ * Make els resizable
1552
+ * @param els selector string / html element
1553
+ * @param opts
1554
+ * @returns
1555
+ */
1214
1556
  function newResizable(els, opts) {
1215
1557
  return new Resizable(els, opts);
1216
1558
  }
@@ -1221,6 +1563,17 @@ const CLASS_DRAGGABLE = "uii-draggable";
1221
1563
  const CLASS_DRAGGABLE_HANDLE = "uii-draggable-handle";
1222
1564
  const CLASS_DRAGGABLE_ACTIVE = "uii-draggable-active";
1223
1565
  const CLASS_DRAGGABLE_GHOST = "uii-draggable-ghost";
1566
+ /**
1567
+ * 用于表示一个或多个可拖动元素的定义
1568
+ * 每个拖动元素可以有独立handle,也可以公用一个handle
1569
+ * 可拖动元素拖动时自动剔除left/top/x/y/cx/cy属性,而使用transform:translate替代
1570
+ * > 可用CSS接口
1571
+ * - .uii-draggable
1572
+ * - .uii-draggable-handle
1573
+ * - .uii-draggable-active
1574
+ * - .uii-draggable-ghost
1575
+ * @public
1576
+ */
1224
1577
  class Draggable extends Uii {
1225
1578
  constructor(els, opts) {
1226
1579
  super(els, assign({
@@ -1248,6 +1601,7 @@ class Draggable extends Uii {
1248
1601
  });
1249
1602
  }
1250
1603
  this.onOptionChanged(this.opts);
1604
+ //put into group
1251
1605
  if (this.opts.group) {
1252
1606
  if (!DRAGGER_GROUPS[this.opts.group]) {
1253
1607
  DRAGGER_GROUPS[this.opts.group] = [];
@@ -1255,6 +1609,7 @@ class Draggable extends Uii {
1255
1609
  DRAGGER_GROUPS[this.opts.group].push(...this.ele);
1256
1610
  }
1257
1611
  __classPrivateFieldGet(this, _Draggable_instances, "m", _Draggable_initStyle).call(this, this.ele);
1612
+ //containment
1258
1613
  if (this.opts.containment) {
1259
1614
  if (isBoolean(this.opts.containment)) {
1260
1615
  __classPrivateFieldSet(this, _Draggable_container, isEmpty(this.ele) ? null : this.ele[0].parentElement, "f");
@@ -1291,27 +1646,32 @@ class Draggable extends Uii {
1291
1646
  var _a;
1292
1647
  let t = ev.target;
1293
1648
  if (!t)
1294
- return;
1649
+ return true;
1650
+ //refresh draggableList
1295
1651
  if (opts.watch && eleString) {
1296
1652
  draggableList = bindTarget.querySelectorAll(eleString);
1297
1653
  initStyle(draggableList);
1298
1654
  }
1655
+ //find drag dom & handle
1299
1656
  let findRs = find(draggableList, el => el.contains(t));
1300
1657
  if (!findRs)
1301
- return;
1658
+ return true;
1302
1659
  const dragDom = findRs;
1303
1660
  let handle = handleMap.get(dragDom);
1304
1661
  if (handle && !handle.contains(t)) {
1305
- return;
1662
+ return true;
1306
1663
  }
1664
+ //检测
1307
1665
  const onPointerDown = opts.onPointerDown;
1308
1666
  if (onPointerDown && onPointerDown({ draggable: dragDom }, ev) === false)
1309
- return;
1667
+ return true;
1310
1668
  const filter = opts.filter;
1669
+ //check filter
1311
1670
  if (filter) {
1312
1671
  if (some(dragDom.querySelectorAll(filter), ele => ele.contains(t)))
1313
- return;
1672
+ return true;
1314
1673
  }
1674
+ //用于计算鼠标移动时当前位置
1315
1675
  const offsetParent = dragDom instanceof HTMLElement ? dragDom.offsetParent || document.body : dragDom.ownerSVGElement;
1316
1676
  const offsetParentRect = offsetParent.getBoundingClientRect();
1317
1677
  const offsetParentCStyle = window.getComputedStyle(offsetParent);
@@ -1363,7 +1723,9 @@ class Draggable extends Uii {
1363
1723
  let lastSnapDirY = "", lastSnapDirX = "";
1364
1724
  let lastSnapping = "";
1365
1725
  if (snapOn) {
1726
+ //获取拖动元素所在容器内的可吸附对象
1366
1727
  snappable = map((container || document).querySelectorAll(snapOn), (el) => {
1728
+ //计算相对容器xy
1367
1729
  const { x, y, w, h } = getRectInContainer(el, offsetParent);
1368
1730
  return {
1369
1731
  x1: x,
@@ -1377,6 +1739,7 @@ class Draggable extends Uii {
1377
1739
  const dragDomRect = dragDom.getBoundingClientRect();
1378
1740
  const originW = dragDomRect.width + parseFloat(currentCStyle.borderLeftWidth) + parseFloat(currentCStyle.borderRightWidth);
1379
1741
  const originH = dragDomRect.height + parseFloat(currentCStyle.borderTopWidth) + parseFloat(currentCStyle.borderBottomWidth);
1742
+ // boundary
1380
1743
  let minX = 0;
1381
1744
  let minY = 0;
1382
1745
  let maxX = 0;
@@ -1399,6 +1762,7 @@ class Draggable extends Uii {
1399
1762
  let toRight = false;
1400
1763
  let toBottom = false;
1401
1764
  let endX = 0, endY = 0;
1765
+ //bind events
1402
1766
  onPointerStart(function (args) {
1403
1767
  var _a;
1404
1768
  const { ev } = args;
@@ -1425,11 +1789,13 @@ class Draggable extends Uii {
1425
1789
  else {
1426
1790
  transformer = wrapper(dragDom);
1427
1791
  }
1792
+ //apply classes
1428
1793
  dragDom.classList.add(...compact(split(classes, ' ')));
1429
1794
  if (!copyNode)
1430
1795
  dragDom.style.zIndex = zIndex + '';
1431
1796
  dragDom.classList.toggle(CLASS_DRAGGABLE_ACTIVE, true);
1432
1797
  onStart && onStart({ draggable: dragDom, x: currentXy.x, y: currentXy.y }, ev);
1798
+ //notify
1433
1799
  const customEv = new Event("uii-dragactive", { "bubbles": true, "cancelable": false });
1434
1800
  dragDom.dispatchEvent(customEv);
1435
1801
  });
@@ -1438,6 +1804,7 @@ class Draggable extends Uii {
1438
1804
  const currentXy = getPointInContainer(ev, offsetParent, offsetParentRect, offsetParentCStyle);
1439
1805
  let newX = currentXy.x;
1440
1806
  let newY = currentXy.y;
1807
+ //edge detect
1441
1808
  if (scroll) {
1442
1809
  const lX = pointX - offsetParentRect.x;
1443
1810
  const lY = pointY - offsetParentRect.y;
@@ -1474,8 +1841,9 @@ class Draggable extends Uii {
1474
1841
  }
1475
1842
  }
1476
1843
  }
1477
- let x = newX - offsetPointX + 0;
1478
- let y = newY - offsetPointY + 0;
1844
+ let x = newX - offsetPointX;
1845
+ let y = newY - offsetPointY;
1846
+ //grid
1479
1847
  if (isNumber(gridX) && isNumber(gridY)) {
1480
1848
  x = ((x / gridX) >> 0) * gridX;
1481
1849
  y = ((y / gridY) >> 0) * gridY;
@@ -1501,24 +1869,29 @@ class Draggable extends Uii {
1501
1869
  const currPageY1 = y;
1502
1870
  const currPageX2 = currPageX1 + originW;
1503
1871
  const currPageY2 = currPageY1 + originH;
1872
+ //check snappable
1504
1873
  let snapX = NaN, snapY = NaN;
1505
1874
  let targetX, targetY;
1506
1875
  let snapDirX, snapDirY;
1507
1876
  if (!direction || direction === "v") {
1508
1877
  each(snappable, (data) => {
1509
1878
  if (Math.abs(data.y1 - currPageY1) <= snapTolerance) {
1879
+ //top parallel
1510
1880
  snapY = data.y1;
1511
1881
  snapDirY = "t2t";
1512
1882
  }
1513
1883
  else if (Math.abs(data.y2 - currPageY1) <= snapTolerance) {
1884
+ //b2t
1514
1885
  snapY = data.y2;
1515
1886
  snapDirY = "t2b";
1516
1887
  }
1517
1888
  else if (Math.abs(data.y1 - currPageY2) <= snapTolerance) {
1889
+ //t2b
1518
1890
  snapY = data.y1 - originH;
1519
1891
  snapDirY = "b2t";
1520
1892
  }
1521
1893
  else if (Math.abs(data.y2 - currPageY2) <= snapTolerance) {
1894
+ //bottom parallel
1522
1895
  snapY = data.y2 - originH;
1523
1896
  snapDirY = "b2b";
1524
1897
  }
@@ -1532,18 +1905,22 @@ class Draggable extends Uii {
1532
1905
  if (!direction || direction === "h") {
1533
1906
  each(snappable, (data) => {
1534
1907
  if (Math.abs(data.x1 - currPageX1) <= snapTolerance) {
1908
+ //left parallel
1535
1909
  snapX = data.x1;
1536
1910
  snapDirX = "l2l";
1537
1911
  }
1538
1912
  else if (Math.abs(data.x2 - currPageX1) <= snapTolerance) {
1913
+ //r2l
1539
1914
  snapX = data.x2;
1540
1915
  snapDirX = "l2r";
1541
1916
  }
1542
1917
  else if (Math.abs(data.x1 - currPageX2) <= snapTolerance) {
1918
+ //l2r
1543
1919
  snapX = data.x1 - originW;
1544
1920
  snapDirX = "r2l";
1545
1921
  }
1546
1922
  else if (Math.abs(data.x2 - currPageX2) <= snapTolerance) {
1923
+ //right parallel
1547
1924
  snapX = data.x2 - originW;
1548
1925
  snapDirX = "r2r";
1549
1926
  }
@@ -1563,6 +1940,7 @@ class Draggable extends Uii {
1563
1940
  }
1564
1941
  if (onSnap && lastSnapping !== lastSnapDirX + "" + lastSnapDirY) {
1565
1942
  setTimeout(() => {
1943
+ //emit after relocate
1566
1944
  onSnap({
1567
1945
  el: copyNode || dragDom,
1568
1946
  targetH: targetX,
@@ -1615,6 +1993,7 @@ class Draggable extends Uii {
1615
1993
  timer = null;
1616
1994
  }
1617
1995
  }
1996
+ //restore classes
1618
1997
  dragDom.classList.remove(...compact(split(classes, ' ')));
1619
1998
  currentStyle.zIndex = originalZIndex;
1620
1999
  dragDom.classList.remove(CLASS_DRAGGABLE_ACTIVE);
@@ -1622,6 +2001,7 @@ class Draggable extends Uii {
1622
2001
  if (onEnd) {
1623
2002
  moveToGhost = onEnd({ draggable: dragDom, x: endX, y: endY }, ev) === false ? false : true;
1624
2003
  }
2004
+ //notify
1625
2005
  const customEv = new Event("uii-dragdeactive", { "bubbles": true, "cancelable": false });
1626
2006
  dragDom.dispatchEvent(customEv);
1627
2007
  if (ghost) {
@@ -1636,6 +2016,9 @@ class Draggable extends Uii {
1636
2016
  lockPage: true
1637
2017
  });
1638
2018
  }
2019
+ /**
2020
+ * @internal
2021
+ */
1639
2022
  onOptionChanged(opts) {
1640
2023
  const droppable = opts.droppable;
1641
2024
  if (!isFunction(droppable)) {
@@ -1661,7 +2044,7 @@ _Draggable_handleMap = new WeakMap(), _Draggable_container = new WeakMap(), _Dra
1661
2044
  el.classList.toggle(CLASS_DRAGGABLE, true);
1662
2045
  const ee = __classPrivateFieldGet(this, _Draggable_handleMap, "f").get(el) || el;
1663
2046
  ee.classList.toggle(CLASS_DRAGGABLE_HANDLE, true);
1664
- if (isDefined(this.opts.cursor)) {
2047
+ if (!isUndefined(this.opts.cursor)) {
1665
2048
  el.style.cursor = this.opts.cursor.default || 'move';
1666
2049
  if (isDefined(this.opts.cursor.over)) {
1667
2050
  el.dataset.cursorOver = this.opts.cursor.over;
@@ -1670,6 +2053,12 @@ _Draggable_handleMap = new WeakMap(), _Draggable_container = new WeakMap(), _Dra
1670
2053
  }
1671
2054
  });
1672
2055
  };
2056
+ /**
2057
+ * create a draggable pattern for one or more elements with opts
2058
+ * @param els selector string / html element
2059
+ * @param opts
2060
+ * @returns Draggable instance
2061
+ */
1673
2062
  function newDraggable(els, opts) {
1674
2063
  return new Draggable(els, opts);
1675
2064
  }
@@ -1677,13 +2066,23 @@ function newDraggable(els, opts) {
1677
2066
  var _Droppable_active;
1678
2067
  const Droppables = [];
1679
2068
  const CLASS_DROPPABLE = "uii-droppable";
2069
+ /**
2070
+ * 用于表示一个或多个可响应拖动元素的定义
2071
+ * > 可用CSS接口
2072
+ * - .uii-droppable
2073
+ * @public
2074
+ */
1680
2075
  class Droppable extends Uii {
1681
2076
  constructor(el, opts) {
1682
2077
  super(el, assign({}, opts));
1683
2078
  _Droppable_active.set(this, void 0);
1684
2079
  Droppables.push(this);
1685
2080
  }
2081
+ /**
2082
+ * @internal
2083
+ */
1686
2084
  bindEvent(droppable, opts) {
2085
+ //dragenter
1687
2086
  this.registerEvent(droppable, "mouseenter", (e) => {
1688
2087
  if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1689
2088
  return;
@@ -1697,6 +2096,7 @@ class Droppable extends Uii {
1697
2096
  }
1698
2097
  opts.onEnter && opts.onEnter({ draggable: __classPrivateFieldGet(this, _Droppable_active, "f"), droppable }, e);
1699
2098
  });
2099
+ //dragleave
1700
2100
  this.registerEvent(droppable, "mouseleave", (e) => {
1701
2101
  if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1702
2102
  return;
@@ -1710,11 +2110,13 @@ class Droppable extends Uii {
1710
2110
  }
1711
2111
  opts.onLeave && opts.onLeave({ draggable: __classPrivateFieldGet(this, _Droppable_active, "f"), droppable }, e);
1712
2112
  });
2113
+ //dragover
1713
2114
  this.registerEvent(droppable, "mousemove", (e) => {
1714
2115
  if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1715
2116
  return;
1716
2117
  opts.onOver && opts.onOver({ draggable: __classPrivateFieldGet(this, _Droppable_active, "f"), droppable }, e);
1717
2118
  });
2119
+ //drop
1718
2120
  this.registerEvent(droppable, "mouseup", (e) => {
1719
2121
  if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1720
2122
  return;
@@ -1726,9 +2128,13 @@ class Droppable extends Uii {
1726
2128
  opts.onDrop && opts.onDrop({ draggable: __classPrivateFieldGet(this, _Droppable_active, "f"), droppable }, e);
1727
2129
  });
1728
2130
  }
2131
+ /**
2132
+ * @internal
2133
+ */
1729
2134
  active(target) {
1730
2135
  let valid = true;
1731
2136
  const opts = this.opts;
2137
+ //check accepts
1732
2138
  if (isString(opts.accepts)) {
1733
2139
  valid = !!target.dataset.dropType && test(opts.accepts, target.dataset.dropType);
1734
2140
  }
@@ -1746,12 +2152,16 @@ class Droppable extends Uii {
1746
2152
  });
1747
2153
  }
1748
2154
  opts.onActive && opts.onActive({ draggable: target, droppables: this.ele });
2155
+ //bind events
1749
2156
  each(this.ele, (el) => {
1750
2157
  el.classList.toggle(CLASS_DROPPABLE, true);
1751
2158
  el.style.pointerEvents = 'initial';
1752
2159
  this.bindEvent(el, opts);
1753
2160
  });
1754
2161
  }
2162
+ /**
2163
+ * @internal
2164
+ */
1755
2165
  deactive(target) {
1756
2166
  if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1757
2167
  return;
@@ -1765,10 +2175,12 @@ class Droppable extends Uii {
1765
2175
  });
1766
2176
  }
1767
2177
  opts.onDeactive && opts.onDeactive({ draggable: target, droppables: this.ele });
2178
+ //unbind events
1768
2179
  this.destroy();
1769
2180
  }
1770
2181
  }
1771
2182
  _Droppable_active = new WeakMap();
2183
+ //uii-drag active
1772
2184
  document.addEventListener("uii-dragactive", (e) => {
1773
2185
  each(Droppables, dpb => {
1774
2186
  dpb.active(e.target);
@@ -1779,18 +2191,41 @@ document.addEventListener("uii-dragdeactive", (e) => {
1779
2191
  dpb.deactive(e.target);
1780
2192
  });
1781
2193
  });
2194
+ /**
2195
+ * Enable els to response to draggable objects
2196
+ * @param els selector string / html element
2197
+ * @param opts
2198
+ * @returns
2199
+ */
1782
2200
  function newDroppable(els, opts) {
1783
2201
  return new Droppable(els, opts);
1784
2202
  }
1785
2203
 
2204
+ /* eslint-disable max-len */
1786
2205
  const THRESHOLD$2 = 2;
1787
2206
  const CLASS_ROTATABLE = "uii-rotatable";
1788
2207
  const CLASS_ROTATABLE_HANDLE = "uii-rotatable-handle";
1789
2208
  const CLASS_ROTATABLE_ACTIVE = "uii-rotatable-active";
2209
+ /**
2210
+ * 用于表示一个或多个可旋转元素的定义
2211
+ * > 可用CSS接口
2212
+ * - .uii-rotatable
2213
+ * - .uii-rotatable-handle
2214
+ * - .uii-rotatable-active
2215
+ * @public
2216
+ */
1790
2217
  class Rotatable extends Uii {
1791
2218
  constructor(els, opts) {
1792
2219
  super(els, opts);
1793
2220
  each(this.ele, (el) => {
2221
+ let tmp = el;
2222
+ if (tmp._uiik_rotatable) {
2223
+ tmp._uiik_rotatable.destroy();
2224
+ return false;
2225
+ }
2226
+ });
2227
+ each(this.ele, (el) => {
2228
+ el._uiik_rotatable = this;
1794
2229
  initHandle(this, el, this.opts);
1795
2230
  });
1796
2231
  }
@@ -1822,29 +2257,56 @@ function bindHandle(uiik, handle, el, opts) {
1822
2257
  const onEnd = opts.onEnd;
1823
2258
  let deg = 0;
1824
2259
  uiik.addPointerDown(handle, ({ onPointerStart, onPointerMove, onPointerEnd }) => {
1825
- const { x, y, ox, oy } = getCenterXy(el);
1826
- let centerX = x, centerY = y;
2260
+ let centerX = 0, centerY = 0;
2261
+ let startOx = 0;
2262
+ let startOy = 0;
1827
2263
  let startDeg = 0;
2264
+ let container;
2265
+ //bind events
1828
2266
  onPointerStart(function (args) {
1829
2267
  const { ev } = args;
1830
- const currentXy = getPointInContainer(ev, el.parentElement);
2268
+ const { w, h } = getStyleSize(el);
2269
+ const { originX, originY } = parseOxy(opts.ox, opts.oy, w, h);
2270
+ startOx = originX;
2271
+ startOy = originY;
2272
+ const { x, y, ox, oy } = el instanceof SVGGraphicsElement
2273
+ ? getCenterXySVG(el, startOx, startOy)
2274
+ : getCenterXy(el, startOx, startOy);
2275
+ (centerX = x), (centerY = y);
2276
+ (startOx = ox), (startOy = oy);
2277
+ container =
2278
+ el instanceof SVGGraphicsElement
2279
+ ? closest(el, (ele) => lowerCase(ele.tagName) === "svg", "parentNode")
2280
+ : el.parentElement;
2281
+ const currentXy = getPointInContainer(ev, container);
1831
2282
  startDeg =
1832
- Math.atan2(currentXy.y - centerY, currentXy.x - centerX) * ONE_RAD + 90;
2283
+ Math.atan2(currentXy.y - centerY, currentXy.x - centerX) * ONE_RAD +
2284
+ 90;
1833
2285
  if (startDeg < 0)
1834
2286
  startDeg = 360 + startDeg;
1835
2287
  let matrixInfo = getMatrixInfo(el);
1836
2288
  startDeg -= matrixInfo.angle;
2289
+ //apply classes
1837
2290
  el.classList.toggle(CLASS_ROTATABLE_ACTIVE, true);
1838
2291
  onStart && onStart({ deg, cx: centerX, cy: centerY }, ev);
1839
2292
  });
1840
2293
  onPointerMove((args) => {
1841
2294
  const { ev } = args;
1842
- const currentXy = getPointInContainer(ev, el.parentElement);
2295
+ const currentXy = getPointInContainer(ev, container);
1843
2296
  deg =
1844
2297
  Math.atan2(currentXy.y - centerY, currentXy.x - centerX) * ONE_RAD +
1845
- 90 - startDeg;
1846
- onRotate && onRotate({ deg, cx: centerX, cy: centerY }, ev);
1847
- rotateTo(el, deg, ox, oy);
2298
+ 90 -
2299
+ startDeg;
2300
+ onRotate &&
2301
+ onRotate({
2302
+ deg,
2303
+ cx: centerX,
2304
+ cy: centerY,
2305
+ target: el,
2306
+ ox: startOx,
2307
+ oy: startOy,
2308
+ }, ev);
2309
+ rotateTo(el, deg, startOx, startOy);
1848
2310
  });
1849
2311
  onPointerEnd((args) => {
1850
2312
  const { ev } = args;
@@ -1856,6 +2318,12 @@ function bindHandle(uiik, handle, el, opts) {
1856
2318
  lockPage: true,
1857
2319
  });
1858
2320
  }
2321
+ /**
2322
+ * Make els rotatable
2323
+ * @param els selector string / html element
2324
+ * @param opts
2325
+ * @returns
2326
+ */
1859
2327
  function newRotatable(els, opts) {
1860
2328
  return new Rotatable(els, opts);
1861
2329
  }
@@ -1876,6 +2344,7 @@ class CollisionDetector {
1876
2344
  }
1877
2345
  const ele = domEl;
1878
2346
  this.el = domEl;
2347
+ //el data
1879
2348
  const offset = getBox(ele, this.opts.container);
1880
2349
  const rect = { x: offset.x, y: offset.y, width: ele.offsetWidth, height: ele.offsetHeight };
1881
2350
  this.elData = {
@@ -1884,8 +2353,12 @@ class CollisionDetector {
1884
2353
  x2: rect.x + rect.width,
1885
2354
  y2: rect.y + rect.height,
1886
2355
  };
2356
+ //targets data
1887
2357
  this.update();
1888
2358
  }
2359
+ /**
2360
+ * update targets data if them changed
2361
+ */
1889
2362
  update() {
1890
2363
  let targets;
1891
2364
  if (isFunction(__classPrivateFieldGet(this, _CollisionDetector__targets, "f"))) {
@@ -1950,6 +2423,14 @@ class CollisionDetector {
1950
2423
  }
1951
2424
  }
1952
2425
  _CollisionDetector__targets = new WeakMap();
2426
+ /**
2427
+ * create a detector for the el and return
2428
+ * @param el element to be detected
2429
+ * @param targets
2430
+ * @param opts CollisionDetectorOptions
2431
+ * @param opts.container a root element of targets
2432
+ * @returns
2433
+ */
1953
2434
  function newCollisionDetector(el, targets, opts) {
1954
2435
  return new CollisionDetector(el, targets, opts);
1955
2436
  }
@@ -1959,6 +2440,14 @@ const CLASS_SELECTOR = "uii-selector";
1959
2440
  const CLASS_SELECTING = "uii-selecting";
1960
2441
  const CLASS_SELECTED = "uii-selected";
1961
2442
  const THRESHOLD$1 = 2;
2443
+ /**
2444
+ * 用于表示一个元素选择器的定义
2445
+ * > 可用CSS接口
2446
+ * - .uii-selector
2447
+ * - .uii-selecting
2448
+ * - .uii-selected
2449
+ * @public
2450
+ */
1962
2451
  class Selectable extends Uii {
1963
2452
  constructor(container, opts) {
1964
2453
  super(container, assign({
@@ -1969,6 +2458,7 @@ class Selectable extends Uii {
1969
2458
  _Selectable__detector.set(this, void 0);
1970
2459
  _Selectable__lastSelected.set(this, void 0);
1971
2460
  const domEl = this.ele[0];
2461
+ //create selector
1972
2462
  let selector = document.createElement("div");
1973
2463
  if (domEl instanceof SVGElement) {
1974
2464
  selector = document.createElementNS('http://www.w3.org/2000/svg', "rect");
@@ -1986,14 +2476,21 @@ class Selectable extends Uii {
1986
2476
  }
1987
2477
  selector.style.display = 'none';
1988
2478
  domEl.appendChild(selector);
2479
+ //create detector
1989
2480
  __classPrivateFieldSet(this, _Selectable__detector, newCollisionDetector(selector, this.opts.targets, {
1990
2481
  container: domEl,
1991
2482
  }), "f");
1992
2483
  __classPrivateFieldGet(this, _Selectable_instances, "m", _Selectable_bindEvent).call(this, selector, domEl);
1993
2484
  }
2485
+ /**
2486
+ * 更新targets
2487
+ */
1994
2488
  updateTargets() {
1995
2489
  __classPrivateFieldGet(this, _Selectable__detector, "f").update();
1996
2490
  }
2491
+ /**
2492
+ * @internal
2493
+ */
1997
2494
  onOptionChanged() {
1998
2495
  this.updateTargets();
1999
2496
  }
@@ -2011,17 +2508,19 @@ _Selectable__detector = new WeakMap(), _Selectable__lastSelected = new WeakMap()
2011
2508
  const filter = opts.filter;
2012
2509
  const selectingClassAry = compact(split(opts.selectingClass, " "));
2013
2510
  const selectedClassAry = compact(split(opts.selectedClass, " "));
2511
+ //check filter
2014
2512
  if (filter) {
2015
2513
  if (isFunction(filter)) {
2016
2514
  if (filter(target))
2017
- return;
2515
+ return true;
2018
2516
  }
2019
2517
  else if (some(con.querySelectorAll(filter), (el) => el.contains(target)))
2020
- return;
2518
+ return true;
2021
2519
  }
2520
+ //检测
2022
2521
  const onPointerDown = opts.onPointerDown;
2023
2522
  if (onPointerDown && onPointerDown(ev) === false)
2024
- return;
2523
+ return true;
2025
2524
  let originPos = "";
2026
2525
  let matrixInfo = getMatrixInfo(currentCStyle);
2027
2526
  const startxy = getPointInContainer(ev, con, currentRect, currentCStyle, matrixInfo);
@@ -2036,14 +2535,18 @@ _Selectable__detector = new WeakMap(), _Selectable__lastSelected = new WeakMap()
2036
2535
  let toTop = false;
2037
2536
  let toRight = false;
2038
2537
  let toBottom = false;
2538
+ //bind events
2039
2539
  onPointerStart(function (args) {
2040
2540
  const { ev } = args;
2541
+ //update targets count & positions
2041
2542
  __classPrivateFieldGet(that, _Selectable__detector, "f").update();
2543
+ //detect container position
2042
2544
  const pos = currentCStyle.position;
2043
2545
  if (pos === "static") {
2044
2546
  originPos = con.style.position;
2045
2547
  con.style.position = "relative";
2046
2548
  }
2549
+ //clear _lastSelected
2047
2550
  each(__classPrivateFieldGet(that, _Selectable__lastSelected, "f"), t => {
2048
2551
  target.classList.toggle(CLASS_SELECTED, false);
2049
2552
  });
@@ -2052,11 +2555,13 @@ _Selectable__detector = new WeakMap(), _Selectable__lastSelected = new WeakMap()
2052
2555
  });
2053
2556
  onPointerMove((args) => {
2054
2557
  const { ev } = args;
2558
+ //获取当前位置坐标
2055
2559
  const currentXy = getPointInContainer(ev, currentTarget, currentRect, currentCStyle, matrixInfo);
2056
2560
  let pointX = currentXy.x;
2057
2561
  let pointY = currentXy.y;
2058
2562
  let offX = pointX - hitPosX;
2059
2563
  let offY = pointY - hitPosY;
2564
+ //edge detect
2060
2565
  if (scroll) {
2061
2566
  const ltX = ev.clientX - currentRect.x;
2062
2567
  const ltY = ev.clientY - currentRect.y;
@@ -2109,6 +2614,7 @@ _Selectable__detector = new WeakMap(), _Selectable__lastSelected = new WeakMap()
2109
2614
  style.width = w + "px";
2110
2615
  style.height = h + "px";
2111
2616
  style.transform = `translate3d(${x}px,${y}px,0)`;
2617
+ //detect collision
2112
2618
  if (mode === "overlap") {
2113
2619
  selection = __classPrivateFieldGet(that, _Selectable__detector, "f").getOverlaps(x1, y1, x1 + w, y1 + h);
2114
2620
  }
@@ -2143,6 +2649,7 @@ _Selectable__detector = new WeakMap(), _Selectable__lastSelected = new WeakMap()
2143
2649
  timer = null;
2144
2650
  }
2145
2651
  }
2652
+ //restore container position
2146
2653
  if (originPos) {
2147
2654
  con.style.position = originPos;
2148
2655
  }
@@ -2165,6 +2672,12 @@ _Selectable__detector = new WeakMap(), _Selectable__lastSelected = new WeakMap()
2165
2672
  lockPage: true
2166
2673
  });
2167
2674
  };
2675
+ /**
2676
+ * Add a selector into the container
2677
+ * @param container css selector or html element
2678
+ * @param opts
2679
+ * @returns
2680
+ */
2168
2681
  function newSelectable(container, opts) {
2169
2682
  return new Selectable(container, opts);
2170
2683
  }
@@ -2176,6 +2689,14 @@ const CLASS_SORTABLE_GHOST = "uii-sortable-ghost";
2176
2689
  const CLASS_SORTABLE_ACTIVE = "uii-sortable-active";
2177
2690
  const ATTR_SORTABLE_ACTIVE = "uii-sortable-active";
2178
2691
  const THRESHOLD = 2;
2692
+ /**
2693
+ * 用于表示一类排序容器的定义
2694
+ * > 可用CSS接口
2695
+ * - .uii-sortable-container
2696
+ * - .uii-sortable-ghost
2697
+ * - .uii-sortable-active
2698
+ * @public
2699
+ */
2179
2700
  class Sortable extends Uii {
2180
2701
  constructor(container, opts) {
2181
2702
  super(container, merge({
@@ -2196,6 +2717,7 @@ class Sortable extends Uii {
2196
2717
  el.style.pointerEvents = "initial";
2197
2718
  bindContainer(this.registerEvent.bind(this), el, this.opts);
2198
2719
  });
2720
+ //put into group
2199
2721
  if (this.opts.group) {
2200
2722
  if (!SORTABLE_GROUPS[this.opts.group]) {
2201
2723
  SORTABLE_GROUPS[this.opts.group] = [];
@@ -2203,10 +2725,16 @@ class Sortable extends Uii {
2203
2725
  SORTABLE_GROUPS[this.opts.group].push([this, this.ele]);
2204
2726
  }
2205
2727
  }
2728
+ /**
2729
+ * 调用active表示移出策略肯定是true | 'copy'
2730
+ * @internal
2731
+ */
2206
2732
  active(draggingItem, fromContainer, toContainers, toOpts) {
2207
2733
  var _a;
2734
+ //check move
2208
2735
  const moveFrom = (_a = toOpts.move) === null || _a === void 0 ? void 0 : _a.from;
2209
2736
  const acceptFn = isFunction(moveFrom) ? moveFrom : () => !!moveFrom;
2737
+ //验证移入策略
2210
2738
  const activableContainers = flatMap(toContainers, (el) => {
2211
2739
  const valid = acceptFn(draggingItem, fromContainer, el);
2212
2740
  return valid ? el : [];
@@ -2226,6 +2754,9 @@ class Sortable extends Uii {
2226
2754
  toOpts.onActive &&
2227
2755
  toOpts.onActive({ item: draggingItem, from: fromContainer });
2228
2756
  }
2757
+ /**
2758
+ * @internal
2759
+ */
2229
2760
  deactive(draggingItem, fromContainer, toContainers, opts) {
2230
2761
  each(toContainers, (el) => {
2231
2762
  el.removeAttribute(ATTR_SORTABLE_ACTIVE);
@@ -2241,6 +2772,9 @@ class Sortable extends Uii {
2241
2772
  opts.onDeactive &&
2242
2773
  opts.onDeactive({ item: draggingItem, from: fromContainer });
2243
2774
  }
2775
+ /**
2776
+ * @internal
2777
+ */
2244
2778
  onOptionChanged() { }
2245
2779
  }
2246
2780
  _Sortable_removeListenItems = new WeakMap();
@@ -2252,6 +2786,7 @@ function bindContainer(registerEvent, container, opts) {
2252
2786
  let t = e.target;
2253
2787
  if (t === con)
2254
2788
  return;
2789
+ // filter & handle
2255
2790
  const filterStr = opts.filter ? `:not(${opts.filter})` : "";
2256
2791
  const filteredItems = con.querySelectorAll(":scope > *" + filterStr);
2257
2792
  const handles = opts.handle
@@ -2319,6 +2854,7 @@ function bindContainer(registerEvent, container, opts) {
2319
2854
  if (sort) {
2320
2855
  removeListenItems = listenItems(opts, con, toCopy ? draggingItem : copy, filteredItems, i);
2321
2856
  }
2857
+ //active
2322
2858
  if (moveMode && group && SORTABLE_GROUPS[group]) {
2323
2859
  each(SORTABLE_GROUPS[group], ([sortable, ele]) => {
2324
2860
  const filtered = reject(ele, (el) => el === container);
@@ -2354,6 +2890,7 @@ function bindContainer(registerEvent, container, opts) {
2354
2890
  DraggingData = null;
2355
2891
  if (removeListenItems)
2356
2892
  removeListenItems();
2893
+ //deactive
2357
2894
  if (group && SORTABLE_GROUPS[group]) {
2358
2895
  each(SORTABLE_GROUPS[group], ([sortable, ele]) => {
2359
2896
  const filtered = reject(ele, (el) => el === container);
@@ -2392,6 +2929,7 @@ function bindContainer(registerEvent, container, opts) {
2392
2929
  }
2393
2930
  }
2394
2931
  });
2932
+ //总是先触发容器enter,之后才是itementer
2395
2933
  registerEvent(container, "mouseenter", (e) => {
2396
2934
  var _a;
2397
2935
  if (!DraggingData)
@@ -2428,6 +2966,7 @@ function bindContainer(registerEvent, container, opts) {
2428
2966
  DraggingData.toContainer = container;
2429
2967
  if (container.getAttribute(ATTR_SORTABLE_ACTIVE)) {
2430
2968
  let valid = true;
2969
+ //check move
2431
2970
  const moveFrom = (_a = opts.move) === null || _a === void 0 ? void 0 : _a.from;
2432
2971
  const acceptFn = isFunction(moveFrom) ? moveFrom : () => !!moveFrom;
2433
2972
  valid = acceptFn(DraggingData.item, DraggingData.fromContainer, container);
@@ -2436,6 +2975,7 @@ function bindContainer(registerEvent, container, opts) {
2436
2975
  if (container.contains(draggingItem)) {
2437
2976
  return;
2438
2977
  }
2978
+ //此处检测移出策略
2439
2979
  const moveTo = DraggingData.moveTo;
2440
2980
  if (moveTo === "copy") {
2441
2981
  draggingItem = DraggingData.copy;
@@ -2479,6 +3019,7 @@ function bindContainer(registerEvent, container, opts) {
2479
3019
  });
2480
3020
  }
2481
3021
  function listenItems(opts, toContainer, draggingItem, items, fromIndex = 0) {
3022
+ //sorting listener
2482
3023
  const listener = (e) => {
2483
3024
  const ct = e.currentTarget;
2484
3025
  if (ct.style.transform) {
@@ -2540,6 +3081,7 @@ function listenItems(opts, toContainer, draggingItem, items, fromIndex = 0) {
2540
3081
  item.addEventListener("mouseenter", listener);
2541
3082
  });
2542
3083
  return () => {
3084
+ //解绑enter事件
2543
3085
  each(items, (item, i) => {
2544
3086
  if (item === draggingItem)
2545
3087
  return;
@@ -2547,16 +3089,23 @@ function listenItems(opts, toContainer, draggingItem, items, fromIndex = 0) {
2547
3089
  });
2548
3090
  };
2549
3091
  }
3092
+ /**
3093
+ * make elements within the container sortable
3094
+ * @param container css selector or html element(array)
3095
+ * @param opts
3096
+ * @returns
3097
+ */
2550
3098
  function newSortable(container, opts) {
2551
3099
  return new Sortable(container, opts);
2552
3100
  }
2553
3101
 
2554
- var version = "1.3.0-alpha";
3102
+ var version = "1.3.0-beta.1";
2555
3103
  var repository = {
2556
3104
  type: "git",
2557
3105
  url: "https://github.com/holyhigh2/uiik"
2558
3106
  };
2559
3107
 
3108
+ // welcome info
2560
3109
  const welcome = globalThis.welcome;
2561
3110
  if (!welcome) {
2562
3111
  const ssAry = [];
@@ -2584,4 +3133,4 @@ var index = {
2584
3133
  newSortable
2585
3134
  };
2586
3135
 
2587
- export { CollisionDetector, DRAGGING_RULE, Draggable, Droppable, EDGE_THRESHOLD, ONE_ANG, ONE_RAD, Resizable, Rotatable, Selectable, Sortable, Splittable, Uii, UiiTransformer, VERSION, index as default, getBox, getCenterXy, getMatrixInfo, getPointInContainer, getPointOffset, getRectInContainer, getStyleXy, getTranslate, isSVGEl, lockPage, moveBy, moveTo, newCollisionDetector, newDraggable, newDroppable, newResizable, newRotatable, newSelectable, newSortable, newSplittable, restoreCursor, rotateTo, saveCursor, setCursor, unlockPage, wrapper };
3136
+ export { CollisionDetector, DRAGGING_RULE, Draggable, Droppable, EDGE_THRESHOLD, ONE_ANG, ONE_RAD, Resizable, Rotatable, Selectable, Sortable, Splittable, Uii, UiiTransformer, VERSION, calcVertex, index as default, getBox, getCenterXy, getCenterXySVG, getMatrixInfo, getPointInContainer, getPointOffset, getRectInContainer, getStyleSize, getStyleXy, getTranslate, getVertex, isSVGEl, lockPage, moveBy, moveTo, newCollisionDetector, newDraggable, newDroppable, newResizable, newRotatable, newSelectable, newSortable, newSplittable, parseOxy, restoreCursor, rotateTo, saveCursor, setCursor, unlockPage, wrapper };