going to try implementing in css

This commit is contained in:
Gerard Burns 2024-04-02 10:54:20 +01:00
parent 1716321bef
commit fb25c08523
2 changed files with 105 additions and 31 deletions

View File

@ -317,8 +317,11 @@
<style> <style>
.tooltipContents { .tooltipContents {
width: 300px;
background-color: red; background-color: red;
max-width: 200px;
text-wrap: wrap;
display: inline-block;
word-break: break-all;
} }
.spectrum-Menu { .spectrum-Menu {

View File

@ -2,7 +2,8 @@
import Portal from "svelte-portal" import Portal from "svelte-portal"
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
export let tooltip export let currentTooltip
export let previousTooltip
export let anchor export let anchor
export let visible = false export let visible = false
export let hovering = false export let hovering = false
@ -12,37 +13,63 @@
let endX = 0 let endX = 0
let endY = 0 let endY = 0
let currentTooltipWidth = 0
let currentTooltipHeight = 0
let previousTooltipWidth = 0
let previousTooltipHeight = 0
let x = 0; let x = 0;
let y = 0; let y = 0;
let w = 0;
let h = 0;
let animationStartTime = 0; let animationStartTime = 0;
const updatePositionOnVisibilityChange = (visible, hovering) => { const updatePositionOnVisibilityChange = (visible, hovering) => {
if (!visible && !hovering) { if (!visible && !hovering) {
x = 0; x = 0;
y = 0; y = 0;
}
}
const updatePosition = (anchor, tooltip) => { previousTooltipWidth = 0
if (anchor == null) { previousTooltipHeight = 0
return; } }
}
const rect = anchor.getBoundingClientRect(); const updatePosition = (anchor, currentTooltip, previousTooltip) => {
const tooltipWidth = tooltip?.getBoundingClientRect()?.width ?? 0; requestAnimationFrame(() => {
if (anchor == null || currentTooltip == null || previousTooltip == null) {
return;
}
startX = x const rect = anchor.getBoundingClientRect();
startY = y
endX = rect.x - tooltipWidth currentTooltipWidth = currentTooltip.clientWidth
endY = rect.y currentTooltipHeight = currentTooltip.clientHeight
animationStartTime = document.timeline.currentTime previousTooltipWidth = previousTooltip.clientWidth
previousTooltipHeight = previousTooltip.clientHeight
if (x === 0 && y === 0) { if (previousTooltipWidth === 0) {
startX = endX previousTooltipWidth = currentTooltipWidth;
startY = endY }
}
if (previousTooltipHeight === 0) {
previousTooltipHeight = currentTooltipHeight;
}
startX = x
startY = y
endX = rect.x - currentTooltipWidth
endY = rect.y
animationStartTime = document.timeline.currentTime
if (x === 0 && y === 0) {
startX = endX
startY = endY
}
})
} }
const getNormalizedTime = (startTime, endTime, currentTime) => { const getNormalizedTime = (startTime, endTime, currentTime) => {
@ -52,11 +79,13 @@
return distanceFromStart / timeDiff; return distanceFromStart / timeDiff;
} }
const cubicBezierInterpolation = (p1, p2, p3, p4, t) => { const cubicBezierInterpolation = (p1, p2, p3, p4, currentTime) => {
return Math.pow(1 - t, 3) * p1 + return (
3 * Math.pow(1 - t, 2) * t * p2 + (Math.pow(1 - currentTime, 3) * p1) +
3 * (1 - t) * Math.pow(t, 2) * p3 + (3 * Math.pow(1 - currentTime, 2) * currentTime * p2) +
Math.pow(t, 3) * p4; (3 * (1 - currentTime) * Math.pow(currentTime, 2) * p3) +
(Math.pow(currentTime, 3) * p4)
)
} }
// Made to match the interface of the css bezier curve function // Made to match the interface of the css bezier curve function
@ -83,7 +112,7 @@
return; return;
} }
const animationDuration = 200 const animationDuration = 300
const normalizedTime = getNormalizedTime(invokedAnimationStartTime, invokedAnimationStartTime + animationDuration, frameTime) const normalizedTime = getNormalizedTime(invokedAnimationStartTime, invokedAnimationStartTime + animationDuration, frameTime)
if (normalizedTime >= 1) { if (normalizedTime >= 1) {
@ -95,11 +124,16 @@
x = linearInterpolation(startX, endX, easing.x) x = linearInterpolation(startX, endX, easing.x)
y = linearInterpolation(startY, endY, easing.y) y = linearInterpolation(startY, endY, easing.y)
w = linearInterpolation(previousTooltipWidth, currentTooltipWidth, easing.x)
console.log(currentTooltipWidth);
console.log(previousTooltipWidth);
console.log(w);
console.log("")
requestAnimationFrame((newFrameTime) => animate(invokedAnimationStartTime, newFrameTime)) requestAnimationFrame((newFrameTime) => animate(invokedAnimationStartTime, newFrameTime))
} }
$: updatePosition(anchor, tooltip) $: updatePosition(anchor, currentTooltip, previousTooltip)
$: updatePositionOnVisibilityChange(visible, hovering) $: updatePositionOnVisibilityChange(visible, hovering)
$: requestAnimationFrame((frameTime) => animate(animationStartTime, frameTime)) $: requestAnimationFrame((frameTime) => animate(animationStartTime, frameTime))
@ -114,29 +148,66 @@
<Portal target=".spectrum"> <Portal target=".spectrum">
<div <div
bind:this={tooltip}
on:mouseenter={handleMouseenter} on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave} on:mouseleave={handleMouseleave}
style:top={`${y}px`} style:width={`${w}px`}
style:height={`${currentTooltipHeight}px`}
style:left={`${x}px`} style:left={`${x}px`}
style:top={`${y}px`}
class="tooltip" class="tooltip"
class:visible={visible || hovering} class:visible={visible || hovering}
> >
<slot /> <div class="screenSize">
<div
bind:this={currentTooltip}
class="currentContent"
style:left={`${endX - x}px`}
style:top={`${endY - y}px`}
>
<slot />
</div>
</div>
<div class="screenSize">
<div
bind:this={previousTooltip}
class="previousContent"
style:left={`${startX - x}px`}
style:top={`${startY - y}px`}
>
<slot name="previous"/>
</div>
</div>
</div> </div>
<slot name="previous" />
</Portal> </Portal>
<style> <style>
.screenSize {
position: absolute;
width: 100vw;
height: 100vh;
}
.tooltip { .tooltip {
position: absolute; position: absolute;
z-index: 9999; z-index: 9999;
opacity: 0;
pointer-events: none; pointer-events: none;
background-color: red;
opacity: 0;
overflow: hidden;
} }
.visible { .visible {
opacity: 1; opacity: 1;
pointer-events: auto; pointer-events: auto;
} }
.currentContent {
position: absolute;
z-index: 10000;
}
.previousContent {
position: absolute;
z-index: 10000;
}
</style> </style>