Improve performance of grid DND handler

This commit is contained in:
Andrew Kingston 2024-08-09 20:18:30 +01:00
parent 8aa0407236
commit 376192e85a
No known key found for this signature in database
1 changed files with 27 additions and 62 deletions

View File

@ -56,13 +56,12 @@
return clone return clone
} }
const processEvent = Utils.throttle((mouseX, mouseY) => { const processEvent = Utils.domDebounce((mouseX, mouseY) => {
if (!dragInfo?.grid) { if (!dragInfo?.grid) {
return return
} }
const { mode, side, gridId, grid } = dragInfo const { mode, side, grid, domGrid } = dragInfo
const { startX, startY, rowStart, rowEnd, colStart, colEnd } = grid const { startX, startY, rowStart, rowEnd, colStart, colEnd } = grid
const domGrid = getDOMNode(gridId)
if (!domGrid) { if (!domGrid) {
return return
} }
@ -107,7 +106,7 @@
} }
styles.set(newStyles) styles.set(newStyles)
} }
}, 10) })
const handleEvent = e => { const handleEvent = e => {
e.preventDefault() e.preventDefault()
@ -138,61 +137,47 @@
id = component.dataset.id id = component.dataset.id
} }
// Find grid parent // Find grid parent and read from DOM
const domComponent = getDOMNode(id) const domComponent = getDOMNode(id)
const domGrid = getGridParent(domComponent) const domGrid = getGridParent(domComponent)
if (!domGrid) { if (!domGrid) {
return return
} }
builderStore.actions.selectComponent(id) const gridCols = parseInt(domGrid.dataset.cols)
const styles = getComputedStyle(domComponent.parentNode)
// Apply active class to grid // Show as active
builderStore.actions.selectComponent(id)
domComponent.parentNode.classList.add("dragging") domComponent.parentNode.classList.add("dragging")
domGrid.classList.add("highlight") domGrid.classList.add("highlight")
// Update state // Update state
dragInfo = { dragInfo = {
domTarget: e.target, domTarget: e.target,
domComponent,
domGrid,
id, id,
gridId: domGrid.parentNode.dataset.id, gridId: domGrid.parentNode.dataset.id,
mode, mode,
side, side,
grid: {
startX: e.clientX,
startY: e.clientY,
// Ensure things are within limits
rowStart: Math.max(styles["grid-row-start"], 1),
rowEnd: Math.max(styles["grid-row-end"], 2),
colStart: minMax(styles["grid-column-start"], 1, gridCols),
colEnd: minMax(styles["grid-column-end"], 2, gridCols + 1),
},
} }
// Add event handler to clear all drag state when dragging ends // Add event handler to clear all drag state when dragging ends
dragInfo.domTarget.addEventListener("dragend", stopDragging) dragInfo.domTarget.addEventListener("dragend", stopDragging)
} }
// Callback when entering a potential drop target
const onDragEnter = e => {
// Skip if we aren't validly dragging currently
if (!dragInfo || dragInfo.grid) {
return
}
const { id, gridId } = dragInfo
const domComponent = getDOMNode(id)
const domGrid = getDOMNode(gridId)
if (!domComponent || !domGrid) {
return
}
const gridCols = parseInt(domGrid.dataset.cols)
const styles = getComputedStyle(domComponent.parentNode)
dragInfo.grid = {
startX: e.clientX,
startY: e.clientY,
// Ensure things are within limits
rowStart: Math.max(styles["grid-row-start"], 1),
rowEnd: Math.max(styles["grid-row-end"], 2),
colStart: minMax(styles["grid-column-start"], 1, gridCols),
colEnd: minMax(styles["grid-column-end"], 2, gridCols + 1),
}
handleEvent(e)
}
const onDragOver = e => { const onDragOver = e => {
if (!dragInfo?.grid) { if (!dragInfo) {
return return
} }
handleEvent(e) handleEvent(e)
@ -203,7 +188,12 @@
if (!dragInfo) { if (!dragInfo) {
return return
} }
const { id, gridId, domTarget } = dragInfo const { id, gridId, domTarget, domGrid, domComponent } = dragInfo
// Reset DOM
domComponent.parentNode.classList.remove("dragging")
domGrid.classList.remove("highlight")
domTarget.removeEventListener("dragend", stopDragging)
// Save changes // Save changes
if ($styles) { if ($styles) {
@ -213,44 +203,19 @@
await builderStore.actions.updateStyles($gridStyles, gridId) await builderStore.actions.updateStyles($gridStyles, gridId)
} }
// Reset DOM
const domComponent = getDOMNode(id)
if (domComponent) {
domComponent.parentNode.classList.remove("dragging")
}
const domGrid = getDOMNode(gridId)
if (domGrid) {
domGrid.classList.remove("highlight")
}
domTarget.removeEventListener("dragend", stopDragging)
// Reset state // Reset state
dragInfo = null dragInfo = null
styles.set(null) styles.set(null)
gridStyles.set(null) gridStyles.set(null)
} }
const calculateRequiredRows = () => {
let required = 1
const children = document.querySelectorAll(`.${gridId}-dom > .component`)
for (let child of children) {
const rowEnd = child.dataset.grid_desktop_col_end
if (rowEnd > required) {
required = rowEnd
}
}
return required - 1
}
onMount(() => { onMount(() => {
document.addEventListener("dragstart", onDragStart, false) document.addEventListener("dragstart", onDragStart, false)
document.addEventListener("dragenter", onDragEnter, false)
document.addEventListener("dragover", onDragOver, false) document.addEventListener("dragover", onDragOver, false)
}) })
onDestroy(() => { onDestroy(() => {
document.removeEventListener("dragstart", onDragStart, false) document.removeEventListener("dragstart", onDragStart, false)
document.removeEventListener("dragenter", onDragEnter, false)
document.removeEventListener("dragover", onDragOver, false) document.removeEventListener("dragover", onDragOver, false)
}) })
</script> </script>