Skip to content

Commit

Permalink
feat: add typing animation component
Browse files Browse the repository at this point in the history
  • Loading branch information
selemondev committed Oct 8, 2024
1 parent a3d13a8 commit 4a8f405
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,5 @@ import Demos from './src/components/Demos.vue'
<demo src="./src/example/orbitingCircles/Demo.vue" />

<demo src="./src/example/meteors/Demo.vue" />

<demo src="./src/example/typingAnimation/Demo.vue" />
51 changes: 51 additions & 0 deletions docs/src/components/spark-ui/typingAnimation/typing-animation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script setup lang='ts'>
import { ref, watch } from 'vue'
import { cn } from '../../../lib/utils'
interface TypingAnimationProps {
text: string
duration?: number
class?: string
}
const props = withDefaults(defineProps<TypingAnimationProps>(), {
duration: 300,
})
const displayedText = ref('')
const i = ref(0)
function handleTypingEffect(d: number, n: number) {
const typingEffect = setInterval(() => {
if (n < props.text.length) {
displayedText.value = props.text.substring(0, n + 1)
n = n + 1
}
else {
clearInterval(typingEffect)
}
}, d)
return () => {
clearInterval(typingEffect)
}
}
watch(() => [props.duration, i.value], ([d, n]) => {
handleTypingEffect(d, n)
}, {
deep: true,
immediate: true,
})
const className = cn(
'font-display text-center text-4xl font-bold leading-[5rem] tracking-[-0.02em] drop-shadow-sm',
props.class,
)
</script>

<template>
<h1 :class="className">
{{ displayedText ? displayedText : props.text }}
</h1>
</template>
7 changes: 7 additions & 0 deletions docs/src/example/typingAnimation/Demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script setup lang='ts'>
import TypingAnimation from './typing-animation.vue'
</script>

<template>
<TypingAnimation class="text-4xl font-bold text-black" text="Typing Animation" />
</template>
51 changes: 51 additions & 0 deletions docs/src/example/typingAnimation/typing-animation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script setup lang='ts'>
import { ref, watch } from 'vue'
import { cn } from '../../lib/utils'
interface TypingAnimationProps {
text: string
duration?: number
class?: string
}
const props = withDefaults(defineProps<TypingAnimationProps>(), {
duration: 300,
})
const displayedText = ref('')
const i = ref(0)
function handleTypingEffect(d: number, n: number) {
const typingEffect = setInterval(() => {
if (n < props.text.length) {
displayedText.value = props.text.substring(0, n + 1)
n = n + 1
}
else {
clearInterval(typingEffect)
}
}, d)
return () => {
clearInterval(typingEffect)
}
}
watch(() => [props.duration, i.value], ([d, n]) => {
handleTypingEffect(d, n)
}, {
deep: true,
immediate: true,
})
const className = cn(
'font-display text-center text-4xl font-bold leading-[5rem] tracking-[-0.02em] drop-shadow-sm',
props.class,
)
</script>

<template>
<h1 :class="className">
{{ displayedText ? displayedText : props.text }}
</h1>
</template>

0 comments on commit 4a8f405

Please sign in to comment.