client: refactor marquee component to composition API

This commit is contained in:
Johann150 2022-10-07 13:32:44 +02:00
parent 8311b30b4c
commit 3f59b7f705
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1

View file

@ -1,94 +1,65 @@
<script lang="ts">
import { h, onMounted, onUnmounted, ref, watch } from 'vue';
<template>
<div class="marquee">
<span ref="contentEl" :class="{ content: true, paused, reverse }">
<span v-for="i in repeat" :key="i" class="text">
<slot></slot>
</span>
</span>
</div>
</template>
export default {
name: 'MarqueeText',
props: {
duration: {
type: Number,
default: 15,
},
repeat: {
type: Number,
default: 2,
},
paused: {
type: Boolean,
default: false,
},
reverse: {
type: Boolean,
default: false,
},
},
setup(props) {
const contentEl = ref();
<script lang="ts" setup>
import { watch, onMounted } from 'vue';
const props = withDefaults(defineProps<{
duration?: number;
repeat?: number;
paused?: boolean;
reverse?: boolean;
}>(), {
duration: 15,
repeat: 2,
paused: false,
reverse: false,
});
let contentEl = $ref();
function calc() {
const eachLength = contentEl.value.offsetWidth / props.repeat;
const eachLength = contentEl.offsetWidth / props.repeat;
const factor = 3000;
const duration = props.duration / ((1 / eachLength) * factor);
contentEl.value.style.animationDuration = `${duration}s`;
contentEl.style.animationDuration = `${duration}s`;
}
watch(() => props.duration, calc);
onMounted(() => {
calc();
});
onUnmounted(() => {
});
return {
contentEl,
};
},
render({
$slots, $style, $props: {
repeat, paused, reverse,
},
}) {
return h('div', { class: [$style.wrap] }, [
h('span', {
ref: 'contentEl',
class: [
paused
? $style.paused
: undefined,
$style.content,
],
}, Array(repeat).fill(
h('span', {
class: $style.text,
style: {
animationDirection: reverse
? 'reverse'
: undefined,
},
}, $slots.default()),
)),
]);
},
};
onMounted(calc);
</script>
<style lang="scss" module>
.wrap {
<style lang="scss" scoped>
.marquee {
overflow: clip;
animation-play-state: running;
&:hover {
animation-play-state: paused;
}
}
.content {
> .content {
display: inline-block;
white-space: nowrap;
animation-play-state: inherit;
&.paused {
animation-play-state: paused;
}
.text {
&.reverse {
animation-direction: reverse;
}
> .text {
display: inline-block;
animation-name: marquee;
animation-timing-function: linear;
@ -96,9 +67,9 @@ export default {
animation-duration: inherit;
animation-play-state: inherit;
}
.paused .text {
animation-play-state: paused;
}
}
@keyframes marquee {
0% { transform:translateX(0); }
100% { transform:translateX(-100%); }