组件
渐进模糊 Progressive Blur
使用多层渐变遮罩构建方向可控的渐进式背景模糊。
基础示例
Loading…
pnpm dlx wui@latest add @wui/progressive-blur"use client"
import * as React from "react"
import { motion, type HTMLMotionProps } from "motion/react"
import { cn } from "@/lib/utils"
const gradientAngles = {
top: 0,
right: 90,
bottom: 180,
left: 270,
} as const
export interface ProgressiveBlurProps extends HTMLMotionProps<"div"> {
/** Edge that receives the strongest blur. @default "bottom" */
direction?: keyof typeof gradientAngles
/** Number of overlapping mask bands. Values below 2 are clamped. @default 8 */
blurLayers?: number
/** Blur added by each successive layer in pixels. @default 0.25 */
blurIntensity?: number
}
function ProgressiveBlur({
direction = "bottom",
blurLayers = 8,
blurIntensity = 0.25,
className,
...props
}: ProgressiveBlurProps) {
const layers = Math.max(Math.round(blurLayers), 2)
const segmentSize = 1 / (layers + 1)
const angle = gradientAngles[direction]
return (
<div
aria-hidden="true"
data-slot="progressive-blur"
className={cn("pointer-events-none relative", className)}
>
{Array.from({ length: layers }, (_, index) => {
const stops = [index, index + 1, index + 2, index + 3].map(
(position, stopIndex) =>
`rgba(0, 0, 0, ${stopIndex === 1 || stopIndex === 2 ? 1 : 0}) ${position * segmentSize * 100}%`
)
const maskImage = `linear-gradient(${angle}deg, ${stops.join(", ")})`
const blur = Math.max(0, index * blurIntensity)
return (
<motion.div
key={index}
data-slot="progressive-blur-layer"
className="absolute inset-0 rounded-[inherit]"
style={{
maskImage,
WebkitMaskImage: maskImage,
backdropFilter: `blur(${blur}px)`,
WebkitBackdropFilter: `blur(${blur}px)`,
}}
{...props}
/>
)
})}
</div>
)
}
export { ProgressiveBlur, gradientAngles }
组件作用
ProgressiveBlur 将多个带渐变 mask 的 backdrop-filter 图层叠加起来,使模糊强度沿某个方向逐步增加。它适合滚动容器边缘、图片文字交界处和固定操作栏后方,用来建立内容层级而不是遮盖信息。
组件仅负责视觉效果,默认忽略指针事件并从无障碍树隐藏。父容器通常需要 position: relative 与明确尺寸。
组件属性
| Prop | Type | Default | Description |
|---|---|---|---|
| direction | "top" | "right" | "bottom" | "left" | bottom | Edge that receives the strongest blur. |
| blurLayers | number | 8 | Number of overlapping mask bands. Values below 2 are clamped. |
| blurIntensity | number | 0.25 | Blur added by each successive layer in pixels. |
事件
组件透传 Motion div 的动画与原生指针事件属性。由于它默认用于纯装饰层,一般不应在模糊图层本身绑定交互。
扩展使用
使用 direction 将最强模糊放在 top、right、bottom 或 left。增加 blurLayers 会让过渡更细腻但也提高渲染成本;优先从 6–10 层和较低的 blurIntensity 开始调整。