1<script lang="ts">
2 import { genDollcode } from '$lib/dollcode';
3
4 interface Props {
5 top: number;
6 left: number;
7 kind?: string;
8 visits: number[];
9 id: string;
10 }
11
12 let { top, left, kind = 'normal', visits }: Props = $props();
13
14 let rotation = $state((Math.random() - 0.5) * 0.4);
15 const opacity = Math.min(Math.random() * 0.3 + 0.4, 0.7);
16
17 let closed = $state(false);
18 let look = $state('forward');
19 const looks = ['left', 'forward', 'right'];
20 const pickLook = $derived(() => {
21 const pickable = looks.filter((l) => {
22 return l !== look;
23 });
24 return pickable.at(Math.floor(Math.random() * pickable.length)) ?? 'forward';
25 });
26 const randomizeLook = () => {
27 look = pickLook();
28 rotation = (Math.random() - 0.5) * 0.4;
29 setTimeout(randomizeLook, 2000 + Math.random() * 6000);
30 };
31
32 let src = $derived(closed ? `/eyes/closed.webp` : `/eyes/${kind}_${look}.webp`);
33
34 // generate dollcode based on time, but mod by 3 hours
35 const timeDollcode = genDollcode((visits[0] / 1000) % (60 * 60 * 24));
36 const visitsDollcode = genDollcode(visits.length);
37
38 randomizeLook();
39</script>
40
41<!-- svelte-ignore a11y_mouse_events_have_key_events -->
42<!-- svelte-ignore a11y_no_static_element_interactions -->
43<div
44 class="group flex gap-4 items-center scale-[0.75]"
45 style="
46 position: fixed;
47 top: {top}vh;
48 left: {left}%;
49 opacity: {opacity};
50 flex-direction: column-reverse;
51 "
52 onmouseover={() => {
53 closed = true;
54 }}
55 onmouseleave={() => {
56 closed = false;
57 }}
58>
59 <span class="eye-text !text-base">{visitsDollcode}</span>
60 <!-- svelte-ignore a11y_missing_attribute -->
61 <img class="w-24 eye-image" style="transform: rotate({rotation}rad);" {src} />
62 <span class="eye-text">{timeDollcode}</span>
63</div>
64
65<style lang="postcss">
66 .eye-text {
67 @apply text-sm [font-family:Doll_Mono] opacity-30 group-hover:opacity-80;
68 }
69 .eye-image {
70 @apply opacity-50 group-hover:opacity-100;
71 image-rendering: pixelated !important;
72 filter: drop-shadow(4px 4px 0 theme(colors.ralsei.green.light))
73 drop-shadow(-4px -4px 0 theme(colors.ralsei.pink.neon));
74 }
75</style>