Add SplitText component

This commit is contained in:
2021-10-18 16:18:16 +02:00
parent 7f8dc8cec6
commit 691e499e9e
3 changed files with 65 additions and 5 deletions

View File

@@ -0,0 +1,38 @@
<script lang="ts">
import { splitText } from '$utils/functions'
export let text: string
export let mode: string = undefined
export let clone: boolean = false
$: split = splitText(text, mode)
const classes = [
'text-split',
$$props.class
].join(' ').trim()
</script>
{#if clone}
{#if mode && mode === 'words'}
<span class={classes}>
{#each Array(2) as _, index}
<span class="text-split__line" aria-hidden={index === 1}>
{#each split as word, i}
<span class="word" style="--i-w: {i};">{word}</span>{#if word.includes('\n')}<br>{/if}
<!-- svelte-ignore empty-block -->
{#if i < split.length - 1}{/if}
{/each}
</span>
{/each}
</span>
{:else}
<span class={classes}>
{#each Array(2) as _, index}
<span class="text-split__line" aria-hidden={index === 1}>
{text}
</span>
{/each}
</span>
{/if}
{/if}

View File

@@ -78,10 +78,8 @@ button {
transform-style: preserve-3d;
will-change: transform;
}
.words-3d {
perspective: 800px;
span {
transform-origin: 0 85%;
.text-split {
span, &__line {
transition: opacity 0.7s var(--ease-quart), transform 0.7s var(--ease-quart);
}
}

View File

@@ -24,6 +24,30 @@ export const debounce = (func: Function, timeout: number) => {
}
/**
* Split text
* @description Split a string into words or characters
* @returns string[]
*/
export const splitText = (text: string, mode: string = 'words'): string[] => {
// Split by words
if (mode === 'words') {
const words = text
.replace(/\\n/g, '\n')
.replace(/\s+/g, m => m.includes('\n') ? '\n ' : ' ')
.trim()
.split(' ')
return words
}
// Split by chars
else if (mode === 'chars') {
const chars = Array.from(text).map(char => char === ' ' ? '\xa0' : char)
return chars
}
}
/**
* Linear Interpolation
*/