I want to make a component that makes a typewriter effect, but I need to keep the styling inside the slot so I can use any text style with the same effect.
Main file :
<TypewriterText>
<h1>Hey what's up!</h1>
</TypewriterText>
TypewriterText.svelte :
<script>
import { onMount } from 'svelte';
let content = '';
let currentText = '';
let currentIndex = 0;
onMount(() => {
const data = document.querySelector('.hidden');
content = data?.innerText || '';
typeWriter();
});
function typeWriter() {
if (currentIndex < content.length) {
currentText += content.charAt(currentIndex);
currentIndex++;
setTimeout(typeWriter, 10);
}
}
</script>
<span class="hidden"><slot /></span>
{currentText}
<style>
.hidden {
display: none;
}
</style>
The only way I found is to hide the slot and reproduce the innerText below. But this way I lose the html tag...
Thx a lot !!
You have to switch h1
and TypewriterText
so it applies the styling before the text effect.
<h1>
<TypewriterText>Hey what's up!</TypewriterText>
</h1>
Also, using an action would be more suited to your need.
<script>
const typewriter = node => {
let timeout = undefined;
const fullText = node.textContent;
node.textContent = '';
type();
function type() {
if (node.textContent.length >= fullText.length)
return;
node.textContent = fullText.substring(0, node.textContent.length + 1);
timeout = setTimeout(type, 100);
}
return { destroy() { clearTimeout(timeout); } }
}
</script>
<h1 use:typewriter>Hello there</h1>