Updated to use Svelte 5 runes
This commit is contained in:
parent
1f2cf71e21
commit
8c31d08064
2 changed files with 58 additions and 58 deletions
|
|
@ -2,29 +2,48 @@
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
|
|
||||||
let isHovering = false
|
let isHovering = $state(false)
|
||||||
let isBlinking = false
|
let isBlinking = $state(false)
|
||||||
|
|
||||||
const scale = spring(1, {
|
const scale = spring(1, {
|
||||||
stiffness: 0.1,
|
stiffness: 0.1,
|
||||||
damping: 0.125
|
damping: 0.125
|
||||||
})
|
})
|
||||||
|
|
||||||
$: isHovering ? scale.set(1.25) : scale.set(1)
|
$effect(() => {
|
||||||
|
if (isHovering) {
|
||||||
|
scale.set(1.25)
|
||||||
|
} else {
|
||||||
|
scale.set(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function blink() {
|
function sleep(ms) {
|
||||||
isBlinking = true
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
setTimeout(() => {
|
}
|
||||||
isBlinking = false
|
|
||||||
if (Math.random() < 0.45) {
|
function setBlinkState(state) {
|
||||||
setTimeout(() => {
|
isBlinking = state
|
||||||
isBlinking = true
|
}
|
||||||
setTimeout(() => {
|
|
||||||
isBlinking = false
|
async function singleBlink(duration) {
|
||||||
}, 150)
|
setBlinkState(true)
|
||||||
}, 100)
|
await sleep(duration)
|
||||||
}
|
setBlinkState(false)
|
||||||
}, 150)
|
}
|
||||||
|
|
||||||
|
async function doubleBlink() {
|
||||||
|
await singleBlink(50)
|
||||||
|
await sleep(100)
|
||||||
|
await singleBlink(150)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function blink() {
|
||||||
|
await singleBlink(150)
|
||||||
|
|
||||||
|
if (Math.random() < 0.45) {
|
||||||
|
await doubleBlink()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startBlinking() {
|
function startBlinking() {
|
||||||
|
|
|
||||||
|
|
@ -2,59 +2,46 @@
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
|
|
||||||
export let SVGComponent
|
const {
|
||||||
export let backgroundColor = '#f0f0f0'
|
SVGComponent,
|
||||||
export let maxMovement = 20
|
backgroundColor = '#f0f0f0',
|
||||||
export let smoothness = 0.1
|
maxMovement = 20,
|
||||||
export let containerHeight = '300px'
|
containerHeight = '300px',
|
||||||
export let bounceStiffness = 0.1
|
stiffness = 0.15,
|
||||||
export let bounceDamping = 0.4
|
damping = 0.8
|
||||||
|
} = $props()
|
||||||
|
|
||||||
let container
|
let container = $state(null)
|
||||||
let svg
|
let svg = $state(null)
|
||||||
let isHovering = false
|
|
||||||
let animationFrame
|
|
||||||
|
|
||||||
const position = spring(
|
const position = spring(
|
||||||
{ x: 0, y: 0 },
|
{ x: 0, y: 0 },
|
||||||
{
|
{
|
||||||
stiffness: bounceStiffness,
|
stiffness,
|
||||||
damping: bounceDamping
|
damping
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
$: if (svg) {
|
$effect(() => {
|
||||||
svg.style.transform = `translate(calc(-50% + ${$position.x}px), calc(-50% + ${$position.y}px))`
|
if (svg) {
|
||||||
}
|
const { x, y } = $position
|
||||||
|
svg.style.transform = `translate(calc(-50% + ${x}px), calc(-50% + ${y}px))`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function handleMouseMove(event) {
|
function handleMouseMove(event) {
|
||||||
isHovering = true
|
|
||||||
const rect = container.getBoundingClientRect()
|
const rect = container.getBoundingClientRect()
|
||||||
const x = event.clientX - rect.left
|
const x = event.clientX - rect.left
|
||||||
const y = event.clientY - rect.top
|
const y = event.clientY - rect.top
|
||||||
|
|
||||||
const targetX = (x / rect.width - 0.5) * 2 * maxMovement
|
position.set({
|
||||||
const targetY = (y / rect.height - 0.5) * 2 * maxMovement
|
x: (x / rect.width - 0.5) * 2 * maxMovement,
|
||||||
|
y: (y / rect.height - 0.5) * 2 * maxMovement
|
||||||
position.set({ x: targetX, y: targetY }, { hard: false })
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMouseLeave() {
|
function handleMouseLeave() {
|
||||||
isHovering = false
|
position.set({ x: 0, y: 0 })
|
||||||
position.set({ x: 0, y: 0 }, { hard: false })
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSVGPosition() {
|
|
||||||
if (isHovering) {
|
|
||||||
const currentX = $position.x
|
|
||||||
const currentY = $position.y
|
|
||||||
position.update((pos) => ({
|
|
||||||
x: pos.x + (currentX - pos.x) * smoothness,
|
|
||||||
y: pos.y + (currentY - pos.y) * smoothness
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
animationFrame = requestAnimationFrame(updateSVGPosition)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
|
@ -65,12 +52,6 @@
|
||||||
svg.style.top = '50%'
|
svg.style.top = '50%'
|
||||||
svg.style.transform = 'translate(-50%, -50%)'
|
svg.style.transform = 'translate(-50%, -50%)'
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSVGPosition()
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
cancelAnimationFrame(animationFrame)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue