<script lang="ts">
import { h, onMounted, onUnmounted, ref, watch } from "vue";

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();

		function calc() {
			const eachLength = contentEl.value.offsetWidth / props.repeat;
			const factor = 3000;
			const duration = props.duration / ((1 / eachLength) * factor);

			contentEl.value.style.animationDuration = `${duration}s`;
		}

		watch(() => props.duration, calc);

		onMounted(() => {
			calc();
		});

		onUnmounted(() => {});

		return {
			contentEl,
		};
	},
	render({ $slots, $style, $props: { duration, 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>

<style lang="scss" module>
.wrap {
	overflow: clip;
	animation-play-state: running;

	&:hover {
		animation-play-state: paused;
	}
}
.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 {
	0% {
		transform: translateX(0);
	}
	100% {
		transform: translateX(-100%);
	}
}
</style>