PrismGlow 棱镜光
从元素一条边升起、横向流动的光谱光锥
安装
pnpm add @talex-touch/tuffex
import { TxPrismGlow } from '@talex-touch/tuffex/prism-glow'
import '@talex-touch/tuffex/prism-glow/style.css'
import '@talex-touch/tuffex/base.css' // 设计令牌与重置样式,全应用引入一次
用法
卡片
根元素就是卡片:背景与圆角写在根元素上,光画在背景之上、插槽之下。
示例加载中...
变高即收起
宿主变高时,光在约 140ms 内缩回边缘,不走淡出;之后保持关闭,直到 active 关掉再打开。
示例加载中...
覆盖层
不传插槽时铺在宿主内容背后(CoreBox 搜索栏的用法):宿主须是层叠上下文,根元素绝对定位到 z-index: -1。
示例加载中...
最佳实践
- 只在进行中打开:开始时把
active设为true,结束时设回false;不要当常驻装饰。 - 光在固定高度的区域里时,用
growTarget指向会变高的外层容器;宿主加载中本就会变高时,才关掉collapseOnGrow。 - 组件不渲染文字也不播报,旁边要有可见状态文字或
role="status"区域(可 sr-only)。 - 背景写在根元素或宿主上,不写在插槽里,否则光会被盖住。
- 主要文字放在远离光源的一侧;一个视图只放一处。
API 参考
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
active | boolean | true | 开 / 关;打开 0.3s 淡入,关闭 0.45s 淡出后卸载。 |
palette | 'spectrum' | 'accent' | 'spectrum' | spectrum 横跨整个色环;accent 取 --tx-color-primary 的相邻色相。 |
placement | 'bottom' | 'top' | 'bottom' | 光升起的边;两种都从左往右流动。 |
intensity | number | 1 | 光层不透明度,钳制到 0–1,非有限数按 1;不影响插槽。 |
duration | number | 6 | 流速基准(秒),越小越快;不是正的有限数时回退到 6。 |
collapseOnGrow | boolean | true | 被监听元素变高超过 8px 时,光约 140ms 内缩回边缘。 |
growTarget | HTMLElement | null | null | collapseOnGrow 监听的元素;null 为组件根元素。 |
插槽
| 插槽 | 说明 |
|---|---|
default | 渲染在光层之上的内容;不传时组件可作覆盖层。 |
CSS 变量
由属性写入根元素内联样式,改值请用属性:
| 变量 | 来源 | 说明 |
|---|---|---|
--tx-prism-glow-intensity | intensity | 光层不透明度,已钳制到 0–1。 |
--tx-prism-glow-duration | duration | 流速基准,带 s 单位。 |
以下声明在根元素上,亮色、暗色各有一套默认值:
| 变量 | 亮色 | 暗色 | 说明 |
|---|---|---|---|
--tx-prism-glow-l / --tx-prism-glow-c | 0.76 / 0.19 | 0.74 / 0.19 | 光锥颜色的 oklch 亮度与彩度。 |
--tx-prism-glow-l-core / -c-core / -a-core | 0.78 / 0.18 / 0.5 | 0.95 / 0.05 / 0.78 | 贴边核心的亮度、彩度与不透明度。 |
--tx-prism-glow-a-halo | 0.22 | 0.3 | 光晕不透明度。 |
--tx-prism-glow-a-fringe | 0.3 | 0.44 | 两侧色散晕边的不透明度。 |
--tx-prism-glow-a-ray | 0.05 | 0.07 | 竖向光柱的不透明度。 |
--tx-prism-glow-blend | normal | plus-lighter | 光锥之间的混合模式。 |
--tx-prism-glow-reach | 1 | 1 | 光锥高度系数;高对比模式为 0.45,收起时的离场光层为 0。 |
- 覆盖时选择器要比组件的主题块更具体(亮色
.tx-prism-glow,暗色:is([data-theme='dark'], .dark) .tx-prism-glow),并给暗色单独写一份。 --tx-pg-*是内部变量,不属于 API。
概述
- 根元素
div.tx-prism-glow带tx-prism-glow--{palette}、tx-prism-glow--{placement}修饰类(收起时另带is-collapsing),isolation: isolate自成层叠上下文;它的position: relative写在:where()里,特异性为零。 - 光层
.tx-prism-glow__field是absolute; inset: 0; z-index: -1:画在根元素背景之上、插槽之下,按根元素圆角裁切,带aria-hidden="true"且不接收指针事件。 - 光亮着或正在淡出时,被监听元素比亮起以来的最低高度高出 8px 以上即收起,离场光层固定在变高前的高度;变矮和 8px 以内的变化不触发,收起后直到
active重新打开才恢复。 - 暗色看祖先:带
[data-theme='dark']或.dark时用暗色参数(近白核心、plus-lighter叠加),否则用亮色参数;没有主题属性。 - 减少动态效果时,动画与过渡全部停止,六束光锥停在从左到右铺满的静态画面,光层随
active立即出现或消失。 - 高对比模式(
html.contrast、html[data-tx-contrast='high'],或prefers-contrast: more且无html[data-tx-contrast='normal'])下,光锥收成贴边的一条带,光柱隐藏。
技术实现
- 只动合成器属性(
translate、scale、opacity),keyframes 不读var(),没有 JS 帧循环,主线程繁忙时照样流畅。 - 观感参考 George Hastings(@soulegit)2026-09-23 发布的 Unicorn Studio「New AI canvas loading state」视频,只借鉴观感,没有代码来源。
- 源码:
packages/tuffex/packages/components/src/prism-glow/,光锥参数在cones.ts。
查看源码
packages/tuffex/packages/components/src/prism-glow/index.ts
使用场景
- 卡片、输入框、搜索栏或消息输入框的加载 / 工作中状态。
- 较长的 AI 生成(画布、图片、长回答)的等待期。
- CoreBox 搜索栏的「搜索中」状态。
相关组件
- BorderBeam 流光边框:沿边框游走或呼吸的光束;画的是边框,不是从边缘升起的光锥。
- ThinkingOrb 思考指示球:自带
label的独立指示球;要让已有的卡片或输入框本身亮起来,用棱镜光。 - GlowText 扫光:在文字或卡片上扫过一道高光。