Hugely improve performance of selection and highlight indicators in builder preview
This commit is contained in:
parent
9040a0bd1c
commit
8576166d03
|
@ -2,6 +2,7 @@
|
|||
import { onMount, onDestroy } from "svelte"
|
||||
import { builderStore } from "../store"
|
||||
import Indicator from "./Indicator.svelte"
|
||||
import { domDebounce } from "../utils/domDebounce"
|
||||
|
||||
let indicators = []
|
||||
let interval
|
||||
|
@ -34,11 +35,17 @@
|
|||
|
||||
indicators = newIndicators
|
||||
}
|
||||
const debouncedUpdate = domDebounce(updatePosition)
|
||||
|
||||
const onMouseOver = e => {
|
||||
const element = e.target.closest("[data-type='component']")
|
||||
componentId = element?.dataset?.id
|
||||
componentName = element?.dataset?.name
|
||||
const newId = element?.dataset?.id
|
||||
const newName = element?.dataset?.name
|
||||
if (newId !== componentId) {
|
||||
componentId = newId
|
||||
componentName = newName
|
||||
debouncedUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
const onMouseLeave = () => {
|
||||
|
@ -47,27 +54,33 @@
|
|||
}
|
||||
|
||||
onMount(() => {
|
||||
interval = setInterval(updatePosition, 100)
|
||||
window.addEventListener("mouseover", onMouseOver)
|
||||
document.documentElement.addEventListener("mouseleave", onMouseLeave)
|
||||
debouncedUpdate()
|
||||
interval = setInterval(debouncedUpdate, 100)
|
||||
document.addEventListener("mouseover", onMouseOver)
|
||||
document.addEventListener("mouseleave", onMouseLeave)
|
||||
document.addEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
clearInterval(interval)
|
||||
window.removeEventListener("mouseover", onMouseOver)
|
||||
document.documentElement.removeEventListener("mouseleave", onMouseLeave)
|
||||
document.removeEventListener("mouseover", onMouseOver)
|
||||
document.removeEventListener("mouseleave", onMouseLeave)
|
||||
document.removeEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if componentId !== $builderStore.selectedComponentId}
|
||||
{#each indicators as indicator, idx}
|
||||
<Indicator
|
||||
top={indicator.top}
|
||||
left={indicator.left}
|
||||
width={indicator.width}
|
||||
height={indicator.height}
|
||||
text={idx === 0 ? componentName : null}
|
||||
color="rgb(120, 170, 244)"
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{#key componentId}
|
||||
{#if componentId !== $builderStore.selectedComponentId}
|
||||
{#each indicators as indicator, idx}
|
||||
<Indicator
|
||||
top={indicator.top}
|
||||
left={indicator.left}
|
||||
width={indicator.width}
|
||||
height={indicator.height}
|
||||
text={idx === 0 ? componentName : null}
|
||||
color="rgb(120, 170, 244)"
|
||||
transition
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{/key}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
<script>
|
||||
import { fade } from "svelte/transition"
|
||||
|
||||
export let top
|
||||
export let left
|
||||
export let width
|
||||
export let height
|
||||
export let text
|
||||
export let color
|
||||
export let transition = false
|
||||
</script>
|
||||
|
||||
<div
|
||||
in:fade={{ delay: transition ? 65 : 0, duration: transition ? 130 : 0 }}
|
||||
class="indicator"
|
||||
style="top: {top}px; left: {left}px; width: {width}px; height: {height}px; --color: {color};"
|
||||
>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { onMount, onDestroy } from "svelte"
|
||||
import { builderStore } from "../store"
|
||||
import Indicator from "./Indicator.svelte"
|
||||
import { domDebounce } from "../utils/domDebounce"
|
||||
|
||||
let indicators = []
|
||||
let interval
|
||||
|
@ -29,13 +30,17 @@
|
|||
}
|
||||
indicators = newIndicators
|
||||
}
|
||||
const debouncedUpdate = domDebounce(updatePosition)
|
||||
|
||||
onMount(() => {
|
||||
interval = setInterval(updatePosition, 100)
|
||||
debouncedUpdate()
|
||||
interval = setInterval(debouncedUpdate, 100)
|
||||
document.addEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
clearInterval(interval)
|
||||
document.removeEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { onMount, onDestroy } from "svelte"
|
||||
import SettingsButton from "./SettingsButton.svelte"
|
||||
import { builderStore } from "../store"
|
||||
import { domDebounce } from "../utils/domDebounce"
|
||||
|
||||
const verticalOffset = 28
|
||||
const horizontalOffset = 2
|
||||
|
@ -63,13 +64,17 @@
|
|||
measured = true
|
||||
}
|
||||
}
|
||||
const debouncedUpdate = domDebounce(updatePosition)
|
||||
|
||||
onMount(() => {
|
||||
interval = setInterval(updatePosition, 100)
|
||||
debouncedUpdate()
|
||||
interval = setInterval(debouncedUpdate, 100)
|
||||
document.addEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
clearInterval(interval)
|
||||
document.removeEventListener("scroll", debouncedUpdate, true)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
export const domDebounce = callback => {
|
||||
let active = false
|
||||
return e => {
|
||||
if (!active) {
|
||||
window.requestAnimationFrame(() => {
|
||||
callback(e)
|
||||
active = false
|
||||
})
|
||||
active = true
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue