= $state({});
+ let particleCount = 0;
- let MAX_PARTICLES = 200;
+ let MAX_PARTICLES = 400;
function spwanParticle(key: string) {
- if (particles.length > MAX_PARTICLES) return;
- if (from.cur[key] <= particlesState[key]) {
+ if (particleCount > MAX_PARTICLES) return;
+ if (from.cur[key] <= (particlesState[key] ?? []).length) {
return;
}
- particles.push({
+ const toAdd: Particle = {
percentage: 0,
to: key,
rand: Math.random(),
- randX: Math.random(),
- randY: Math.random(),
+ randXStart: Math.floor(Math.random() * 100),
+ randXEnd: Math.floor(Math.random() * 100),
color: [
'oklch(68.5% 0.169 237.323)',
'oklch(62.3% 0.214 259.815)',
'oklch(62.7% 0.265 303.9)'
][Math.floor(Math.random() * 3)]
- });
- particlesState[key] = (particlesState[key] ?? 0) + 1;
+ };
+ if (particlesState[key]) {
+ particlesState[key].push(toAdd);
+ } else {
+ particlesState[key] = [toAdd];
+ }
+ particleCount++;
}
- const MAX_ROUNDS = 40;
+ const MAX_ROUNDS = 200;
let timeout: number | undefined = undefined;
function t(k: number) {
@@ -72,39 +79,64 @@
for (const key of Object.keys(from.cur)) {
spwanParticle(key);
}
- timeout = setTimeout(() => t(k + 1), Math.random() * 1500) as unknown as number;
+ timeout = setTimeout(() => t(k + 1), Math.random() * 1000) as unknown as number;
}
$effect(() => {
if (timeout !== undefined) clearTimeout(timeout);
+ // this is used for making this effect block dependednt on form
+ // eslint-disable-next-line
const _ = from;
- particles = [];
+ particlesState = {};
timeout = setTimeout(() => t(0), 10) as unknown as number;
return () => {
if (timeout !== undefined) clearTimeout(timeout);
};
});
+
+ let showColor = $derived(hovering === undefined || hovering === node);
{
+ hovering = node;
+ }}
+ onmouseleave={() => {
+ hovering = undefined;
+ }}
+ role="figure"
>
-{#each particles as particle}
- {@const to = statusStore.nodesR[particle.to]}
- {@const f_x = to.x + to.width / 2 + particle.randX}
- {@const f_y = to.y - to.height / 2 + particle.randY}
- {@const x = (p: number) => f_x + (node.x + node.width / 2 - f_x) * p}
- {@const y = (p: number) => f_y + (node.y - node.height / 2 - f_y) * p}
+
+{#each Object.keys(particlesState) as key}
+ {@const size = 20}
+ {@const to = statusStore.nodesR[key]}
+ {@const f_x = node.x + node.width / 2}
+ {@const f_y = node.y - node.height / 2}
+ {@const t_x = to.x + to.width / 2}
+ {@const t_y = to.y - to.height / 2}
+ {@const diff = Math.sqrt((f_x - t_x) ** 2 + (f_y - t_y) ** 2)}
+ {@const theta = Math.atan2(f_x - t_x, f_y - t_y)}
+ class="absolute z-30"
+ style="height: {(25 / 2) *
+ diff}px; width: {size}px; transform-origin: top center; transform: translate({canvasX(f_x) +
+ 25 -
+ size / 2}px, {canvasY(f_y) + 25 + size / 8}px) rotate({theta}rad);"
+ >
+ {#each particlesState[key] as particle}
+
+ {/each}
+
{/each}
{#each Object.keys(from.cur) as link}
@@ -117,9 +149,11 @@
{@const diff = Math.sqrt((f_x - t_x) ** 2 + (f_y - t_y) ** 2)}
{@const theta = Math.atan2(f_x - t_x, f_y - t_y)}
@@ -136,7 +170,9 @@
{@const diff = Math.sqrt((f_x - t_x) ** 2 + (f_y - t_y) ** 2)}
{@const theta = Math.atan2(f_x - t_x, f_y - t_y)}
+ {/each}
+{/if}
+
+{#if from.prev && from.prev.prev && from.prev.prev.prev}
+ {#each Object.keys(from.prev.prev.prev.cur) as link}
+ {@const size = 2.5}
+ {@const to = statusStore.nodesR[link]}
+ {@const f_x = node.x + node.width / 2}
+ {@const f_y = node.y - node.height / 2}
+ {@const t_x = to.x + to.width / 2}
+ {@const t_y = to.y - to.height / 2}
+ {@const diff = Math.sqrt((f_x - t_x) ** 2 + (f_y - t_y) ** 2)}
+ {@const theta = Math.atan2(f_x - t_x, f_y - t_y)}
+