171 lines
4.5 KiB
Markdown
171 lines
4.5 KiB
Markdown
|
|
# 心动等级头像组件 (CrushLevelAvatar)
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
`CrushLevelAvatar` 是一个展示用户与AI角色心动等级的头像组件,根据设计稿实现了双头像重叠布局、心动等级徽章显示以及动画效果。
|
|||
|
|
|
|||
|
|
## 功能特性
|
|||
|
|
|
|||
|
|
### 1. 状态处理
|
|||
|
|
- **无等级状态**:只显示AI头像和昵称
|
|||
|
|
- **有等级状态**:显示AI和用户双头像,包含心动等级信息
|
|||
|
|
|
|||
|
|
### 2. 视觉设计
|
|||
|
|
- **双头像布局**:AI头像和用户头像并排显示,带有白色边框和阴影
|
|||
|
|
- **多层背景装饰**:三层渐变圆形背景,从外到内颜色递进
|
|||
|
|
- **心动等级徽章**:居中显示的心形徽章,包含等级数字
|
|||
|
|
- **角色信息展示**:角色名称和心动温度标签
|
|||
|
|
|
|||
|
|
### 3. 动画效果
|
|||
|
|
- **等级变化动画**:心形背景从大到小消失,数字等级渐变切换
|
|||
|
|
- **分层延迟**:三层心形背景依次消失(0ms, 100ms, 200ms延迟)
|
|||
|
|
- **数字切换**:背景完全消失后,等级数字淡出淡入切换到新等级
|
|||
|
|
|
|||
|
|
## 组件属性
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface CrushLevelAvatarProps {
|
|||
|
|
size?: "large" | "small"; // 头像尺寸
|
|||
|
|
showAnimation?: boolean; // 是否显示等级变化动画
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import CrushLevelAvatar from './components/CrushLevelAvatar';
|
|||
|
|
|
|||
|
|
// 基础使用
|
|||
|
|
<CrushLevelAvatar />
|
|||
|
|
|
|||
|
|
// 大尺寸带动画
|
|||
|
|
<CrushLevelAvatar
|
|||
|
|
size="large"
|
|||
|
|
showAnimation={true}
|
|||
|
|
/>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 依赖要求
|
|||
|
|
|
|||
|
|
组件需要在以下上下文中使用:
|
|||
|
|
|
|||
|
|
1. **ChatConfigContext** - 提供AI信息和ID
|
|||
|
|
2. **用户认证** - 获取当前用户信息
|
|||
|
|
3. **IM服务** - 获取心动等级数据
|
|||
|
|
|
|||
|
|
## 数据来源
|
|||
|
|
|
|||
|
|
- `useChatConfig()` - AI信息和聊天配置
|
|||
|
|
- `useCurrentUser()` - 当前用户信息
|
|||
|
|
- `useGetHeartbeatLevel()` - 心动等级数据
|
|||
|
|
- `useHeartLevelTextFromLevel()` - 等级文本转换
|
|||
|
|
|
|||
|
|
## 样式系统
|
|||
|
|
|
|||
|
|
### CSS 动画类
|
|||
|
|
- `.animate-scale-down` - 缩放动画
|
|||
|
|
- `.animate-delay-100/200/300` - 动画延迟
|
|||
|
|
|
|||
|
|
### 颜色设计
|
|||
|
|
- 外层背景:`from-purple-500/20`
|
|||
|
|
- 中层背景:`from-pink-500/30`
|
|||
|
|
- 内层背景:`from-magenta-500/40`
|
|||
|
|
- 心形徽章:`from-pink-400 to-red-500`
|
|||
|
|
|
|||
|
|
## 实现细节
|
|||
|
|
|
|||
|
|
### 背景装饰层
|
|||
|
|
```tsx
|
|||
|
|
{/* 心形背景层 - 使用SVG图标 */}
|
|||
|
|
<div className={cn(
|
|||
|
|
"absolute left-1/2 top-[-63px] -translate-x-1/2 w-60 h-[210px] pointer-events-none",
|
|||
|
|
isLevelChanging && showAnimation && "animate-scale-fade-out"
|
|||
|
|
)}>
|
|||
|
|
<Image
|
|||
|
|
src="/icons/crushlevel_heart.svg"
|
|||
|
|
alt="heart background"
|
|||
|
|
fill
|
|||
|
|
className="object-contain opacity-20"
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 心动等级徽章
|
|||
|
|
```tsx
|
|||
|
|
{/* 心形背景 + 等级数字 */}
|
|||
|
|
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 size-10 z-10">
|
|||
|
|
<Image
|
|||
|
|
src="/icons/crushlevel_heart.svg"
|
|||
|
|
alt="heart"
|
|||
|
|
width={40}
|
|||
|
|
height={40}
|
|||
|
|
/>
|
|||
|
|
<div
|
|||
|
|
className={cn(
|
|||
|
|
"relative z-10 font-bold text-white text-base transition-all duration-300",
|
|||
|
|
isLevelChanging && "animate-level-change"
|
|||
|
|
)}
|
|||
|
|
key={displayLevel}
|
|||
|
|
>
|
|||
|
|
{displayLevel?.replace('LEVEL_', '') || '1'}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 动画触发机制
|
|||
|
|
```tsx
|
|||
|
|
// 监听等级变化触发动画
|
|||
|
|
useEffect(() => {
|
|||
|
|
if (showAnimation && heartbeatLevel && heartbeatLevel !== displayLevel) {
|
|||
|
|
setIsLevelChanging(true);
|
|||
|
|
setAnimationKey(prev => prev + 1);
|
|||
|
|
|
|||
|
|
// 背景消失后更新等级数字
|
|||
|
|
setTimeout(() => {
|
|||
|
|
setDisplayLevel(heartbeatLevel);
|
|||
|
|
setIsLevelChanging(false);
|
|||
|
|
}, 600); // 背景消失动画时长
|
|||
|
|
}
|
|||
|
|
}, [heartbeatLevel, showAnimation, displayLevel]);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### CSS 动画定义
|
|||
|
|
```css
|
|||
|
|
/* 心形背景消失动画 */
|
|||
|
|
@keyframes scale-fade-out {
|
|||
|
|
0% { transform: scale(1); opacity: 1; }
|
|||
|
|
100% { transform: scale(0.3); opacity: 0; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 等级数字变化动画 */
|
|||
|
|
@keyframes level-change {
|
|||
|
|
0% { opacity: 1; transform: scale(1); }
|
|||
|
|
50% { opacity: 0; transform: scale(0.8); }
|
|||
|
|
100% { opacity: 1; transform: scale(1); }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
1. **上下文依赖**:组件必须在正确的 Context 环境中使用
|
|||
|
|
2. **性能考虑**:动画效果会增加渲染开销
|
|||
|
|
3. **响应式设计**:组件在不同屏幕尺寸下的表现
|
|||
|
|
4. **数据安全**:处理用户头像加载失败的情况
|
|||
|
|
5. **图标依赖**:需要确保 `/icons/crushlevel_heart.svg` 文件存在
|
|||
|
|
|
|||
|
|
## 测试
|
|||
|
|
|
|||
|
|
可以通过访问 `/test-crush-level-avatar` 页面查看组件的不同状态和配置效果。
|
|||
|
|
|
|||
|
|
### 调试功能
|
|||
|
|
在浏览器控制台中可以调用以下函数来手动触发动画:
|
|||
|
|
```javascript
|
|||
|
|
window.triggerLevelAnimation(); // 触发等级变化动画
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 更新历史
|
|||
|
|
|
|||
|
|
- 2024-01-XX:初始实现,包含基础功能
|
|||
|
|
- 2024-01-XX:添加动画效果和背景装饰
|
|||
|
|
- 2024-01-XX:优化性能和用户体验
|