enhance(client): better marquee component
This commit is contained in:
		
							
								
								
									
										97
									
								
								packages/client/src/components/marquee.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								packages/client/src/components/marquee.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| <script lang="ts"> | ||||
| import { h, onMounted, onUnmounted, ref } 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`; | ||||
| 		} | ||||
|  | ||||
| 		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; | ||||
| } | ||||
| .content { | ||||
| 	display: inline-block; | ||||
| 	white-space: nowrap; | ||||
| } | ||||
| .text { | ||||
| 	display: inline-block; | ||||
| 	animation-name: marquee; | ||||
| 	animation-timing-function: linear; | ||||
| 	animation-iteration-count: infinite; | ||||
| 	animation-duration: inherit; | ||||
| } | ||||
| .paused .text { | ||||
| 	animation-play-state: paused; | ||||
| } | ||||
| @keyframes marquee { | ||||
| 	0% { transform:translateX(0); } | ||||
| 	100% { transform:translateX(-100%); } | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo