client: refactor marquee component to composition API

This commit is contained in:
Johann150 2022-10-07 13:32:44 +02:00 committed by Francis Dinh
parent f6a5459f91
commit b95f90eb15
Signed by: norm
GPG key ID: 7123E30E441E80DE

View file

@ -1,104 +1,75 @@
<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: {
type: Number,
default: 15,
},
repeat: {
type: Number,
default: 2,
},
paused: {
type: Boolean,
default: false,
},
reverse: {
type: Boolean,
default: false,
},
},
setup(props) {
const contentEl = ref();
function calc() { const props = withDefaults(defineProps<{
const eachLength = contentEl.value.offsetWidth / props.repeat; duration?: number;
const factor = 3000; repeat?: number;
const duration = props.duration / ((1 / eachLength) * factor); paused?: boolean;
reverse?: boolean;
}>(), {
duration: 15,
repeat: 2,
paused: false,
reverse: false,
});
contentEl.value.style.animationDuration = `${duration}s`; let contentEl = $ref();
}
watch(() => props.duration, calc); function calc() {
const eachLength = contentEl.offsetWidth / props.repeat;
const factor = 3000;
const duration = props.duration / ((1 / eachLength) * factor);
onMounted(() => { contentEl.style.animationDuration = `${duration}s`;
calc(); }
});
onUnmounted(() => { watch(() => props.duration, calc);
}); onMounted(calc);
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 {
display: inline-block;
white-space: nowrap;
animation-play-state: inherit;
&.paused {
animation-play-state: paused;
}
&.reverse {
animation-direction: reverse;
}
> .text {
display: inline-block;
animation-name: marquee;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: inherit;
animation-play-state: inherit;
}
}
} }
.content {
display: inline-block;
white-space: nowrap;
animation-play-state: inherit;
}
.text {
display: inline-block;
animation-name: marquee;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 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%); }