|
1 | 1 | <script lang="ts"> |
2 | | - import { onDestroy, onMount } from 'svelte'; |
3 | | - import { cubicOut } from 'svelte/easing'; |
4 | | - import { tweened } from 'svelte/motion'; |
| 2 | + import { onMount } from 'svelte'; |
5 | 3 |
|
6 | 4 | // Randomly move the star around by tweening its x and y coordinates |
7 | 5 | // in an offset from its original position, using a sine wave to |
8 | 6 | // create a smooth, natural motion |
| 7 | + let data = { x: 0, y: 0, size: 0, opacity: 0 }; |
9 | 8 |
|
10 | | - let xTween = tweened(0, { duration: 1000, easing: cubicOut }); |
11 | | - let yTween = tweened(0, { duration: 1000, easing: cubicOut }); |
| 9 | + // Create a random offset |
| 10 | + const offset = Math.random() * 5; |
12 | 11 |
|
13 | | - // Randomly change the star's size and opacity |
14 | | - let size = tweened(Math.random() * 20 + 10, { duration: 1000, easing: cubicOut }); |
15 | | - let opacityTween = tweened(Math.random() * 0.5 + 0.5, { duration: 1000, easing: cubicOut }); |
| 12 | + // Create a random speed |
| 13 | + // 5 - 10 |
| 14 | + let speed = 0; |
16 | 15 |
|
17 | | - // Perform the movement and size/opacity changes on mount |
18 | | - let lastTimeout; |
| 16 | + // Signed directions |
| 17 | + let directions = [-1, 1]; |
19 | 18 |
|
20 | | - onMount(() => { |
21 | | - function update() { |
22 | | - xTween.set(Math.random() * 20 - 10); |
23 | | - yTween.set(Math.random() * 20 - 10); |
24 | | - opacityTween.set(Math.random() * 0.5 + 0.5); |
25 | | - size.set(Math.random() * 20 + 10); |
26 | | -
|
27 | | - lastTimeout = setTimeout(update, Math.random() * 1000 + 1000); |
| 19 | + const render = () => { |
| 20 | + // Update the completion status |
| 21 | + if (speed === 0 || data.opacity < 0.001) { |
| 22 | + speed = Math.random() * 15 + 5; |
| 23 | + directions = [Math.random() * 2 - 1, Math.random() * 2 - 1]; |
28 | 24 | } |
29 | 25 |
|
30 | | - update(); |
31 | | - }); |
32 | | - onDestroy(() => clearTimeout(lastTimeout)); |
| 26 | + // Update the data |
| 27 | + data = { |
| 28 | + x: directions[0] * Math.sin(Date.now() / 1000 + offset) * speed, |
| 29 | + y: directions[1] * Math.sin(Date.now() / 1000 + offset) * speed, |
| 30 | + size: Math.sin(Date.now() / 1000 + offset) * speed + 20, |
| 31 | + opacity: Math.sin(Date.now() / 1000 + offset) * 0.5 + 0.5, |
| 32 | + }; |
| 33 | +
|
| 34 | + // Request the next frame |
| 35 | + requestAnimationFrame(render); |
| 36 | + }; |
| 37 | +
|
| 38 | + onMount(() => requestAnimationFrame(render)); |
33 | 39 | </script> |
34 | 40 |
|
35 | 41 | <div class="relative"> |
36 | | - <div class="absolute" style="left: {$xTween}px; top: {$yTween}px; width: {$size}px; height: {$size}px; opacity: {$opacityTween};"> |
| 42 | + <div class="absolute" style="left: {data.x}px; top: {data.y}px; width: {data.size}px; height: {data.size}px; opacity: {data.opacity};"> |
37 | 43 | <slot /> |
38 | 44 | </div> |
39 | 45 | </div> |
0 commit comments