Add SplitText component
This commit is contained in:
38
src/components/SplitText.svelte
Normal file
38
src/components/SplitText.svelte
Normal 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}
|
||||||
@@ -78,10 +78,8 @@ button {
|
|||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
.words-3d {
|
.text-split {
|
||||||
perspective: 800px;
|
span, &__line {
|
||||||
|
transition: opacity 0.7s var(--ease-quart), transform 0.7s var(--ease-quart);
|
||||||
span {
|
|
||||||
transform-origin: 0 85%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
* Linear Interpolation
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user