Components/MotionText

MotionText

45 source-mapped text effects, four registry reveals, scramble, inline caller media and interactive focus blur.

Since 0.6.3BETA

This component doc is in progress

This page is still being migrated. Demos and API details may change.

Overview

TxMotionText preserves the 45 original Amicro catalog IDs and seven independent registry/source additions. Each preset keeps its own direction, grouping, stagger, scale, blur, mask, 3D transform or continuous rhythm. MOTION_TEXT_VARIANTS provides typed names, groups, segmentation and fixed source references; MOTION_TEXT_VARIANT_IDS is the complete ID list.

Entrance and decorative playback are separate from value changes. A mounted TxTextMorph owns every text update; there is no second diff engine and replay does not remount it. The original is exposed to screen readers once. Only one text layer is selectable: the decorative original during normal playback, the unchanged original during scramble, and the TextMorph layer at rest. Whitespace, newlines, emoji ZWJ sequences and combining marks are retained.

Usage

All source variants

Select any of the 52 IDs in the live catalog, filter by group/name/ID, use Next to traverse them, edit multilingual text, or replay repeatedly. Hover presets respond to individual graphemes/words and support keyboard focus. Pause restores the complete readable text, including during typewriter and scramble playback.

Loading demo...

Source interactions

Scramble is real hover/focus-driven substitution, not a static title. It can reveal from the start, end or center using whole graphemes, and can use the original character pool or caller-supplied characters. Whitespace is never scrambled. focus-blur takes caller items: links remain native links and items without href are buttons emitting select. The hovered/focused item remains sharp while peers soften; focus brackets use the shared spring.

<TxMotionText
  text="ไฟ็•™ ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿ’ป ๅ’Œ eฬ"
  variant="scramble-hover"
  sequential
  reveal-direction="center"
  :use-original-chars-only="false"
  characters="ABC123โœฆ"
/>
<TxMotionText
  variant="focus-blur"
  :items="[
    { id: 'design', label: 'Design', href: '/design' },
    { id: 'motion', label: 'Motion' },
  ]"
  @select="item => selectedId = item.id"
/>

Inline media uses caller mediaSrc, image/video properties, or the media slot. With the default hover trigger, leaving both pointer and keyboard focus closes the media. trigger="manual" uses the exposed animate()/reset() methods; trigger="in-view" opens on visibility. Reduced motion reveals media immediately without a width/scale animation. Built-in and slotted videos pause when motion is inactive or the media closes; slotted media receives active and open for its own resource lifecycle.

<TxMotionText
  variant="media-between-text"
  first-text="Crafting"
  second-text="experiences"
  :media-src="imageUrl"
  media-alt="Abstract texture"
/>
<TxMotionText variant="media-between-text" first-text="Your" second-text="media">
  <template #media="{ active, open }">
    <img :src="imageUrl" alt="Caller illustration">
  </template>
</TxMotionText>

Best Practices

  • Keep text, media and items caller-owned. No demo business data is embedded in the component.
  • Keep the component mounted when replacing text. Use replayKey or replay() for decorative replay rather than keying the component by the value.
  • Use a valid locale for Chinese word segmentation. Grapheme effects never split a family emoji or a combining mark; without Intl.Segmenter, decorative grapheme playback keeps the whole value as a safe unit.
  • Hover effects are decoration, not action buttons. Use the native focus-blur items or a separate semantic control for navigation/actions.
  • Use paused to stop all owned animations, scramble timeouts and video playback. Ambient effects run only while mounted, intersecting, document-visible, enabled and not reduced, including across KeepAlive suspension.
  • The morph engine does not soft-wrap. Supply explicit newlines (text-reveal animates each line) or choose a wrapping text primitive for prose.
  • Tracking presets converge to natural body spacing. Glow crossfades two static shadow layers, and hover colors change immediately rather than tweening.

API Reference

Props

PropTypeDefaultDescription
textstring''Original text for the catalog, registry and scramble effects.
variantMotionTextVariant'txt-dia'One of the 52 IDs below.
size'xs' | 'sm' | 'md' | 'lg''md'Token-controlled content sizing.
tag'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3''span'Root semantic element.
localestring'en'Word/grapheme segmentation and TextMorph locale.
pausedbooleanfalseCancel motion and show the complete readable value.
trigger'in-view' | 'hover' | 'manual'Source-dependentEntrances/ambient effects default to in-view; scramble/media to hover. Character/word hover and focus items retain their native interactions.
replayKeystring | numberโ€”Changing the key replays the effect without remounting TextMorph.
durationMsnumberSource-dependentTimed-effect duration in ms. A physical spring owns its settling duration.
staggerMsnumberSource-dependentOverride each source unit delay in ms.
transitionTransitionSource-dependentShared 'snappy' | 'smooth' | 'bouncy', { stiffness?, damping?, mass? }, or { duration, ease? }; overrides source timing.
initialBlurnumber8Registry blur-text blur radius, in pixels.
yOffsetnumber15Registry character-stagger vertical start offset.
scrambleSpeednumber40Milliseconds between scramble frames.
maxIterationsnumber10Non-sequential scramble iterations.
sequentialbooleanfalseReveal a growing set of whole graphemes per frame.
revealDirection'start' | 'end' | 'center''start'Sequential scramble reveal direction.
useOriginalCharsOnlybooleantruePick replacements from the original non-whitespace graphemes.
charactersstringLatin letters, digits and symbolsCustom replacement pool when original-only is false.
firstTextstring''Text preceding inline media.
secondTextstring''Text following inline media.
mediaSrcstringโ€”Caller image/video URL; no fabricated fallback.
mediaType'image' | 'video''image'Built-in media renderer.
mediaAltstring''Image alternative text / video accessible name.
mediaPosterstring''Caller video poster.
mediaWidthnumber70Expanded inline media width in pixels.
mediaHeightnumber40Inline media height in pixels.
mediaAutoplaybooleantrueRequest playback only while active and open; browser autoplay policy can reject it.
mediaLoopbooleantrueLoop built-in video only while active.
mediaMutedbooleantrueBuilt-in video muted state.
mediaPlaysinlinebooleantrueBuilt-in video inline playback attribute.
itemsreadonly MotionTextItem[][]Focus items { id, label, href? }. Stable IDs preserve mounted label engines.
blurAmountnumber4Blur radius for inactive focus items, in pixels.
opacityAmountnumber0.4Opacity of inactive focus items.
showBracketsbooleantrueShared-spring focus brackets.

Events

EventPayloadDescription
animation-startMotionTextVariantDecorative playback or a text-value morph begins.
animation-completeMotionTextVariantA finite playback/morph completes. Ambient loops do not periodically announce completion.
animation-cancelMotionTextVariantA running finite playback/morph is interrupted.
selectMotionTextItemA focus item is activated. Native links keep their navigation behavior.
media-errorEventThe caller image/video reports a real load error.

Slots

SlotScopeDescription
media{ open: boolean, active: boolean }Replace the built-in image/video while retaining hover/manual/in-view geometry and activity control.

Exposed Methods

MethodDescription
replay()Cancel the prior decorative run and replay; opens inline media.
animate()Same explicit playback/open action for the upstream ref-trigger contract.
reset()Cancel work, restore the original and close media; clears focus-item decoration.

MotionTextProps, MotionTextItem, MotionTextVariant, MotionTextVariantInfo, MotionTextTrigger, MotionTextRevealDirection, MotionTextMediaSlotProps, MotionTextSlots, MotionTextExpose and TxMotionTextInstance are exported from @talex-touch/tuffex/motion-text.

Variant catalogue

Original IDEffect retained
txt-diaPolygon mask reveal plus 8px blur, 850ms.
txt-blurWhole text 12px blur, 0.9โ†’1 scale and fade, 700ms.
txt-shimmerStatic clipped gradient with a 2s opacity shimmer.
txt-typewriterWhole-grapheme stepping over 1.2s with a moving blinking cursor.
txt-revealHorizontal inset-mask reveal, 750ms.
txt-fade-charGrapheme fade, 300ms / 50ms stagger.
txt-fade-wordWord fade, 400ms / 150ms stagger.
txt-fade-textWhole-text fade, 800ms.
txt-blurup-wordWords rise 15px out of 8px blur, 500ms / 120ms.
txt-blurup-charGraphemes rise 15px out of 8px blur, 400ms / 40ms.
txt-staggerWords rise 20px with expo easing, 500ms / 100ms.
txt-slideup-charMasked graphemes from +100% Y, 400ms / 40ms.
txt-slideup-wordMasked words from +100% Y, 500ms / 100ms.
txt-slideup-textMasked whole text from +100% Y, 600ms.
txt-slidedown-charMasked graphemes from โˆ’100% Y, 400ms / 40ms.
txt-slidedown-wordMasked words from โˆ’100% Y, 500ms / 100ms.
txt-slideleft-charGraphemes from +40px X with fade, 400ms / 40ms.
txt-slideright-charGraphemes from โˆ’40px X with fade, 400ms / 40ms.
txt-dropin-charGraphemes drop 50px, spring 500/25, 40ms stagger.
txt-riseup-wordWords rise 30px and scale 0.8โ†’1, spring 400/22, 120ms stagger.
txt-bouncein-charGrapheme scale 0โ†’1.3โ†’1 and fade, 500ms / 50ms.
txt-scalein-charGrapheme scale 0โ†’1, spring 450/22, 40ms stagger.
txt-scalein-wordWord scale 0.4โ†’1 and fade, 400ms / 120ms.
txt-scalein-textWhole-text scale 0.5โ†’1 and fade, spring 400/25.
txt-zoomin-textWhole-text scale 0.2โ†’1 and fade, 600ms.
txt-zoomout-textWhole-text scale 1.8โ†’1 and fade, 600ms.
txt-flipy-charGrapheme Y-axis 90ยฐโ†’0ยฐ rotation, 500ms / 50ms.
txt-flipx-charGrapheme X-axis 90ยฐโ†’0ยฐ rotation, 500ms / 50ms.
txt-rotatein-charGrapheme โˆ’45ยฐโ†’0ยฐ plus 0.5โ†’1 scale/fade, 400ms / 40ms.
txt-swing-wordTop-origin word X rotation โˆ’90ยฐโ†’0ยฐ, spring 350/18, 120ms stagger.
txt-stretchx-charGrapheme X scale 2.5โ†’1 and fade, 400ms / 40ms.
txt-stretchy-charGrapheme Y scale 2.5โ†’1 and fade, 400ms / 40ms.
txt-skewx-charGrapheme X skew โˆ’30ยฐโ†’0ยฐ and fade, 400ms / 40ms.
txt-trackingin-textWide 0.6em spread converges to natural spacing, 700ms.
txt-trackingout-textTight โˆ’0.2em spread expands to natural spacing, 700ms.
txt-spring-textPer-grapheme hover lift โˆ’8px and scale 1.2, spring 500/15.
txt-hoverlift-charThe source's same per-grapheme hover lift/scale trajectory.
txt-hoverlift-wordWord hover lift โˆ’6px, spring 400/18.
txt-hoverscale-charGrapheme hover scale 1.4, spring 500/18.
txt-hoverscale-wordWord hover scale 1.25, spring 400/20.
txt-float-char0โ†’โˆ’6pxโ†’0, 2s cycle / 100ms phase per grapheme.
txt-float-word0โ†’โˆ’8pxโ†’0, 2.4s cycle / 200ms phase per word.
txt-pulse-char0.3โ†’1โ†’0.3 opacity, 1.5s cycle / 80ms phase.
txt-pulse-word0.3โ†’1โ†’0.3 opacity, 1.8s cycle / 250ms phase.
txt-glow-textCrossfading 10px/25px ambient shadow layers, 2s cycle.
registry-blur-textRegistry per-grapheme blur/fade, configurable radius, 500ms / 20ms.
character-staggerRegistry per-grapheme rise/0.8 scale/fade, spring 300/18/0.8, 15ms stagger.
text-revealRegistry per-line +100% Y masked reveal, 800ms / 150ms.
word-revealRegistry words rise 15px and scale 0.9โ†’1 with cubic easing, 500ms / 40ms.
scramble-hoverHover/focus scramble; iterative or start/end/center sequential reveal.
media-between-textCaller media expands/fades/scales between two morphing text values.
focus-blurActual pointer/keyboard peer blur with native item activation and spring brackets.

CSS Variables

VariableDefaultDescription
--tx-motion-text-font-sizeSize-dependentInherited motion-text content size.
--tx-motion-text-line-height1.5 (lg: 1.75)Content leading; large has more breathing room without enlarging body text.
--tx-motion-text-media-width70pxInline width derived from mediaWidth.
--tx-motion-text-media-height40pxInline height derived from mediaHeight.

Ink, glow, focus, surfaces and rings use the existing --tx-* theme tokens.

Technologies

  • Fixed upstream Amicro commit 43c29ce9cdd16459e3eab4992381b8d35b38776a; MIT, Copyright (c) 2026 SYED SUBHAN UDDIN.
  • The 45 catalog rows map to src/data/textAnimations.ts and their individual src/components/text/AnimatedText.tsx branches. The four registry sources live in registry/ui/text/. Extra sources are ScrambleHover.tsx, MediaBetweenText.tsx, and both FocusBlur.tsx implementations. Exact ranges are exported in MOTION_TEXT_VARIANTS and shown by the demo.
  • Implementation: motion-text/src/TxMotionText.vue, source trajectories in src/presets.ts, typed API in src/types.ts. Decorative WAAPI resources and the single scramble timeout have an idempotent cancel boundary through useMotionActivity; value changes reuse TxTextMorph, word grouping reuses stream-text/src/segment.ts, and spring easing reuses liquid/src/spring.ts.
  • Typewriter is stepped by whole graphemes rather than cropping half a glyph. Spacing settles to natural body spacing. The two hover catalog IDs that share an upstream switch branch remain separately discoverable without pretending to have different source trajectories.
  • This page documents implementation behavior; integration/build/browser acceptance is performed by the owning workflow, not claimed by this page.
ๆŸฅ็œ‹ๆบ็ 
packages/tuffex/packages/components/src/motion-text/index.ts