组件/MotionText

MotionText

45 个可追溯文字效果、4 个 registry 揭示,以及乱序揭示、调用方行内媒体和真实焦点模糊交互。

自 0.6.3BETA

当前组件文档正在开发中

该页面正在持续迁移,示例与 API 可能会继续调整。

概述

TxMotionText 保留 Amicro 的 45 个原始目录 ID 与 7 个独立的 registry / 源码扩展。各变体分别保留自己的方向、分段、错峰、缩放、模糊、遮罩、3D 变换或持续节奏。MOTION_TEXT_VARIANTS 提供真实类型化的名称、分组、分段方式和固定来源;MOTION_TEXT_VARIANT_IDS 是完整 ID 清单。

入场与装饰播放和值变化分开处理。始终挂载的 TxTextMorph 负责所有文字值更新,没有第二套 diff 引擎,回放也不重新挂载它。屏幕阅读器只读取一次原文。同一时刻只有一个文字层可选中:一般播放时选中装饰原文,乱序揭示时选中未改动的原文,静止时选中 TextMorph 层。空白、换行、emoji ZWJ 序列及组合字符均保留。

用法

全量来源变体

在真实目录中选择全部 52 个 ID,按分组、名称或 ID 筛选,使用“下一个效果”遍历,编辑多语言原文,并反复回放。悬停变体响应独立字素 / 词,也支持键盘聚焦。“暂停”会恢复完整可读文字,包括打字和乱序揭示进行到一半时。

示例加载中...

源码交互能力

乱序揭示是实际悬停 / 聚焦触发的字素替换,不是静态标题。它可从开头、末尾或中心按完整字素揭示,并使用原文字符池或调用方 characters。空白不参与乱序。focus-blur 接收调用方条目:有 href 的条目仍为原生链接,没有 href 的条目为发出 select 的按钮。悬停或聚焦项保持清晰,其它项变模糊;焦点括号复用共享 spring。

<TxMotionText
  text="保留 👩🏽‍💻 和 é"
  variant="scramble-hover"
  sequential
  reveal-direction="center"
  :use-original-chars-only="false"
  characters="ABC123✦"
/>
<TxMotionText
  variant="focus-blur"
  :items="[
    { id: 'design', label: '设计', href: '/design' },
    { id: 'motion', label: '动效' },
  ]"
  @select="item => selectedId = item.id"
/>

行内媒体使用调用方 mediaSrc、图片 / 视频属性或 media 插槽。默认悬停触发时,指针和键盘焦点都离开后收起媒体。trigger="manual" 通过暴露的 animate() / reset() 控制;trigger="in-view" 在可见时展开。减少动态效果模式下,媒体立即显示,不执行宽度 / 缩放动画。内置或插槽视频在失活或媒体收起时暂停;插槽收到 active 和 open,用于自己管理资源生命周期。

<TxMotionText
  variant="media-between-text"
  first-text="创造"
  second-text="体验"
  :media-src="imageUrl"
  media-alt="抽象纹理"
/>
<TxMotionText variant="media-between-text" first-text="你的" second-text="媒体">
  <template #media="{ active, open }">
    <img :src="imageUrl" alt="调用方插图">
  </template>
</TxMotionText>

最佳实践

  • 文字、媒体和条目由调用方持有;组件不内嵌演示业务数据。
  • 替换文字时保持组件挂载。装饰回放使用 replayKey 或 replay(),不要按文字值给组件设置 key。
  • 中文词分段使用有效的 locale。字素效果不拆开家庭 emoji 或组合字符;没有 Intl.Segmenter 时,装饰字素播放把整段原文保留为一个安全单元。
  • 悬停效果属于装饰,不冒充操作按钮。导航 / 操作使用原生 focus-blur 条目或独立语义控件。
  • paused 停止所有自有动画、乱序超时和视频播放。持续效果仅在挂载、处于交叉可见区域、文档可见、启用且非减少动态效果时运行,KeepAlive 失活同样停止。
  • Morph 引擎不做软换行。可传入显式换行(text-reveal 逐行揭示),长正文则使用支持换行的文字组件。
  • 字距变体最终回到自然正文间距。光晕交叉淡化两层静态阴影;悬停颜色立即变化,不做颜色补间。

API 参考

属性

属性类型默认值说明
textstring''目录、registry 和乱序效果的原文。
variantMotionTextVariant'txt-dia'下方 52 个 ID 之一。
size'xs' | 'sm' | 'md' | 'lg''md'由 token 控制的内容字号。
tag'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3''span'根语义元素。
localestring'en'词 / 字素分段及 TextMorph 的 locale。
pausedbooleanfalse取消动态效果,显示完整可读原文。
trigger'in-view' | 'hover' | 'manual'按来源入场 / 持续效果默认 in-view;乱序 / 媒体默认 hover。字素 / 词悬停和焦点条目保留原生交互。
replayKeystring | number—改变时回放,不重新挂载 TextMorph。
durationMsnumber按来源定时效果时长(毫秒);物理 spring 使用自己的稳定时长。
staggerMsnumber按来源覆盖来源中各单元的延迟(毫秒)。
transitionTransition按来源共享 'snappy' | 'smooth' | 'bouncy'、{ stiffness?, damping?, mass? } 或 { duration, ease? },覆盖来源节奏。
initialBlurnumber8Registry blur-text 初始模糊半径(像素)。
yOffsetnumber15Registry character-stagger 初始竖向偏移。
scrambleSpeednumber40乱序帧之间的毫秒数。
maxIterationsnumber10非顺序乱序的迭代次数。
sequentialbooleanfalse每帧逐步揭示更多完整字素。
revealDirection'start' | 'end' | 'center''start'顺序乱序的揭示方向。
useOriginalCharsOnlybooleantrue替换字符从原文非空白字素中选择。
charactersstring拉丁字母、数字与符号original-only 为 false 时的自定义替换字符池。
firstTextstring''行内媒体前的文字。
secondTextstring''行内媒体后的文字。
mediaSrcstring—调用方图片 / 视频 URL,不制造假兜底。
mediaType'image' | 'video''image'内置媒体渲染类型。
mediaAltstring''图片替代文字 / 视频无障碍名称。
mediaPosterstring''调用方视频封面。
mediaWidthnumber70展开后的行内媒体宽度(像素)。
mediaHeightnumber40行内媒体高度(像素)。
mediaAutoplaybooleantrue仅在 active 且展开时请求播放;浏览器自动播放策略可拒绝。
mediaLoopbooleantrue内置视频仅在 active 时循环。
mediaMutedbooleantrue内置视频的静音状态。
mediaPlaysinlinebooleantrue内置视频的行内播放属性。
itemsreadonly MotionTextItem[][]焦点条目 { id, label, href? }。稳定 ID 保留已挂载的标签引擎。
blurAmountnumber4非当前焦点条目的模糊半径(像素)。
opacityAmountnumber0.4非当前焦点条目的透明度。
showBracketsbooleantrue共享 spring 焦点括号。

事件

事件参数说明
animation-startMotionTextVariant装饰播放或文字值 morph 开始。
animation-completeMotionTextVariant有限播放 / morph 结束,持续循环不会周期性播报完成。
animation-cancelMotionTextVariant正在运行的有限播放 / morph 被打断。
selectMotionTextItem激活焦点条目;原生链接保留其导航行为。
media-errorEvent调用方图片 / 视频报告真实加载错误。

插槽

插槽作用域说明
media{ open: boolean, active: boolean }替换内置图片 / 视频,保留 hover / manual / in-view 几何与活动状态控制。

暴露方法

方法说明
replay()取消上次装饰播放后回放;行内媒体执行展开。
animate()相同的显式播放 / 展开操作,保留上游 ref 触发契约。
reset()取消工作,恢复原文并收起媒体;清除焦点条目装饰。

MotionTextProps、MotionTextItem、MotionTextVariant、MotionTextVariantInfo、MotionTextTrigger、MotionTextRevealDirection、MotionTextMediaSlotProps、MotionTextSlots、MotionTextExpose 和 TxMotionTextInstance 均由 @talex-touch/tuffex/motion-text 导出。

变体目录

原始 ID保留的效果
txt-dia多边形遮罩揭示与 8px 模糊,850ms。
txt-blur整段 12px 模糊、0.9→1 缩放与淡入,700ms。
txt-shimmer静态文字渐变与 2s 透明度微光。
txt-typewriter1.2s 内逐完整字素显示,光标移动并闪烁。
txt-reveal水平 inset 遮罩揭示,750ms。
txt-fade-char字素淡入,300ms / 50ms 错峰。
txt-fade-word词淡入,400ms / 150ms 错峰。
txt-fade-text整段淡入,800ms。
txt-blurup-word词从 15px 和 8px 模糊上升,500ms / 120ms。
txt-blurup-char字素从 15px 和 8px 模糊上升,400ms / 40ms。
txt-stagger词以 expo 曲线上升 20px,500ms / 100ms。
txt-slideup-char字素从 +100% Y 滑入遮罩,400ms / 40ms。
txt-slideup-word词从 +100% Y 滑入遮罩,500ms / 100ms。
txt-slideup-text整段从 +100% Y 滑入遮罩,600ms。
txt-slidedown-char字素从 −100% Y 滑入遮罩,400ms / 40ms。
txt-slidedown-word词从 −100% Y 滑入遮罩,500ms / 100ms。
txt-slideleft-char字素从 +40px X 滑入并淡入,400ms / 40ms。
txt-slideright-char字素从 −40px X 滑入并淡入,400ms / 40ms。
txt-dropin-char字素从 50px 上方下落,spring 500/25,40ms 错峰。
txt-riseup-word词上升 30px、0.8→1 缩放,spring 400/22,120ms 错峰。
txt-bouncein-char字素 0→1.3→1 缩放与淡入,500ms / 50ms。
txt-scalein-char字素 0→1 缩放,spring 450/22,40ms 错峰。
txt-scalein-word词 0.4→1 缩放与淡入,400ms / 120ms。
txt-scalein-text整段 0.5→1 缩放与淡入,spring 400/25。
txt-zoomin-text整段 0.2→1 缩放与淡入,600ms。
txt-zoomout-text整段 1.8→1 缩放与淡入,600ms。
txt-flipy-char字素 Y 轴 90°→0° 翻转,500ms / 50ms。
txt-flipx-char字素 X 轴 90°→0° 翻转,500ms / 50ms。
txt-rotatein-char字素 −45°→0° 与 0.5→1 缩放 / 淡入,400ms / 40ms。
txt-swing-word词绕顶部 X 轴 −90°→0°,spring 350/18,120ms 错峰。
txt-stretchx-char字素 X 缩放 2.5→1 与淡入,400ms / 40ms。
txt-stretchy-char字素 Y 缩放 2.5→1 与淡入,400ms / 40ms。
txt-skewx-char字素 X 倾斜 −30°→0° 与淡入,400ms / 40ms。
txt-trackingin-text0.6em 宽间距收拢到自然间距,700ms。
txt-trackingout-text−0.2em 紧间距展开到自然间距,700ms。
txt-spring-text字素悬停上升 −8px、缩放 1.2,spring 500/15。
txt-hoverlift-char来源中相同的字素悬停上升 / 缩放轨迹。
txt-hoverlift-word词悬停上升 −6px,spring 400/18。
txt-hoverscale-char字素悬停缩放 1.4,spring 500/18。
txt-hoverscale-word词悬停缩放 1.25,spring 400/20。
txt-float-char0→−6px→0,2s 周期 / 每字素 100ms 相位。
txt-float-word0→−8px→0,2.4s 周期 / 每词 200ms 相位。
txt-pulse-char0.3→1→0.3 透明度,1.5s 周期 / 80ms 相位。
txt-pulse-word0.3→1→0.3 透明度,1.8s 周期 / 250ms 相位。
txt-glow-text10px / 25px 静态环境阴影交叉淡化,2s 周期。
registry-blur-textRegistry 逐字素模糊 / 淡入,可配置半径,500ms / 20ms。
character-staggerRegistry 字素升起、0.8 缩放与淡入,spring 300/18/0.8,15ms 错峰。
text-revealRegistry 逐行 +100% Y 遮罩揭示,800ms / 150ms。
word-revealRegistry 词上升 15px、0.9→1 缩放与 cubic 曲线,500ms / 40ms。
scramble-hover悬停 / 聚焦乱序;迭代或开头 / 末尾 / 中心顺序揭示。
media-between-text调用方媒体在两段 morph 文字之间展开、淡入并缩放。
focus-blur真实指针 / 键盘同级模糊,原生条目激活与 spring 括号。

CSS 变量

变量默认值说明
--tx-motion-text-font-size按尺寸MotionText 继承的内容字号。
--tx-motion-text-line-height1.5(lg:1.75)内容行高;大尺寸增加呼吸感,不放大正文字号。
--tx-motion-text-media-width70px从 mediaWidth 派生的行内宽度。
--tx-motion-text-media-height40px从 mediaHeight 派生的行内高度。

文字、光晕、焦点、表面及描边均使用现有 --tx-* 主题 token。

技术实现

  • 固定上游 Amicro 提交 43c29ce9cdd16459e3eab4992381b8d35b38776a;MIT,Copyright (c) 2026 SYED SUBHAN UDDIN。
  • 45 个目录条目对应 src/data/textAnimations.ts 与 src/components/text/AnimatedText.tsx 的独立分支。4 个 registry 来源位于 registry/ui/text/。额外来源为 ScrambleHover.tsx、MediaBetweenText.tsx 和两份 FocusBlur.tsx 实现。准确范围由 MOTION_TEXT_VARIANTS 导出并在演示中显示。
  • 实现:motion-text/src/TxMotionText.vue;来源轨迹位于 src/presets.ts,类型 API 位于 src/types.ts。装饰 WAAPI 资源和唯一乱序超时通过 useMotionActivity 的幂等取消边界管理;值变化复用 TxTextMorph,词分段复用 stream-text/src/segment.ts,spring 曲线复用 liquid/src/spring.ts。
  • 打字按完整字素步进,不裁切半个字符。字距最终回到自然正文间距。两个共用上游 switch 分支的悬停目录 ID 仍可分别发现,但不虚构来源中不存在的不同轨迹。
  • 本页描述实现行为;集成、构建和真实浏览器验收由所属工作流统一执行,不在本页声称已通过。
查看源码
packages/tuffex/packages/components/src/motion-text/index.ts