企业官网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

89 lines
1.8 KiB

<template>
<span
v-if="!props.highlightText"
:class="cn('inline-block px-1 pb-1 highlight-all', props.class)"
>
{{ props.text }}
</span>
<span v-else>
{{ beforeText }}
<div :class="cn('inline-block highlight-all', props.class)">
{{ props.highlightText }}
</div>
{{ afterText }}
</span>
</template>
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
interface Props {
delay?: number
duration?: number
class?: HTMLAttributes['class']
textEndColor?: string
highlightText?: string
text: string
}
const props = withDefaults(defineProps<Props>(), {
delay: 0,
duration: 2000,
endColor: 'inherit',
})
const delayMs = computed(() => `${props.delay}ms`)
const durationMs = computed(() => `${props.duration}ms`)
const beforeText = computed(() => {
if (!props.highlightText || !props.text) return ''
const index = props.text.indexOf(props.highlightText)
if (index === -1) return props.text
return props.text.substring(0, index)
})
const afterText = computed(() => {
if (!props.highlightText || !props.text) return ''
const index = props.text.indexOf(props.highlightText)
if (index === -1) return ''
return props.text.substring(index + props.highlightText.length)
})
</script>
<style scoped>
@keyframes background-expand {
0% {
background-size: 0% 100%;
}
100% {
background-size: 100% 100%;
}
}
@keyframes text-color-change {
0% {
color: inherit;
}
100% {
color: v-bind(textEndColor);
}
}
span {
background-size: 0% 100%;
background-repeat: no-repeat;
background-position: left center;
}
.highlight-all,
.highlight-text {
animation:
background-expand v-bind(durationMs) ease-in-out v-bind(delayMs) forwards,
text-color-change v-bind(durationMs) ease-in-out v-bind(delayMs) forwards;
}
</style>