Hyper Text
svelte-animations/hyper-textFreeBlock
An animated text component that creates a glitch effect by cycling through random characters before revealing the final text.
Install it
npx shadcn@latest add https://sv-animations.vercel.app/r/hyper-text.jsonSource
1<script lang="ts">2 import { onMount } from "svelte";3 import { motion, AnimatePresence } from "motion-sv";4 import { cn } from "$UTILS$";56 type CharacterSet = string[] | readonly string[];78 type ElementType = "div" | "span" | "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";910 interface HyperTextProps {11 text: string;12 class?: string;13 duration?: number;14 delay?: number;15 as?: ElementType;16 startOnView?: boolean;17 animateOnHover?: boolean;18 characterSet?: CharacterSet;19 }2021 let {22 text,23 class: className,24 duration = 800,25 delay = 0,26 as = "div",27 startOnView = false,28 animateOnHover = true,29 characterSet = Object.freeze("ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("")) as readonly string[],30 }: HyperTextProps = $props();3132 let MotionComponent = $derived(motion[as]);3334 let displayText = $state<string[]>([]);35 let isAnimating = $state(false);36 let iterationCount = $state(0);37 let elementRef: any = $state(null);3839 // Initialize displayText when text changes40 $effect(() => {41 displayText = text.split("");42 });4344 const getRandomInt = (max: number): number => Math.floor(Math.random() * max);4546 const handleAnimationTrigger = () => {47 if (animateOnHover && !isAnimating) {48 iterationCount = 0;49 isAnimating = true;50 }51 };5253 // Handle animation start based on view or delay54 onMount(() => {55 if (!startOnView) {56 const startTimeout = setTimeout(() => {57 isAnimating = true;58 }, delay);59 return () => clearTimeout(startTimeout);60 }6162 const observer = new IntersectionObserver(63 ([entry]) => {64 if (entry.isIntersecting) {65 setTimeout(() => {66 isAnimating = true;67 }, delay);68 observer.disconnect();69 }70 },71 { threshold: 0.1, rootMargin: "-30% 0px -30% 0px" }72 );7374 if (elementRef) {75 observer.observe(elementRef);76 }7778 return () => observer.disconnect();79 });8081 // Handle scramble animation82 $effect(() => {83 if (!isAnimating) return;8485 const maxIterations = text.length;86 const startTime = performance.now();87 let animationFrameId: number;8889 const animate = (currentTime: number) => {90 const elapsed = currentTime - startTime;91 const progress = Math.min(elapsed / duration, 1);9293 iterationCount = progress * maxIterations;9495 displayText = displayText.map((letter, index) =>96 letter === " "97 ? letter98 : index <= iterationCount99 ? text[index]100 : characterSet[getRandomInt(characterSet.length)]101 );102103 if (progress < 1) {104 animationFrameId = requestAnimationFrame(animate);105 } else {106// … truncated
What it pulls in
npm packages
Files it writes
More from Svelte Animations
All 66 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Beamanimated-beam | Svelte Animations | Blocks | Free | 1 dep · 6 files | |
| Animated Circular Progress Baranimated-circular-progress-bar | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Gradient Textanimated-gradient-text | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Grid Patternanimated-grid-pattern | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Listanimated-list | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Shiny Textanimated-shiny-text | Svelte Animations | Blocks | Free | no deps | |
| Animated Theme Toggleranimated-theme-toggler | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Arc Timelinearc-timeline | Svelte Animations | Blocks | Free | no deps · 3 files |
