tiny-essentials 1.12.0 → 1.12.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/dist/v1/TinyDragger.js +148 -43
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyEssentials.js +148 -43
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyUploadClicker.js +148 -43
- package/dist/v1/libs/TinyDragger.cjs +148 -43
- package/dist/v1/libs/TinyDragger.d.mts +18 -2
- package/dist/v1/libs/TinyDragger.mjs +132 -38
- package/docs/v1/libs/TinyDragger.md +15 -0
- package/package.json +1 -1
|
@@ -7132,6 +7132,7 @@ class TinyDragger {
|
|
|
7132
7132
|
#offsetY = 0;
|
|
7133
7133
|
#offsetX = 0;
|
|
7134
7134
|
|
|
7135
|
+
#multiCollision = false;
|
|
7135
7136
|
#lockInsideJail = false;
|
|
7136
7137
|
#revertOnDrop = false;
|
|
7137
7138
|
#dragging = false;
|
|
@@ -7176,6 +7177,7 @@ class TinyDragger {
|
|
|
7176
7177
|
* @param {string} [options.classDragCollision='dragging-collision'] - CSS class applied to collision element.
|
|
7177
7178
|
* @param {boolean} [options.lockInsideJail=false] - Restrict movement within the jail container.
|
|
7178
7179
|
* @param {boolean} [options.dropInJailOnly=false] - Restrict drop within the jail container.
|
|
7180
|
+
* @param {boolean} [options.multiCollision=false] - Enables returning multiple collided elements.
|
|
7179
7181
|
* @param {VibrationPatterns|false} [options.vibration=false] - Vibration feedback configuration.
|
|
7180
7182
|
* @param {boolean} [options.revertOnDrop=false] - Whether to return to original position on drop.
|
|
7181
7183
|
* @param {string} [options.classHidden='drag-hidden'] - CSS class to hide original element during dragging.
|
|
@@ -7222,6 +7224,7 @@ class TinyDragger {
|
|
|
7222
7224
|
validateBoolean(options.lockInsideJail, 'lockInsideJail');
|
|
7223
7225
|
validateBoolean(options.dropInJailOnly, 'dropInJailOnly');
|
|
7224
7226
|
validateBoolean(options.revertOnDrop, 'revertOnDrop');
|
|
7227
|
+
validateBoolean(options.multiCollision, 'multiCollision');
|
|
7225
7228
|
|
|
7226
7229
|
validateString(options.classDragging, 'classDragging');
|
|
7227
7230
|
validateString(options.classBodyDragging, 'classBodyDragging');
|
|
@@ -7255,6 +7258,7 @@ class TinyDragger {
|
|
|
7255
7258
|
if (typeof options.revertOnDrop === 'boolean') this.#revertOnDrop = options.revertOnDrop;
|
|
7256
7259
|
if (typeof options.lockInsideJail === 'boolean') this.#lockInsideJail = options.lockInsideJail;
|
|
7257
7260
|
if (typeof options.dropInJailOnly === 'boolean') this.#dropInJailOnly = options.dropInJailOnly;
|
|
7261
|
+
if (typeof options.multiCollision === 'boolean') this.#multiCollision = options.multiCollision;
|
|
7258
7262
|
|
|
7259
7263
|
/** @private */
|
|
7260
7264
|
this._onMouseDown = this.#startDrag.bind(this);
|
|
@@ -7446,22 +7450,67 @@ class TinyDragger {
|
|
|
7446
7450
|
this.#dispatchEvent('drag');
|
|
7447
7451
|
}
|
|
7448
7452
|
|
|
7453
|
+
/** @type {HTMLElement[]} */
|
|
7454
|
+
#collisionsMarked = [];
|
|
7455
|
+
|
|
7456
|
+
/**
|
|
7457
|
+
* Marks an element as currently collided by adding the collision CSS class.
|
|
7458
|
+
* The element is stored in an internal list for easy removal later.
|
|
7459
|
+
*
|
|
7460
|
+
* @param {HTMLElement|null} el - The element to mark as collided.
|
|
7461
|
+
*/
|
|
7462
|
+
#addCollision(el) {
|
|
7463
|
+
if (!el) return;
|
|
7464
|
+
el.classList.add(this.#classDragCollision);
|
|
7465
|
+
this.#collisionsMarked.push(el);
|
|
7466
|
+
}
|
|
7467
|
+
|
|
7468
|
+
/**
|
|
7469
|
+
* Removes the collision CSS class from all previously marked elements.
|
|
7470
|
+
* Also clears the last single collision element, if set.
|
|
7471
|
+
*
|
|
7472
|
+
*/
|
|
7473
|
+
#removeCollision() {
|
|
7474
|
+
while (this.#collisionsMarked.length > 0) {
|
|
7475
|
+
const el = this.#collisionsMarked.shift();
|
|
7476
|
+
if (el) el.classList.remove(this.#classDragCollision);
|
|
7477
|
+
}
|
|
7478
|
+
if (!this.#lastCollision) return;
|
|
7479
|
+
this.#lastCollision.classList.remove(this.#classDragCollision);
|
|
7480
|
+
}
|
|
7481
|
+
|
|
7449
7482
|
/**
|
|
7450
7483
|
* Handles dragging collision.
|
|
7451
7484
|
* @param {MouseEvent|Touch} event - The drag event.
|
|
7452
7485
|
*/
|
|
7453
7486
|
checkDragCollision(event) {
|
|
7454
|
-
const {
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7487
|
+
const { collidedElements } = this.execCollision(event);
|
|
7488
|
+
const first = collidedElements[0] || null;
|
|
7489
|
+
|
|
7490
|
+
// Removes old marking if necessary
|
|
7491
|
+
if (this.#lastCollision && !collidedElements.includes(this.#lastCollision)) {
|
|
7492
|
+
this.#removeCollision();
|
|
7493
|
+
}
|
|
7494
|
+
|
|
7495
|
+
// Adds Marking for All Colluded
|
|
7496
|
+
collidedElements.forEach((el) => this.#addCollision(el));
|
|
7497
|
+
|
|
7498
|
+
// Removes markings from who no longer collided
|
|
7499
|
+
this.#collidables.forEach((el) => {
|
|
7500
|
+
if (!collidedElements.includes(el)) {
|
|
7501
|
+
el.classList.remove(this.#classDragCollision);
|
|
7458
7502
|
}
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
this.#
|
|
7503
|
+
});
|
|
7504
|
+
|
|
7505
|
+
if (
|
|
7506
|
+
navigator.vibrate &&
|
|
7507
|
+
Array.isArray(this.#vibration.collide) &&
|
|
7508
|
+
collidedElements.length > 0
|
|
7509
|
+
) {
|
|
7510
|
+
navigator.vibrate(this.#vibration.collide);
|
|
7464
7511
|
}
|
|
7512
|
+
|
|
7513
|
+
this.#lastCollision = first;
|
|
7465
7514
|
}
|
|
7466
7515
|
|
|
7467
7516
|
/**
|
|
@@ -7508,37 +7557,48 @@ class TinyDragger {
|
|
|
7508
7557
|
/**
|
|
7509
7558
|
* Handles the collision of a drag.
|
|
7510
7559
|
* @param {MouseEvent|Touch} event - The release event.
|
|
7511
|
-
* @returns {{ inJail: boolean;
|
|
7560
|
+
* @returns {{ inJail: boolean; collidedElements: (HTMLElement | null)[] }}
|
|
7512
7561
|
*/
|
|
7513
7562
|
execCollision(event) {
|
|
7514
|
-
if (this.#destroyed || !this.#dragProxy) return { inJail: false,
|
|
7563
|
+
if (this.#destroyed || !this.#dragProxy) return { inJail: false, collidedElements: [] };
|
|
7515
7564
|
|
|
7516
|
-
let
|
|
7565
|
+
let collidedElements = [];
|
|
7517
7566
|
let inJail = true;
|
|
7518
7567
|
const jailRect = this.#jail?.getBoundingClientRect();
|
|
7568
|
+
|
|
7519
7569
|
if (this.#collisionByMouse) {
|
|
7520
7570
|
const x = event.clientX;
|
|
7521
7571
|
const y = event.clientY;
|
|
7572
|
+
|
|
7522
7573
|
if (this.#dropInJailOnly && this.#jail && jailRect) {
|
|
7523
7574
|
inJail =
|
|
7524
7575
|
x >= jailRect.left && x <= jailRect.right && y >= jailRect.top && y <= jailRect.bottom;
|
|
7525
7576
|
}
|
|
7526
7577
|
|
|
7527
|
-
|
|
7578
|
+
collidedElements = inJail
|
|
7579
|
+
? this.#multiCollision
|
|
7580
|
+
? this.getAllCollidedElements(x, y)
|
|
7581
|
+
: [this.getCollidedElement(x, y)].filter(Boolean)
|
|
7582
|
+
: [];
|
|
7528
7583
|
} else {
|
|
7529
|
-
const
|
|
7584
|
+
const rect = this.#dragProxy.getBoundingClientRect();
|
|
7585
|
+
|
|
7530
7586
|
if (this.#dropInJailOnly && this.#jail && jailRect) {
|
|
7531
7587
|
inJail =
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7588
|
+
rect.left >= jailRect.left &&
|
|
7589
|
+
rect.right <= jailRect.right &&
|
|
7590
|
+
rect.top >= jailRect.top &&
|
|
7591
|
+
rect.bottom <= jailRect.bottom;
|
|
7536
7592
|
}
|
|
7537
7593
|
|
|
7538
|
-
|
|
7594
|
+
collidedElements = inJail
|
|
7595
|
+
? this.#multiCollision
|
|
7596
|
+
? this.getAllCollidedElementsByRect(rect)
|
|
7597
|
+
: [this.getCollidedElementByRect(rect)].filter(Boolean)
|
|
7598
|
+
: [];
|
|
7539
7599
|
}
|
|
7540
7600
|
|
|
7541
|
-
return { inJail,
|
|
7601
|
+
return { inJail, collidedElements };
|
|
7542
7602
|
}
|
|
7543
7603
|
|
|
7544
7604
|
/**
|
|
@@ -7561,7 +7621,7 @@ class TinyDragger {
|
|
|
7561
7621
|
|
|
7562
7622
|
document.removeEventListener('touchmove', this._onTouchMove);
|
|
7563
7623
|
document.removeEventListener('touchend', this._onTouchEnd);
|
|
7564
|
-
const {
|
|
7624
|
+
const { collidedElements } = this.execCollision(event);
|
|
7565
7625
|
|
|
7566
7626
|
if (navigator.vibrate && Array.isArray(this.#vibration.end)) {
|
|
7567
7627
|
navigator.vibrate(this.#vibration.end);
|
|
@@ -7574,7 +7634,7 @@ class TinyDragger {
|
|
|
7574
7634
|
this.#dragProxy = null;
|
|
7575
7635
|
}
|
|
7576
7636
|
|
|
7577
|
-
if (this.#lastCollision) this.#
|
|
7637
|
+
if (this.#lastCollision) this.#removeCollision();
|
|
7578
7638
|
this.#lastCollision = null;
|
|
7579
7639
|
|
|
7580
7640
|
this.#target.classList.remove(this.#dragHiddenClass);
|
|
@@ -7585,13 +7645,50 @@ class TinyDragger {
|
|
|
7585
7645
|
|
|
7586
7646
|
const dropEvent = new CustomEvent('drop', {
|
|
7587
7647
|
detail: {
|
|
7588
|
-
|
|
7648
|
+
targets: collidedElements,
|
|
7649
|
+
first: collidedElements[0] || null,
|
|
7589
7650
|
},
|
|
7590
7651
|
});
|
|
7591
|
-
|
|
7592
7652
|
this.#target.dispatchEvent(dropEvent);
|
|
7593
7653
|
}
|
|
7594
7654
|
|
|
7655
|
+
/**
|
|
7656
|
+
* Checks if the provided element intersects with the given bounding rectangle.
|
|
7657
|
+
*
|
|
7658
|
+
* @param {HTMLElement} el - The element to test for collision.
|
|
7659
|
+
* @param {DOMRect} rect - The bounding rectangle to check against.
|
|
7660
|
+
* @returns {boolean} True if the element intersects with the rectangle.
|
|
7661
|
+
*/
|
|
7662
|
+
#getCollidedElementByRect(el, rect) {
|
|
7663
|
+
const elRect = el.getBoundingClientRect();
|
|
7664
|
+
return !(
|
|
7665
|
+
rect.right < elRect.left ||
|
|
7666
|
+
rect.left > elRect.right ||
|
|
7667
|
+
rect.bottom < elRect.top ||
|
|
7668
|
+
rect.top > elRect.bottom
|
|
7669
|
+
);
|
|
7670
|
+
}
|
|
7671
|
+
|
|
7672
|
+
/**
|
|
7673
|
+
* Returns all elements currently colliding with the given rectangle.
|
|
7674
|
+
*
|
|
7675
|
+
* @param {DOMRect} rect - Bounding rectangle of the dragged proxy.
|
|
7676
|
+
* @returns {HTMLElement[]} A list of all collided elements.
|
|
7677
|
+
* @throws {Error} If the input is not a valid DOMRect with numeric bounds.
|
|
7678
|
+
*/
|
|
7679
|
+
getAllCollidedElementsByRect(rect) {
|
|
7680
|
+
this.#checkDestroy();
|
|
7681
|
+
if (
|
|
7682
|
+
!(rect instanceof DOMRect) ||
|
|
7683
|
+
typeof rect.left !== 'number' ||
|
|
7684
|
+
typeof rect.right !== 'number' ||
|
|
7685
|
+
typeof rect.top !== 'number' ||
|
|
7686
|
+
typeof rect.bottom !== 'number'
|
|
7687
|
+
)
|
|
7688
|
+
throw new Error('getCollidedElementByRect expects a valid DOMRect object.');
|
|
7689
|
+
return this.#collidables.filter((el) => this.#getCollidedElementByRect(el, rect));
|
|
7690
|
+
}
|
|
7691
|
+
|
|
7595
7692
|
/**
|
|
7596
7693
|
* Detects collision based on rectangle intersection.
|
|
7597
7694
|
* @param {DOMRect} rect - Bounding rectangle of the dragged proxy.
|
|
@@ -7608,18 +7705,32 @@ class TinyDragger {
|
|
|
7608
7705
|
typeof rect.bottom !== 'number'
|
|
7609
7706
|
)
|
|
7610
7707
|
throw new Error('getCollidedElementByRect expects a valid DOMRect object.');
|
|
7708
|
+
return this.#collidables.find((el) => this.#getCollidedElementByRect(el, rect)) || null;
|
|
7709
|
+
}
|
|
7611
7710
|
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7711
|
+
/**
|
|
7712
|
+
* Checks whether a given (x, y) coordinate is inside the bounding rectangle of an element.
|
|
7713
|
+
*
|
|
7714
|
+
* @param {HTMLElement} el - The element to test for collision.
|
|
7715
|
+
* @param {number} x - Horizontal screen coordinate.
|
|
7716
|
+
* @param {number} y - Vertical screen coordinate.
|
|
7717
|
+
* @returns {boolean} True if the point is within the element's bounds.
|
|
7718
|
+
*/
|
|
7719
|
+
#getCollidedElement(el, x, y) {
|
|
7720
|
+
const rect = el.getBoundingClientRect();
|
|
7721
|
+
return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
|
7722
|
+
}
|
|
7723
|
+
|
|
7724
|
+
/**
|
|
7725
|
+
* @param {number} x - Horizontal screen coordinate.
|
|
7726
|
+
* @param {number} y - Vertical screen coordinate.
|
|
7727
|
+
* @returns {HTMLElement[]} The collided element or null.
|
|
7728
|
+
*/
|
|
7729
|
+
getAllCollidedElements(x, y) {
|
|
7730
|
+
this.#checkDestroy();
|
|
7731
|
+
if (typeof x !== 'number' || typeof y !== 'number')
|
|
7732
|
+
throw new Error('getCollidedElement expects numeric x and y coordinates.');
|
|
7733
|
+
return this.#collidables.filter((el) => this.#getCollidedElement(el, x, y));
|
|
7623
7734
|
}
|
|
7624
7735
|
|
|
7625
7736
|
/**
|
|
@@ -7632,13 +7743,7 @@ class TinyDragger {
|
|
|
7632
7743
|
this.#checkDestroy();
|
|
7633
7744
|
if (typeof x !== 'number' || typeof y !== 'number')
|
|
7634
7745
|
throw new Error('getCollidedElement expects numeric x and y coordinates.');
|
|
7635
|
-
|
|
7636
|
-
return (
|
|
7637
|
-
this.#collidables.find((el) => {
|
|
7638
|
-
const rect = el.getBoundingClientRect();
|
|
7639
|
-
return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
|
7640
|
-
}) || null
|
|
7641
|
-
);
|
|
7746
|
+
return this.#collidables.find((el) => this.#getCollidedElement(el, x, y)) || null;
|
|
7642
7747
|
}
|
|
7643
7748
|
|
|
7644
7749
|
/**
|
|
@@ -7888,7 +7993,7 @@ class TinyDragger {
|
|
|
7888
7993
|
document.removeEventListener('touchmove', this._onTouchMove);
|
|
7889
7994
|
document.removeEventListener('touchend', this._onTouchEnd);
|
|
7890
7995
|
|
|
7891
|
-
if (this.#lastCollision) this.#
|
|
7996
|
+
if (this.#lastCollision) this.#removeCollision();
|
|
7892
7997
|
if (this.#dragProxy) {
|
|
7893
7998
|
this.#dragProxy.remove();
|
|
7894
7999
|
this.#dragProxy = null;
|