Files
web_server/nginx/vue/src/components/text/Headline.vue
2026-02-10 16:46:49 +00:00

69 lines
1.2 KiB
Vue

<script setup>
import { onMounted, useTemplateRef, onUnmounted } from "vue";
const container = useTemplateRef("container");
const item1 = useTemplateRef("item1");
let offset = 0;
let rafId;
const speed = 0.5; // pixels per frame
function animate() {
const ctnr = container.value;
const it1 = item1.value;
const width = Math.max(ctnr.offsetWidth, it1.scrollWidth);
offset -= speed;
if (offset <= -width) {
offset += width;
}
ctnr.style.transform = `translateX(${offset}px)`;
rafId = requestAnimationFrame(animate);
}
onMounted(() => {
rafId = requestAnimationFrame(animate);
});
onUnmounted(() => {
cancelAnimationFrame(rafId);
});
</script>
<template>
<div class="root">
<div class="container" ref="container">
<div ref="item1">
<slot />
</div>
<div>
<slot />
</div>
</div>
</div>
</template>
<style scoped>
.root {
overflow: hidden;
}
.container {
width: fit-content;
height: fit-content;
display: grid;
grid-auto-flow: column;
grid-auto-columns: max-content;
/* Each column fits its content */
overflow-x: visible;
will-change: transform;
gap: 10em;
}
</style>