Skip to content

Commit 3ea0146

Browse files
committed
add: clock thing
1 parent bd0dc15 commit 3ea0146

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

src/App.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<script lang="ts">
22
import ThemeToggle from "./lib/components/ThemeToggle.svelte";
33
import MainBird from "./lib/components/MainBird.svelte";
4+
import Clock from "./lib/components/Clock.svelte";
45
</script>
56

67
<ThemeToggle />
78
<header class="fixed flex flex-row bg-transparent"></header>
89
<main class="flex flex-col justify-center items-center">
10+
<Clock />
911
<MainBird />
1012
<h1 class="text-4xl text-center mt-5">hi there</h1>
1113
</main>

src/lib/components/Clock.svelte

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<script lang="ts">
2+
import { onDestroy, onMount } from "svelte";
3+
4+
let marker: HTMLDivElement;
5+
6+
let timeHours = $state(0);
7+
let timeMinutes = $state(0);
8+
let totalMinutes = $derived(timeHours * 60 + timeMinutes);
9+
10+
let angle = $derived.by(() => {
11+
let a = totalMinutes;
12+
if (totalMinutes >= 720) a -= 720;
13+
return mapRange(a, 0, 720, -85, 85); // NOTE: consider radians
14+
});
15+
16+
let interval: any;
17+
18+
function mapRange(
19+
x: number,
20+
inMin: number,
21+
inMax: number,
22+
outMin: number,
23+
outMax: number,
24+
): number {
25+
return ((x - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
26+
}
27+
28+
function getTime(hasTemporal: boolean): [number, number] {
29+
let h: number;
30+
let m: number;
31+
32+
if (hasTemporal) {
33+
let now = Temporal.Now.plainTimeISO();
34+
h = now.hour;
35+
m = now.minute;
36+
} else {
37+
let legacyNow: Date = new Date();
38+
h = legacyNow.getHours();
39+
m = legacyNow.getMinutes();
40+
}
41+
42+
return [h, m];
43+
}
44+
45+
function updateMarker() {
46+
marker.style.transform = `translateY(-15vh) rotate(${angle}deg)`;
47+
}
48+
49+
onMount(() => {
50+
let hasTemporal: boolean = false;
51+
try {
52+
hasTemporal = Temporal.Now.instant() !== undefined;
53+
} catch (e) {
54+
console.warn(
55+
"Temporal API not implemented, falling back to Date API...",
56+
);
57+
}
58+
59+
interval = setInterval(() => {
60+
[timeHours, timeMinutes] = getTime(hasTemporal);
61+
updateMarker();
62+
}, 1000);
63+
});
64+
65+
onDestroy(() => {
66+
clearInterval(interval);
67+
});
68+
</script>
69+
70+
<div bind:this={marker} class="clock">hi</div>
71+
72+
<style>
73+
.clock {
74+
position: absolute;
75+
transform-origin: 50% 45vh;
76+
transform: translateY(-15vh) rotate(-90deg);
77+
transition: transform 1s ease-in-out;
78+
}
79+
</style>

0 commit comments

Comments
 (0)