Fix Smooth Transition

This commit is contained in:
Utkarsh-Singhal-26
2025-07-12 18:40:23 +05:30
parent 90a41d1469
commit adfaf20b5f

View File

@@ -46,7 +46,7 @@ const props = withDefaults(defineProps<RotatingTextProps>(), {
}); });
const currentTextIndex = ref<number>(0); const currentTextIndex = ref<number>(0);
let intervalId: number | undefined = undefined; let intervalId: number | null = null;
const splitIntoCharacters = (text: string): string[] => { const splitIntoCharacters = (text: string): string[] => {
if (typeof Intl !== 'undefined' && Intl.Segmenter) { if (typeof Intl !== 'undefined' && Intl.Segmenter) {
@@ -85,14 +85,6 @@ const elements = computed(() => {
})); }));
}); });
const getPreviousCharsCount = (wordIndex: number): number => {
return elements.value.slice(0, wordIndex).reduce((sum, word) => sum + word.characters.length, 0);
};
const getTotalCharsCount = (): number => {
return elements.value.reduce((sum, word) => sum + word.characters.length, 0);
};
const getStaggerDelay = (index: number, totalChars: number): number => { const getStaggerDelay = (index: number, totalChars: number): number => {
const total = totalChars; const total = totalChars;
@@ -112,9 +104,7 @@ const getStaggerDelay = (index: number, totalChars: number): number => {
const handleIndexChange = (newIndex: number) => { const handleIndexChange = (newIndex: number) => {
currentTextIndex.value = newIndex; currentTextIndex.value = newIndex;
if (props.onNext) { if (props.onNext) props.onNext(newIndex);
props.onNext(newIndex);
}
}; };
const next = () => { const next = () => {
@@ -150,7 +140,7 @@ const jumpTo = (index: number) => {
const reset = () => { const reset = () => {
if (currentTextIndex.value !== 0) { if (currentTextIndex.value !== 0) {
currentTextIndex.value = 0; handleIndexChange(0);
} }
}; };
@@ -162,14 +152,14 @@ defineExpose({
}); });
watch( watch(
() => props.auto, () => [props.auto, props.rotationInterval],
newAuto => { () => {
if (intervalId) { if (intervalId) {
clearInterval(intervalId); clearInterval(intervalId);
intervalId = undefined; intervalId = null;
} }
if (newAuto) { if (props.auto) {
intervalId = setInterval(next, props.rotationInterval); intervalId = setInterval(next, props.rotationInterval);
} }
}, },
@@ -206,8 +196,8 @@ onUnmounted(() => {
:key="currentTextIndex" :key="currentTextIndex"
tag="span" tag="span"
:class="cn(splitBy === 'lines' ? 'flex flex-col w-full' : 'flex flex-wrap whitespace-pre-wrap relative')" :class="cn(splitBy === 'lines' ? 'flex flex-col w-full' : 'flex flex-wrap whitespace-pre-wrap relative')"
layout
aria-hidden="true" aria-hidden="true"
layout
> >
<span v-for="(wordObj, wordIndex) in elements" :key="wordIndex" :class="cn('inline-flex', splitLevelClassName)"> <span v-for="(wordObj, wordIndex) in elements" :key="wordIndex" :class="cn('inline-flex', splitLevelClassName)">
<Motion <Motion
@@ -219,13 +209,16 @@ onUnmounted(() => {
:exit="exit" :exit="exit"
:transition="{ :transition="{
...transition, ...transition,
delay: getStaggerDelay(getPreviousCharsCount(wordIndex) + charIndex, getTotalCharsCount()) delay: getStaggerDelay(
elements.slice(0, wordIndex).reduce((sum, word) => sum + word.characters.length, 0) + charIndex,
elements.reduce((sum, word) => sum + word.characters.length, 0)
)
}" }"
:class="cn('inline-block', elementLevelClassName)" :class="cn('inline-block', elementLevelClassName)"
> >
{{ char }} {{ char }}
</Motion> </Motion>
<span v-if="wordObj.needsSpace" class="inline-block">&nbsp;</span> <span v-if="wordObj.needsSpace" class="whitespace-pre"> </span>
</span> </span>
</Motion> </Motion>
</AnimatePresence> </AnimatePresence>