| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import React, { useEffect, useState } from 'react';
- import type { EmotionType, AnimationState } from '@/types';
- interface AnimatedCharacterProps {
- emotion: EmotionType;
- state: AnimationState;
- }
- // Emoji配置映射
- interface EmojiConfig {
- emoji: string;
- description: string;
- speech: string;
- }
- const EMOJI_MAP: Record<string, EmojiConfig> = {
- // 基础状态
- idle: {
- emoji: '😐',
- description: '待机中',
- speech: '您好!我是您的语音助手,请问有什么可以帮您?',
- },
- listening: {
- emoji: '👂',
- description: '正在倾听',
- speech: '正在聆听您的指令...',
- },
- thinking: {
- emoji: '🤔',
- description: '正在思考',
- speech: '让我思考一下...',
- },
- error: {
- emoji: '😵',
- description: '出错了',
- speech: '抱歉,出现了一些问题',
- },
- // 情感 - 说话状态
- speaking_neutral: {
- emoji: '😐',
- description: '平静回应',
- speech: '根据您的要求...',
- },
- speaking_happy: {
- emoji: '😊',
- description: '开心回应',
- speech: '太好了!',
- },
- speaking_sad: {
- emoji: '😢',
- description: '难过回应',
- speech: '听到这个我也很难过',
- },
- speaking_excited: {
- emoji: '😄',
- description: '兴奋回应',
- speech: '太棒了!',
- },
- speaking_angry: {
- emoji: '😠',
- description: '生气回应',
- speech: '这确实让人生气',
- },
- speaking_surprised: {
- emoji: '😲',
- description: '惊讶回应',
- speech: '哇!真没想到',
- },
- speaking_thoughtful: {
- emoji: '🤔',
- description: '深思回应',
- speech: '这是个值得深思的问题',
- },
- speaking_encouraging: {
- emoji: '💪',
- description: '鼓励回应',
- speech: '加油!你可以的',
- },
- speaking_confused: {
- emoji: '😕',
- description: '困惑回应',
- speech: '抱歉,我不太明白您的意思',
- },
- speaking_worried: {
- emoji: '😟',
- description: '担忧回应',
- speech: '这确实需要注意',
- },
- speaking_satisfied: {
- emoji: '😌',
- description: '满意回应',
- speech: '操作成功完成!',
- },
- speaking_friendly: {
- emoji: '😄',
- description: '友好回应',
- speech: '很高兴为您服务!',
- },
- speaking_sorry: {
- emoji: '😔',
- description: '抱歉回应',
- speech: '对不起,我无法完成这个请求',
- },
- };
- /**
- * 动画IP组件 - Emoji版本
- * 根据状态和情感显示对应的Emoji表情
- */
- export const AnimatedCharacter: React.FC<AnimatedCharacterProps> = ({ emotion, state }) => {
- const [currentEmoji, setCurrentEmoji] = useState('😐');
- const [statusText, setStatusText] = useState('待机中');
- const [speechText, setSpeechText] = useState('您好!我是您的语音助手');
- const [isAnimating, setIsAnimating] = useState(false);
- useEffect(() => {
- // 根据状态和情感获取对应的emoji配置
- let key = state;
- if (state === 'speaking') {
- key = `speaking_${emotion}`;
- }
- const config = EMOJI_MAP[key] || EMOJI_MAP.idle;
- // 添加切换动画效果
- setIsAnimating(true);
- setTimeout(() => {
- setCurrentEmoji(config.emoji);
- setStatusText(config.description);
- setSpeechText(config.speech);
- setIsAnimating(false);
- }, 150);
- }, [emotion, state]);
- return (
- <div className="animated-character" style={{
- position: 'relative',
- width: '100%',
- height: '100%',
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- }}>
- {/* 状态指示器 */}
- <div style={{
- position: 'absolute',
- top: '-30px',
- padding: '8px 16px',
- backgroundColor: 'rgba(255, 255, 255, 0.2)',
- borderRadius: '20px',
- fontSize: '0.9rem',
- color: 'white',
- zIndex: 10,
- }}>
- {statusText}
- </div>
- {/* Emoji角色容器 */}
- <div style={{
- width: '200px',
- height: '200px',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- marginBottom: '40px',
- position: 'relative',
- zIndex: 5,
- }}>
- <div
- className="emoji-character"
- style={{
- fontSize: '100px',
- transition: 'all 0.3s ease',
- transform: isAnimating ? 'scale(0.8)' : 'scale(1)',
- filter: 'drop-shadow(0 4px 8px rgba(0, 0, 0, 0.2))',
- }}
- >
- {currentEmoji}
- </div>
- </div>
- {/* 对话气泡 */}
- <div style={{
- position: 'relative',
- background: 'rgba(255, 255, 255, 0.9)',
- borderRadius: '15px',
- padding: '15px 20px',
- color: '#333',
- maxWidth: '80%',
- boxShadow: '0 4px 10px rgba(0, 0, 0, 0.1)',
- textAlign: 'center',
- fontSize: '14px',
- lineHeight: '1.5',
- zIndex: 10,
- }}>
- <div style={{
- position: 'absolute',
- bottom: '100%',
- left: '50%',
- marginLeft: '-10px',
- width: 0,
- height: 0,
- borderLeft: '10px solid transparent',
- borderRight: '10px solid transparent',
- borderBottom: '10px solid rgba(255, 255, 255, 0.9)',
- }} />
- {speechText}
- </div>
- </div>
- );
- };
|