Skip to content

Commit

Permalink
feat(zkgm): save progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Swepool committed Dec 4, 2024
1 parent 9605d3a commit 23e771c
Show file tree
Hide file tree
Showing 14 changed files with 756 additions and 8 deletions.
2 changes: 1 addition & 1 deletion zkgm-dev/src/app.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import 'tailwindcss/utilities'
@import 'tailwindcss/utilities';
2 changes: 1 addition & 1 deletion zkgm-dev/src/app.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="en">
<html lang="en" class="bg-black">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
Expand Down
117 changes: 117 additions & 0 deletions zkgm-dev/src/lib/components/Agents.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<script>
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
let containerWidth;
let containerRef;
let characters = [
{ id: 'omar', x: 10, direction: 1, speed: 2 },
{ id: 'lukas', x: 300, direction: -1, speed: 3 },
{ id: 'ben', x: 600, direction: 1, speed: 1.5 },
{ id: 'cor', x: 900, direction: -1, speed: 2.5 }
];
const CHARACTER_WIDTH = 48;
const COLLISION_THRESHOLD = 2;
const MIN_SPEED = 1;
const MAX_SPEED = 4;
let animationFrameId;
function getRandomSpeed() {
return MIN_SPEED + Math.random() * (MAX_SPEED - MIN_SPEED);
}
function handleResize() {
if (containerRef) {
containerWidth = containerRef.offsetWidth;
}
}
function updatePositions() {
const newPositions = characters.map(char => {
const newX = char.x + (char.speed * char.direction);
return { ...char, newX };
});
characters = newPositions.map((char, index) => {
let finalX = char.newX;
let newDirection = char.direction;
let newSpeed = char.speed;
if (finalX <= 0) {
newDirection = 1;
finalX = 0;
newSpeed = getRandomSpeed();
} else if (finalX >= containerWidth - CHARACTER_WIDTH) {
newDirection = -1;
finalX = containerWidth - CHARACTER_WIDTH;
newSpeed = getRandomSpeed();
}
for (let i = 0; i < newPositions.length; i++) {
if (i !== index) {
const other = newPositions[i];
const distance = char.direction > 0
? other.newX - (char.newX + CHARACTER_WIDTH)
: char.newX - (other.newX + CHARACTER_WIDTH);
const isApproaching = (char.direction > 0 && other.direction < 0) ||
(char.direction < 0 && other.direction > 0);
if (isApproaching && Math.abs(distance) <= COLLISION_THRESHOLD) {
finalX = char.x;
newDirection *= -1;
newSpeed = getRandomSpeed();
break;
}
}
}
return {
...char,
x: finalX,
direction: newDirection,
speed: newSpeed
};
});
animationFrameId = browser ? requestAnimationFrame(updatePositions) : null;
}
onMount(() => {
if (browser) {
handleResize();
window.addEventListener('resize', handleResize);
animationFrameId = requestAnimationFrame(updatePositions);
}
});
onDestroy(() => {
if (browser) {
window.removeEventListener('resize', handleResize);
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
}
}
});
</script>

<div
bind:this={containerRef}
class="relative w-full h-24 bg-transparent overflow-hidden"
>
{#each characters as char (char.id)}
<div
class="absolute bottom-0 transition-transform duration-100 ease-linear"
style="transform: translateX({char.x}px) scaleX({char.direction > 0 ? 1 : -1})"
>
<img
src="/agents/{char.id}.png"
alt="Agent {char.id}"
class="w-12 h-12"
/>
</div>
{/each}
</div>
12 changes: 12 additions & 0 deletions zkgm-dev/src/lib/components/Bar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts">
import Blink from "$lib/components/Blink.svelte";
import Agents from "$lib/components/Agents.svelte";
</script>

<div class="fixed bottom-0 inset-x-0">
<Agents/>
<div class="w-full bg-black p-4 flex items-center justify-center">
<p class="font-supermolot font-bold text-union-accent-500"><Blink /></p>
</div>
</div>
87 changes: 87 additions & 0 deletions zkgm-dev/src/lib/components/Blink.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<script lang="ts">
type Props = {
loading?: boolean
sleep?: boolean
love?: boolean
}
let { loading = false, sleep = false, love = false }: Props = $props()
let eye = $state(sleep ? "-" : love ? "" : "0")
let blinkInterval: number | NodeJS.Timeout
function blinkEye() {
if (!(sleep || love)) {
eye = "-"
setTimeout(() => {
eye = "0"
}, 100)
}
}
function startRandomBlinking() {
blinkInterval = setInterval(() => {
if (!(sleep || love) && Math.random() < 0.08) {
blinkEye()
}
}, 200)
}
$effect(() => {
if (sleep) {
eye = "×"
clearInterval(blinkInterval)
} else if (love) {
eye = ""
clearInterval(blinkInterval)
} else {
eye = "0"
startRandomBlinking()
}
return () => {
clearInterval(blinkInterval)
}
})
</script>

<span>
{eye}<span class:wobble={loading && !sleep}><span>_</span><span>_</span><span>_</span><span>_</span><span>_</span><span>_</span><span>_</span></span>{eye}
</span>

<style>
.wobble {
display: inline-block;
}
.wobble span {
display: inline-block;
animation: wobble 1s infinite ease-in-out;
}
@keyframes wobble {
0% {
transform: translateY(0);
}
25% {
transform: translateY(-3px);
}
50% {
transform: translateY(0);
}
75% {
transform: translateY(3px);
}
100% {
transform: translateY(0);
}
}
.wobble span:nth-child(1) { animation-delay: 0s; }
.wobble span:nth-child(2) { animation-delay: 0.1s; }
.wobble span:nth-child(3) { animation-delay: 0.2s; }
.wobble span:nth-child(4) { animation-delay: 0.3s; }
.wobble span:nth-child(5) { animation-delay: 0.4s; }
.wobble span:nth-child(6) { animation-delay: 0.5s; }
.wobble span:nth-child(7) { animation-delay: 0.6s; }
</style>
Loading

0 comments on commit 23e771c

Please sign in to comment.