Fix: Drag-and-Drop in Welten-Konfig für Desktop (Pointer Events)
touchstart/touchmove/touchend → pointerdown/pointermove/pointerup: - Pointer Events funktionieren auf Mouse (Desktop) + Touch (Mobile) gleich - setPointerCapture() für sauberes Drag auch wenn Maus das Element verlässt - e.touches[0] → e.clientX/clientY direkt aus dem Pointer Event - Nur linke Maustaste (e.button === 0) startet Drag SW by-v1011, APP_VER 1011
This commit is contained in:
parent
1b3b150b50
commit
82869e3f12
4 changed files with 25 additions and 29 deletions
|
|
@ -732,9 +732,9 @@ window.Worlds = (() => {
|
|||
document.body.appendChild(ov);
|
||||
|
||||
const _removeDragListeners = () => {
|
||||
document.removeEventListener('touchmove', _onDragMove);
|
||||
document.removeEventListener('touchend', _onDragEnd);
|
||||
document.removeEventListener('touchcancel', _onDragEnd);
|
||||
document.removeEventListener('pointermove', _onDragMove);
|
||||
document.removeEventListener('pointerup', _onDragEnd);
|
||||
document.removeEventListener('pointercancel', _onDragEnd);
|
||||
};
|
||||
const _cancelDrag = () => {
|
||||
if (!_drag) return;
|
||||
|
|
@ -874,29 +874,27 @@ window.Worlds = (() => {
|
|||
});
|
||||
});
|
||||
|
||||
// Touch-Drag
|
||||
// Pointer-Drag (funktioniert auf Mouse + Touch)
|
||||
ov.querySelectorAll('.wc-chip').forEach(chip => {
|
||||
chip.addEventListener('touchstart', e => _onDragStart(e, chip), { passive: true });
|
||||
chip.addEventListener('pointerdown', e => _onDragStart(e, chip));
|
||||
});
|
||||
document.addEventListener('touchmove', _onDragMove, { passive: false });
|
||||
document.addEventListener('touchend', _onDragEnd);
|
||||
}
|
||||
|
||||
function _onDragStart(e, chipEl) {
|
||||
if (e.button !== undefined && e.button !== 0) return; // nur linke Maustaste
|
||||
if (_drag) _cancelDrag();
|
||||
const touch = e.touches[0];
|
||||
// Drag erst nach Bewegungs-Threshold aktivieren (verhindert Scroll-Konflikte)
|
||||
chipEl.setPointerCapture(e.pointerId);
|
||||
_drag = {
|
||||
page: chipEl.dataset.page, zone: chipEl.dataset.zone,
|
||||
chipEl, ghost: null, dropZone: null, active: false,
|
||||
startX: touch.clientX, startY: touch.clientY, ox: 0, oy: 0,
|
||||
startX: e.clientX, startY: e.clientY, ox: 0, oy: 0,
|
||||
};
|
||||
document.addEventListener('touchmove', _onDragMove, { passive: false });
|
||||
document.addEventListener('touchend', _onDragEnd);
|
||||
document.addEventListener('touchcancel', _onDragEnd);
|
||||
document.addEventListener('pointermove', _onDragMove);
|
||||
document.addEventListener('pointerup', _onDragEnd);
|
||||
document.addEventListener('pointercancel', _onDragEnd);
|
||||
}
|
||||
|
||||
function _activateDrag(touch) {
|
||||
function _activateDrag(e) {
|
||||
const rect = _drag.chipEl.getBoundingClientRect();
|
||||
_drag.ox = _drag.startX - rect.left;
|
||||
_drag.oy = _drag.startY - rect.top;
|
||||
|
|
@ -910,8 +908,8 @@ window.Worlds = (() => {
|
|||
ghost.style.transform = 'scale(1.08) rotate(-2deg)';
|
||||
ghost.style.width = rect.width + 'px';
|
||||
ghost.style.height = rect.height + 'px';
|
||||
ghost.style.left = (touch.clientX - _drag.ox) + 'px';
|
||||
ghost.style.top = (touch.clientY - _drag.oy) + 'px';
|
||||
ghost.style.left = (e.clientX - _drag.ox) + 'px';
|
||||
ghost.style.top = (e.clientY - _drag.oy) + 'px';
|
||||
ghost.style.transition = 'none';
|
||||
ghost.style.boxShadow = '0 8px 24px rgba(0,0,0,0.5)';
|
||||
document.body.appendChild(ghost);
|
||||
|
|
@ -921,24 +919,22 @@ window.Worlds = (() => {
|
|||
|
||||
function _onDragMove(e) {
|
||||
if (!_drag) return;
|
||||
const touch = e.touches[0];
|
||||
|
||||
if (!_drag.active) {
|
||||
const dx = Math.abs(touch.clientX - _drag.startX);
|
||||
const dy = Math.abs(touch.clientY - _drag.startY);
|
||||
if (dx < 8 && dy < 8) return; // Threshold noch nicht erreicht
|
||||
_activateDrag(touch);
|
||||
const dx = Math.abs(e.clientX - _drag.startX);
|
||||
const dy = Math.abs(e.clientY - _drag.startY);
|
||||
if (dx < 8 && dy < 8) return;
|
||||
_activateDrag(e);
|
||||
}
|
||||
|
||||
e.preventDefault(); // Scroll erst NACH Threshold blockieren
|
||||
_drag.ghost.style.left = (touch.clientX - _drag.ox) + 'px';
|
||||
_drag.ghost.style.top = (touch.clientY - _drag.oy) + 'px';
|
||||
_drag.ghost.style.left = (e.clientX - _drag.ox) + 'px';
|
||||
_drag.ghost.style.top = (e.clientY - _drag.oy) + 'px';
|
||||
|
||||
let foundZone = null;
|
||||
ov.querySelectorAll('.wc-zone').forEach(z => {
|
||||
const r = z.getBoundingClientRect();
|
||||
const over = touch.clientX >= r.left && touch.clientX <= r.right
|
||||
&& touch.clientY >= r.top && touch.clientY <= r.bottom;
|
||||
const over = e.clientX >= r.left && e.clientX <= r.right
|
||||
&& e.clientY >= r.top && e.clientY <= r.bottom;
|
||||
z.style.borderColor = over ? (worldColors[z.dataset.zone] || 'rgba(196,132,58,0.8)') : 'transparent';
|
||||
if (over) foundZone = z.dataset.zone;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue