Files
web_server/vue/src/views/home/Stamps.vue
Adam French b2042ffe78
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 16s
Add bouncing auto-scroll animation to stamps section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 21:24:40 +00:00

83 lines
1.9 KiB
Vue

<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import Touchscreen from "@/components/util/Touchscreen.vue";
import Link from "@/components/text/Link.vue";
import { shuffleArray } from "@/js/utils.js";
let srcs = [
"/img/stamps/portal.gif",
"/img/stamps/miku.gif",
"/img/stamps/utau.gif",
"/img/stamps/teto.webp",
"/img/stamps/3ds.jpg",
"/img/stamps/fry.png",
"/img/stamps/ai.png",
"/img/stamps/rei.png",
"/img/stamps/tetris.gif",
"/img/stamps/tf2.gif",
"/img/stamps/demo.gif",
];
shuffleArray(srcs);
const touchscreen = ref(null);
let animId = null;
let dx = 0.5;
let dy = 0.3;
function bounce() {
const el = touchscreen.value?.$el;
if (!el) return;
const maxX = el.scrollWidth - el.clientWidth;
const maxY = el.scrollHeight - el.clientHeight;
if (maxX > 0) {
el.scrollLeft += dx;
if (el.scrollLeft <= 0 || el.scrollLeft >= maxX) dx = -dx;
}
if (maxY > 0) {
el.scrollTop += dy;
if (el.scrollTop <= 0 || el.scrollTop >= maxY) dy = -dy;
}
animId = requestAnimationFrame(bounce);
}
onMounted(() => {
animId = requestAnimationFrame(bounce);
});
onUnmounted(() => {
if (animId) cancelAnimationFrame(animId);
});
</script>
<template>
<Touchscreen ref="touchscreen">
<div class="flex flex-wrap tst">
<Link bare href="https://www.adam-french.co.uk">
<img src="https://www.adam-french.co.uk/img/stamps/mine.gif" />
</Link>
<Link bare href="https://jacobbarron.xyz">
<img
src="https://jacobbarron.xyz/Banneh.gif"
alt="jacobbarron.xyz"
/>
</Link>
<img v-for="src in srcs" :src="src" />
</div>
</Touchscreen>
</template>
<style scoped>
img {
width: 89px;
height: 59px;
}
.tst {
min-width: calc(89px * 4);
}
</style>