Refactors drag and drop logic
Improves drag and drop initialization and handling by extracting methods for clarity. This enhances code readability and maintainability.
This commit is contained in:
parent
b6f2aba398
commit
5d406201b8
2 changed files with 125 additions and 96 deletions
|
|
@ -214,88 +214,111 @@ export class DragDropManager {
|
|||
if (event.buttons === 1) {
|
||||
const currentPosition: MousePosition = { x: event.clientX, y: event.clientY };
|
||||
|
||||
// Check if we need to start drag (movement threshold)
|
||||
// Try to initialize drag if not started
|
||||
if (!this.isDragStarted && this.draggedElement) {
|
||||
const deltaX = Math.abs(currentPosition.x - this.initialMousePosition.x);
|
||||
const deltaY = Math.abs(currentPosition.y - this.initialMousePosition.y);
|
||||
const totalMovement = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
|
||||
if (totalMovement >= this.dragThreshold) {
|
||||
// Start drag - emit drag:start event
|
||||
this.isDragStarted = true;
|
||||
|
||||
// Set high z-index on event-group if exists, otherwise on event itself
|
||||
const eventGroup = this.draggedElement.closest<HTMLElement>('swp-event-group');
|
||||
if (eventGroup) {
|
||||
eventGroup.style.zIndex = '9999';
|
||||
} else {
|
||||
this.draggedElement.style.zIndex = '9999';
|
||||
}
|
||||
|
||||
// Detect current column and save as initial source column
|
||||
this.currentColumnBounds = ColumnDetectionUtils.getColumnBounds(currentPosition);
|
||||
this.initialColumnBounds = this.currentColumnBounds; // Save source column
|
||||
|
||||
// Cast to BaseSwpEventElement and create clone (works for both SwpEventElement and SwpAllDayEventElement)
|
||||
const originalElement = this.draggedElement as BaseSwpEventElement;
|
||||
this.draggedClone = originalElement.createClone();
|
||||
|
||||
const dragStartPayload: DragStartEventPayload = {
|
||||
draggedElement: this.draggedElement,
|
||||
draggedClone: this.draggedClone,
|
||||
mousePosition: this.initialMousePosition,
|
||||
mouseOffset: this.mouseOffset,
|
||||
columnBounds: this.currentColumnBounds
|
||||
};
|
||||
this.eventBus.emit('drag:start', dragStartPayload);
|
||||
} else {
|
||||
// Not enough movement yet - don't start drag
|
||||
return;
|
||||
if (!this.tryInitializeDrag(currentPosition)) {
|
||||
return; // Not enough movement yet
|
||||
}
|
||||
}
|
||||
|
||||
// Continue with normal drag behavior only if drag has started
|
||||
// Continue drag if started
|
||||
if (this.isDragStarted && this.draggedElement && this.draggedClone) {
|
||||
if (!this.draggedElement.hasAttribute("data-allday")) {
|
||||
// Calculate raw position from mouse (no snapping)
|
||||
const column = ColumnDetectionUtils.getColumnBounds(currentPosition);
|
||||
this.continueDrag(currentPosition);
|
||||
this.detectAndEmitColumnChange(currentPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (column) {
|
||||
// Calculate raw Y position relative to column (accounting for mouse offset)
|
||||
const columnRect = column.boundingClientRect;
|
||||
const eventTopY = currentPosition.y - columnRect.top - this.mouseOffset.y;
|
||||
this.targetY = Math.max(0, eventTopY); // Store raw Y as target (no snapping)
|
||||
this.targetColumn = column;
|
||||
/**
|
||||
* Try to initialize drag based on movement threshold
|
||||
* Returns true if drag was initialized, false if not enough movement
|
||||
*/
|
||||
private tryInitializeDrag(currentPosition: MousePosition): boolean {
|
||||
const deltaX = Math.abs(currentPosition.x - this.initialMousePosition.x);
|
||||
const deltaY = Math.abs(currentPosition.y - this.initialMousePosition.y);
|
||||
const totalMovement = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
|
||||
// Start animation loop if not already running
|
||||
if (this.dragAnimationId === null) {
|
||||
this.currentY = parseFloat(this.draggedClone.style.top) || 0;
|
||||
this.animateDrag();
|
||||
}
|
||||
}
|
||||
if (totalMovement < this.dragThreshold) {
|
||||
return false; // Not enough movement
|
||||
}
|
||||
|
||||
// Check for auto-scroll
|
||||
this.checkAutoScroll(currentPosition);
|
||||
}
|
||||
// Start drag
|
||||
this.isDragStarted = true;
|
||||
|
||||
const newColumn = ColumnDetectionUtils.getColumnBounds(currentPosition);
|
||||
if (newColumn == null)
|
||||
return;
|
||||
// Set high z-index on event-group if exists, otherwise on event itself
|
||||
const eventGroup = this.draggedElement!.closest<HTMLElement>('swp-event-group');
|
||||
if (eventGroup) {
|
||||
eventGroup.style.zIndex = '9999';
|
||||
} else {
|
||||
this.draggedElement!.style.zIndex = '9999';
|
||||
}
|
||||
|
||||
if (newColumn?.index !== this.currentColumnBounds?.index) {
|
||||
const previousColumn = this.currentColumnBounds;
|
||||
this.currentColumnBounds = newColumn;
|
||||
// Detect current column and save as initial source column
|
||||
this.currentColumnBounds = ColumnDetectionUtils.getColumnBounds(currentPosition);
|
||||
this.initialColumnBounds = this.currentColumnBounds;
|
||||
|
||||
const dragColumnChangePayload: DragColumnChangeEventPayload = {
|
||||
originalElement: this.draggedElement,
|
||||
draggedClone: this.draggedClone,
|
||||
previousColumn,
|
||||
newColumn,
|
||||
mousePosition: currentPosition
|
||||
};
|
||||
this.eventBus.emit('drag:column-change', dragColumnChangePayload);
|
||||
// Cast to BaseSwpEventElement and create clone
|
||||
const originalElement = this.draggedElement as BaseSwpEventElement;
|
||||
this.draggedClone = originalElement.createClone();
|
||||
|
||||
const dragStartPayload: DragStartEventPayload = {
|
||||
draggedElement: this.draggedElement!,
|
||||
draggedClone: this.draggedClone,
|
||||
mousePosition: this.initialMousePosition,
|
||||
mouseOffset: this.mouseOffset,
|
||||
columnBounds: this.currentColumnBounds
|
||||
};
|
||||
this.eventBus.emit('drag:start', dragStartPayload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue drag movement - update position and auto-scroll
|
||||
*/
|
||||
private continueDrag(currentPosition: MousePosition): void {
|
||||
if (!this.draggedElement!.hasAttribute("data-allday")) {
|
||||
// Calculate raw position from mouse (no snapping)
|
||||
const column = ColumnDetectionUtils.getColumnBounds(currentPosition);
|
||||
|
||||
if (column) {
|
||||
// Calculate raw Y position relative to column (accounting for mouse offset)
|
||||
const columnRect = column.boundingClientRect;
|
||||
const eventTopY = currentPosition.y - columnRect.top - this.mouseOffset.y;
|
||||
this.targetY = Math.max(0, eventTopY);
|
||||
this.targetColumn = column;
|
||||
|
||||
// Start animation loop if not already running
|
||||
if (this.dragAnimationId === null) {
|
||||
this.currentY = parseFloat(this.draggedClone!.style.top) || 0;
|
||||
this.animateDrag();
|
||||
}
|
||||
}
|
||||
|
||||
// Check for auto-scroll
|
||||
this.checkAutoScroll(currentPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect column change and emit event
|
||||
*/
|
||||
private detectAndEmitColumnChange(currentPosition: MousePosition): void {
|
||||
const newColumn = ColumnDetectionUtils.getColumnBounds(currentPosition);
|
||||
if (newColumn == null) return;
|
||||
|
||||
if (newColumn.index !== this.currentColumnBounds?.index) {
|
||||
const previousColumn = this.currentColumnBounds;
|
||||
this.currentColumnBounds = newColumn;
|
||||
|
||||
const dragColumnChangePayload: DragColumnChangeEventPayload = {
|
||||
originalElement: this.draggedElement!,
|
||||
draggedClone: this.draggedClone!,
|
||||
previousColumn,
|
||||
newColumn,
|
||||
mousePosition: currentPosition
|
||||
};
|
||||
this.eventBus.emit('drag:column-change', dragColumnChangePayload);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue