feat(core): Mixly.Drag添加对移动端触摸手势的支持

This commit is contained in:
王立帮
2025-10-28 17:02:24 +08:00
parent 79688b78c9
commit 947ba5b6c7
2 changed files with 95 additions and 12 deletions

View File

@@ -4,6 +4,10 @@
width: 100%;
cursor: s-resize;
z-index: 100;
transition: opacity 0.2s ease;
touch-action: none;
user-select: none;
-webkit-user-select: none;
}
.vertical-line {
@@ -12,35 +16,39 @@
height: 100%;
cursor: w-resize;
z-index: 100;
transition: opacity 0.2s ease;
touch-action: none;
user-select: none;
-webkit-user-select: none;
}
@-webkit-keyframes drag-fadein {
0% {opacity: 0;}
100% {opacity: 1;}
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes drag-fadein {
0% {opacity: 0;}
100% {opacity: 1;}
0% { opacity: 0; }
100% { opacity: 1; }
}
.horizontal-line:hover,
.vertical-line:hover {
-webkit-animation-name: drag-fadein;
animation-name: drag-fadein;
animation-duration: 0.2s;
animation-delay: .3s;
animation-delay: .2s;
animation-fill-mode: forwards;
}
.horizontal-line:active,
.vertical-line:active {
-webkit-animation-name: drag-fadein;
animation-duration: 0.2s;
animation-delay: .3s;
animation-fill-mode: forwards;
.vertical-line:active,
.drag-s-container.dragging > .horizontal-line,
.drag-w-container.dragging > .vertical-line {
opacity: 1;
animation: none;
}
/* 由于拖拽而产生尺寸改变元素的容器 */
.drag-s-container {
display: flex;
flex-direction: column;
@@ -53,22 +61,26 @@
flex-wrap: nowrap;
}
/* 拖拽元素的容器 */
.drag-elem {
position: absolute;
opacity: 0;
touch-action: none;
user-select: none;
-webkit-user-select: none;
}
.drag-s-elem {
width: 100%;
height: 4px;
cursor: s-resize;
touch-action: none;
}
.drag-w-elem {
width: 4px;
height: 100%;
cursor: w-resize;
touch-action: none;
}
html[data-bs-theme=light] .horizontal-line,

View File

@@ -81,6 +81,17 @@ class Drag {
this.#addEventListener_();
}
#getTouch_(event) {
if (event.touches && event.touches.length > 0) {
return {
clientX: event.touches[0].clientX,
clientY: event.touches[0].clientY
};
} else {
return { clientX: 0, clientY: 0 };
}
};
#addEventListener_() {
const dragElem = this.$dragElem[0];
const container = this.$container[0];
@@ -143,6 +154,66 @@ class Drag {
document.onmouseup = null;
};
};
dragElem.ontouchstart = (touchEvent) => {
touchEvent.preventDefault();
this.$container.addClass('dragging');
let touch = this.#getTouch_(touchEvent);
let dis, prev;
if (type === 'h') {
dis = touch.clientY;
dragElem.top = dragElem.offsetTop;
} else {
dis = touch.clientX;
dragElem.left = dragElem.offsetLeft;
}
const prevSize = this.size;
document.ontouchmove = (moveEvent) => {
moveEvent.preventDefault();
this.runEvent('ondragStart');
const current = this.#getTouch_(moveEvent);
let iT, maxT, minT = parseInt(min), movement;
if (type === 'h') {
iT = dragElem.top + (current.clientY - dis);
maxT = container.clientHeight - minT;
movement = current.clientY - dis;
} else {
iT = dragElem.left + (current.clientX - dis);
maxT = container.clientWidth - minT;
movement = current.clientX - dis;
}
iT += 1;
if (prev === iT) return false;
prev = iT;
if (full[0] && movement < 0 && iT < minT * 0.4) { // 向上或向左
this.changeTo('0%');
this.runEvent('onfull', Drag.Extend.NEGATIVE);
} else if (full[1] && movement > 0 && iT > (maxT + minT * 0.6)) { // 向下或向右
this.changeTo('100%');
this.runEvent('onfull', Drag.Extend.POSITIVE);
} else if (iT < maxT && iT > minT) { // 中间区域
let shown = this.shown;
this.changeTo(iT);
if (shown !== Drag.Extend.BOTH) {
this.runEvent('exitfull', shown);
}
}
this.runEvent('ondragEnd');
return false;
};
document.ontouchend = () => {
this.$container.removeClass('dragging');
this.prevSize = prevSize;
document.ontouchmove = null;
document.ontouchend = null;
};
};
}
changeTo(part) {