Throttle updates to prevent all jank and revert to component center breakboints for DND candidates

This commit is contained in:
Andrew Kingston 2022-10-08 15:04:18 +01:00
parent e9769b0721
commit c2b32f8c5e
2 changed files with 89 additions and 25 deletions

View File

@ -495,7 +495,8 @@
transition: padding 250ms ease, border 250ms ease; transition: padding 250ms ease, border 250ms ease;
} }
.component.explode :global(> *) { .component.explode :global(> *) {
padding: 16px !important; padding: 32px !important;
gap: 16px !important;
border: 2px dashed var(--spectrum-global-color-gray-400) !important; border: 2px dashed var(--spectrum-global-color-gray-400) !important;
border-radius: 4px !important; border-radius: 4px !important;
} }

View File

@ -3,6 +3,7 @@
import IndicatorSet from "./IndicatorSet.svelte" import IndicatorSet from "./IndicatorSet.svelte"
import { builderStore } from "stores" import { builderStore } from "stores"
import PlaceholderOverlay from "./PlaceholderOverlay.svelte" import PlaceholderOverlay from "./PlaceholderOverlay.svelte"
import { Utils } from "@budibase/frontend-core"
let dragInfo let dragInfo
let dropInfo let dropInfo
@ -75,15 +76,34 @@
}, 0) }, 0)
} }
const handleEvent = e => { let lastX
let lastY
let lastTime
const processEvent = (mouseX, mouseY) => {
if (!dropInfo) { if (!dropInfo) {
return null return null
} }
e.preventDefault()
let { id, parent, node, acceptsChildren, empty } = dropInfo let { id, parent, node, acceptsChildren, empty } = dropInfo
const mouseY = e.clientY
const mouseX = e.clientX // Debounce by 10px difference
// if (lastX != null && lastY != null) {
// const delta = Math.abs(mouseY - lastY) + Math.abs(mouseX - lastX)
// if (delta < 10) {
// console.log("delta fail")
// return
// }
// }
// lastX = mouseX
// lastY = mouseY
// Debounce by time
// if (Date.now() - (lastTime || 0) < 100) {
// console.log("time fail")
// return
// }
// lastTime = Date.now()
// If we're over something that does not accept children then we go up a // If we're over something that does not accept children then we go up a
// level and consider the mouse position relative to the parent // level and consider the mouse position relative to the parent
@ -112,7 +132,7 @@
const childCoords = [...(node.children || [])].map(node => { const childCoords = [...(node.children || [])].map(node => {
const bounds = node.children[0].getBoundingClientRect() const bounds = node.children[0].getBoundingClientRect()
return { return {
// placeholder: node.classList.contains("placeholder"), placeholder: node.classList.contains("placeholder"),
centerX: bounds.left + bounds.width / 2, centerX: bounds.left + bounds.width / 2,
centerY: bounds.top + bounds.height / 2, centerY: bounds.top + bounds.height / 2,
left: bounds.left, left: bounds.left,
@ -139,36 +159,79 @@
const column = ["centerX", "left", "right"].includes(variances[0].side) const column = ["centerX", "left", "right"].includes(variances[0].side)
console.log(column ? "COL" : "ROW") console.log(column ? "COL" : "ROW")
// Calculate breakpoints between children /** SYMMETRICAL BREAKPOINTS **/
let midpoints = [] // let breakpoints = []
for (let i = 0; i < childCoords.length - 1; i++) { // for (let i = 0; i < childCoords.length - 1; i++) {
const child1 = childCoords[i] // const child1 = childCoords[i]
const child2 = childCoords[i + 1] // const child2 = childCoords[i + 1]
let midpoint // let breakpoint
if (column) { // if (column) {
const top = Math.min(child1.top, child2.top) // const top = Math.min(child1.top, child2.top)
const bottom = Math.max(child1.bottom, child2.bottom) // const bottom = Math.max(child1.bottom, child2.bottom)
midpoint = (top + bottom) / 2 // breakpoint = (top + bottom) / 2
} else { // } else {
const left = Math.min(child1.left, child2.left) // const left = Math.min(child1.left, child2.left)
const right = Math.max(child1.right, child2.right) // const right = Math.max(child1.right, child2.right)
midpoint = (left + right) / 2 // breakpoint = (left + right) / 2
} // }
midpoints.push(midpoint) // breakpoints.push(breakpoint)
} // }
// let midpoints = childCoords.map(x => (column ? x.centerY : x.centerX))
/** CENTER BREAKPOINTS **/
let breakpoints = childCoords
.filter(x => !x.placeholder)
.map(x => {
return column ? x.centerY : x.centerX
})
/** NEXT EDGE BREAKPOINTS **/
// let breakpoints = []
// for (let i = 0; i < childCoords.length; i++) {
// let breakpoint
// if (column) {
// if (mouseY > childCoords[i].top && mouseY < childCoords[i].bottom) {
// // Inside this container
// if (childCoords[i + 1]) {
// breakpoint = childCoords[i + 1].top
// } else {
// breakpoint = childCoords[i].top
// }
// } else {
// breakpoint =
// mouseY < childCoords[i].bottom
// ? childCoords[i].top
// : childCoords[i].bottom
// }
// } else {
// breakpoint =
// mouseX < childCoords[i].left
// ? childCoords[i].left
// : childCoords[i].right
// }
// breakpoints.push(breakpoint)
// }
// Determine the index to drop the component in // Determine the index to drop the component in
const mousePosition = column ? mouseY : mouseX const mousePosition = column ? mouseY : mouseX
let idx = 0 let idx = 0
while (idx < midpoints.length && midpoints[idx] < mousePosition) { while (idx < breakpoints.length && breakpoints[idx] < mousePosition) {
idx++ idx++
} }
// console.log(mousePosition, breakpoints.map(Math.round), idx)
placeholderInfo = { placeholderInfo = {
parent: id, parent: id,
index: idx, index: idx,
} }
} }
const throttledProcessEvent = Utils.throttle(processEvent, 250)
const handleEvent = e => {
e.preventDefault()
throttledProcessEvent(e.clientX, e.clientY)
}
// Callback when on top of a component // Callback when on top of a component
const onDragOver = e => { const onDragOver = e => {