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