Files
vf_react/src/components/FUI/CardGlow.tsx
zdl 958222e75f refactor(StockQuoteCard): 组件拆分与 FUI 光效统一
- 新增 CardGlow 组件到 @components/FUI,支持多种颜色主题 (gold/cyan/purple)
- 拆分 StockQuoteCard 子组件:GlassSection、LoadingSkeleton
- 更新 KeyMetrics、MainForceInfo、SecondaryQuote 使用 DEEP_SPACE_THEME
- 主组件从 540 行精简到 321 行(减少 40%)
- 删除重复的 GlowDecorations,统一使用 FUI/CardGlow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-19 11:29:28 +08:00

141 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* CardGlow - 卡片级装饰光效组件
*
* 为卡片提供 FUI 风格的装饰元素:
* - 顶部光条Ash Thorp 风格)
* - 角落发光效果James Turrell 风格)
* - 可选背景网格
*
* 与 AmbientGlow 的区别:
* - AmbientGlow: 页面级环境光position: fixed
* - CardGlow: 卡片级装饰光,相对于父容器定位
*
* @example
* ```tsx
* <Box position="relative" overflow="hidden">
* <CardGlow variant="gold" />
* {children}
* </Box>
* ```
*/
import React, { memo } from 'react';
import { Box } from '@chakra-ui/react';
export interface CardGlowProps {
/** 预设主题 */
variant?: 'gold' | 'cyan' | 'purple' | 'default';
/** 是否显示背景网格 */
showGrid?: boolean;
/** 自定义主色(覆盖 variant */
primaryColor?: string;
/** 自定义次色(覆盖 variant */
secondaryColor?: string;
}
// 预设颜色配置
const COLOR_PRESETS = {
gold: {
primary: 'rgba(212, 175, 55, 1)',
secondary: 'rgba(0, 212, 255, 0.1)',
grid: 'rgba(212, 175, 55, 0.03)',
},
cyan: {
primary: 'rgba(0, 212, 255, 1)',
secondary: 'rgba(212, 175, 55, 0.1)',
grid: 'rgba(0, 212, 255, 0.03)',
},
purple: {
primary: 'rgba(168, 85, 247, 1)',
secondary: 'rgba(0, 212, 255, 0.1)',
grid: 'rgba(168, 85, 247, 0.03)',
},
default: {
primary: 'rgba(255, 255, 255, 0.6)',
secondary: 'rgba(255, 255, 255, 0.1)',
grid: 'rgba(255, 255, 255, 0.02)',
},
};
/**
* 卡片装饰光效组件
*
* 纯展示组件,需要父容器设置 position: relative 和 overflow: hidden
*/
const CardGlow = memo<CardGlowProps>(({
variant = 'gold',
showGrid = true,
primaryColor,
secondaryColor,
}) => {
const preset = COLOR_PRESETS[variant];
const primary = primaryColor || preset.primary;
const secondary = secondaryColor || preset.secondary;
const gridColor = preset.grid;
return (
<>
{/* 顶部光条 - Ash Thorp 风格数据终端效果 */}
<Box
position="absolute"
top={0}
left="50%"
transform="translateX(-50%)"
width="60%"
height="1px"
background={`linear-gradient(90deg, transparent, ${primary}, transparent)`}
opacity={0.6}
pointerEvents="none"
/>
{/* 左上角光晕 - James Turrell 风格光影效果 */}
<Box
position="absolute"
top="-40px"
left="-40px"
width="80px"
height="80px"
borderRadius="50%"
background={`radial-gradient(circle, ${primary.replace('1)', '0.15)')} 0%, transparent 70%)`}
filter="blur(20px)"
pointerEvents="none"
/>
{/* 右下角光晕 - 补充色,增加层次感 */}
<Box
position="absolute"
bottom="-40px"
right="-40px"
width="80px"
height="80px"
borderRadius="50%"
background={`radial-gradient(circle, ${secondary} 0%, transparent 70%)`}
filter="blur(20px)"
pointerEvents="none"
/>
{/* 背景网格 - 微妙的科技感纹理 */}
{showGrid && (
<Box
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
backgroundImage={`
linear-gradient(${gridColor} 1px, transparent 1px),
linear-gradient(90deg, ${gridColor} 1px, transparent 1px)
`}
backgroundSize="40px 40px"
pointerEvents="none"
opacity={0.5}
/>
)}
</>
);
});
CardGlow.displayName = 'CardGlow';
export default CardGlow;