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