组件
文本波光 Text Shimmer Wave
逐字符传播的立体位移与高光波浪。
基础示例
Loading…
pnpm dlx wui@latest add @wui/text-shimmer-wave"use client"
import * as React from "react"
import { motion, useReducedMotion, type Transition } from "motion/react"
import { cn } from "@/lib/utils"
export interface TextShimmerWaveProps extends React.ComponentProps<"span"> {
/** Text animated as a traveling character wave. */
children: string
/** HTML element rendered by the component. @default "span" */
as?: React.ElementType
/** Seconds for one full wave. @default 1.5 */
duration?: number
/** Z-axis travel in pixels. @default 10 */
zDistance?: number
/** Horizontal travel in pixels. @default 2 */
xDistance?: number
/** Vertical travel in pixels. @default -2 */
yDistance?: number
/** Distance between character wave phases. @default 1 */
spread?: number
/** Peak character scale. @default 1.1 */
scaleDistance?: number
/** Peak Y-axis rotation in degrees. @default 10 */
rotateYDistance?: number
/** Motion transition merged into every character. */
transition?: Transition
}
/** Sends a shimmer-like 3D wave through text, one character at a time. */
function TextShimmerWave({
children,
as = "span",
duration = 1.5,
zDistance = 10,
xDistance = 2,
yDistance = -2,
spread = 1,
scaleDistance = 1.1,
rotateYDistance = 10,
transition,
className,
...props
}: TextShimmerWaveProps) {
const Component = as
const reduceMotion = useReducedMotion()
return (
<Component
aria-label={children}
data-slot="text-shimmer-wave"
className={cn("inline-flex [perspective:400px]", className)}
{...props}
>
{Array.from(children).map((character, index) => (
<motion.span
aria-hidden="true"
data-slot="text-shimmer-wave-character"
className="text-muted-foreground inline-block whitespace-pre"
key={`${character}-${index}`}
animate={
reduceMotion
? undefined
: {
color: [
"var(--muted-foreground)",
"var(--foreground)",
"var(--muted-foreground)",
],
x: [0, xDistance, 0],
y: [0, yDistance, 0],
z: [0, zDistance, 0],
scale: [1, scaleDistance, 1],
rotateY: [0, rotateYDistance, 0],
}
}
transition={{
duration,
ease: "easeInOut",
repeat: Infinity,
delay: (index * duration * 0.08) / Math.max(spread, 0.1),
...transition,
}}
>
{character === " " ? "\u00a0" : character}
</motion.span>
))}
</Component>
)
}
export { TextShimmerWave }
组件作用
TextShimmerWave 把颜色、位移、缩放与轻微旋转组合成逐字符波浪。它比普通扫光更醒目,适合短暂生成状态或单一展示焦点。
组件属性
| Prop | Type | Default | Description |
|---|---|---|---|
| children * | string | — | Text animated as a traveling character wave. |
| as | ElementType<any, keyof IntrinsicElements> | span | HTML element rendered by the component. |
| duration | number | 1.5 | Seconds for one full wave. |
| zDistance | number | 10 | Z-axis travel in pixels. |
| xDistance | number | 2 | Horizontal travel in pixels. |
| yDistance | number | -2 | Vertical travel in pixels. |
| spread | number | 1 | Distance between character wave phases. |
| scaleDistance | number | 1.1 | Peak character scale. |
| rotateYDistance | number | 10 | Peak Y-axis rotation in degrees. |
| transition | Transition | — | Motion transition merged into every character. |
事件
组件没有自有事件,底层元素事件继续透传。减少动态效果时只显示静态文字。
扩展使用
xDistance、yDistance、zDistance 控制空间位移,scaleDistance 和 rotateYDistance 控制形变。使用自定义 transition 时仍建议保留循环,确保波浪持续传播。