Files
wecom_it_smart_desk/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-工具栏统一设计v0.7-头像终极版.html
T

523 lines
26 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>坐席头像 v0.7 - C 方向终极版(我的 SVG 极限)</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
background: linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #4c1d95 100%);
color: #f9fafb;
padding: 32px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
min-height: 100vh;
}
h1 { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 8px; color: #ffffff; }
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 40px 0 12px; color: #ffffff; }
h3 { font-size: 14px; font-weight: 600; margin: 16px 0 8px; color: #e0e7ff; }
.meta { color: #a5b4fc; font-size: 12.5px; margin-bottom: 24px; }
.demo-block {
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 18px;
padding: 32px;
margin-bottom: 20px;
}
.demo-label { font-size: 11.5px; color: #c7d2fe; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 14px; font-weight: 500; }
/* 4 个不同尺寸/状态并排展示 */
.avatar-showcase {
display: flex;
align-items: flex-end;
justify-content: space-around;
gap: 20px;
padding: 32px;
background: linear-gradient(135deg, #1e1b4b 0%, #312e81 100%);
border-radius: 14px;
margin: 16px 0;
}
.avatar-cell {
text-align: center;
}
.avatar-cell .label { font-size: 10.5px; color: #a5b4fc; margin-top: 8px; }
.avatar-cell svg { display: block; margin: 0 auto; }
/* 4 工具按钮整体(头部对比) */
.toolbar-preview {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(28px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 18px;
padding: 8px 12px;
display: inline-flex;
gap: 4px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}
.tool-btn {
width: 38px;
height: 38px;
border: 1px solid rgba(255, 255, 255, 0.25);
background: rgba(255, 255, 255, 0.1);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
/* 6 态切换 */
.state-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid rgba(255, 255, 255, 0.12); }
.state-tab {
padding: 6px 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
background: rgba(255, 255, 255, 0.08);
border-radius: 8px;
cursor: pointer;
font-size: 12.5px;
color: #c7d2fe;
transition: all 0.15s;
font-family: inherit;
}
.state-tab:hover { background: rgba(255, 255, 255, 0.15); }
.state-tab.active { background: linear-gradient(135deg, #6366f1, #8b5cf6); color: #fff; border-color: transparent; }
.stage-bg {
background: linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #4c1d95 100%);
border-radius: 14px;
padding: 48px 32px;
min-height: 180px;
display: flex;
align-items: center;
justify-content: center;
}
.state-desc { color: #c7d2fe; font-size: 12.5px; line-height: 1.7; background: rgba(255, 255, 255, 0.05); padding: 12px 14px; border-radius: 10px; border-left: 2px solid #6366f1; margin-top: 12px; }
/* 实施建议表格 */
.breakthrough-table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12.5px; }
.breakthrough-table th, .breakthrough-table td { border: 1px solid rgba(255, 255, 255, 0.15); padding: 10px; text-align: left; color: #e0e7ff; }
.breakthrough-table th { background: rgba(255, 255, 255, 0.08); font-weight: 600; }
.warning {
background: rgba(251, 191, 36, 0.1);
border: 1px solid rgba(251, 191, 36, 0.3);
border-left: 3px solid #fbbf24;
padding: 14px 18px;
border-radius: 8px;
color: #fde68a;
margin: 16px 0;
font-size: 13px;
line-height: 1.7;
}
.warning strong { color: #fbbf24; }
</style>
</head>
<body>
<svg width="0" height="0" style="position: absolute;">
<defs>
<!-- 终极版头像渐变(更多颜色 + 更精细) -->
<radialGradient id="bg-cosmic" cx="30%" cy="20%" r="100%">
<stop offset="0%" stop-color="#1e1b4b"/>
<stop offset="40%" stop-color="#312e81"/>
<stop offset="80%" stop-color="#1e1b4b"/>
<stop offset="100%" stop-color="#0f172a"/>
</radialGradient>
<radialGradient id="skin-3d" cx="40%" cy="30%" r="80%">
<stop offset="0%" stop-color="#fef3c7"/>
<stop offset="50%" stop-color="#fde68a"/>
<stop offset="100%" stop-color="#f59e0b"/>
</radialGradient>
<radialGradient id="hair-3d" cx="50%" cy="20%" r="100%">
<stop offset="0%" stop-color="#374151"/>
<stop offset="100%" stop-color="#0f172a"/>
</radialGradient>
<linearGradient id="jacket-3d" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#4338ca"/>
<stop offset="50%" stop-color="#3730a3"/>
<stop offset="100%" stop-color="#1e1b4b"/>
</linearGradient>
<linearGradient id="shirt-3d" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#ffffff"/>
<stop offset="100%" stop-color="#e0e7ff"/>
</linearGradient>
<linearGradient id="tie-3d" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#dc2626"/>
<stop offset="100%" stop-color="#7f1d1d"/>
</linearGradient>
<linearGradient id="headphone-3d" x1="20%" y1="0%" x2="80%" y2="100%">
<stop offset="0%" stop-color="#475569"/>
<stop offset="50%" stop-color="#1e293b"/>
<stop offset="100%" stop-color="#0f172a"/>
</linearGradient>
<linearGradient id="headphone-cushion" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#1e293b"/>
<stop offset="100%" stop-color="#020617"/>
</linearGradient>
<linearGradient id="mic-arm" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#475569"/>
<stop offset="100%" stop-color="#1e293b"/>
</linearGradient>
<radialGradient id="mic-bubble" cx="40%" cy="30%" r="70%">
<stop offset="0%" stop-color="#fca5a5"/>
<stop offset="50%" stop-color="#dc2626"/>
<stop offset="100%" stop-color="#7f1d1d"/>
</radialGradient>
<linearGradient id="glasses-lens" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="rgba(99, 102, 241, 0.3)"/>
<stop offset="100%" stop-color="rgba(168, 85, 247, 0.2)"/>
</linearGradient>
<linearGradient id="eye-3d" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#1e1b4b"/>
<stop offset="100%" stop-color="#0f172a"/>
</linearGradient>
<radialGradient id="eye-glint" cx="30%" cy="30%" r="50%">
<stop offset="0%" stop-color="white"/>
<stop offset="100%" stop-color="rgba(255, 255, 255, 0)"/>
</radialGradient>
<linearGradient id="mouth-3d" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#7f1d1d"/>
<stop offset="100%" stop-color="#450a0a"/>
</linearGradient>
<radialGradient id="cheek-blush" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="rgba(244, 63, 94, 0.3)"/>
<stop offset="100%" stop-color="rgba(244, 63, 94, 0)"/>
</radialGradient>
<linearGradient id="highlight" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="white" stop-opacity="0.6"/>
<stop offset="100%" stop-color="white" stop-opacity="0"/>
</linearGradient>
<filter id="soft-shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feFlood flood-color="black" flood-opacity="0.3"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<h1>坐席头像 v0.7 — C 方向终极版(我的 SVG 极限)</h1>
<p class="meta">深色背景 + 3D 拟人客服(西装/眼镜/领带/专业麦克风)· 2026-08-04 凌晨</p>
<div class="warning">
<strong>⚠️ 主理人坦诚:</strong><br>
我的 SVG 实现有<strong>硬上限</strong>。真正的"高级感"(如 Figma 设计师出的图、3D 渲染、Lottie 动画)需要<strong>专业工具或外部资源</strong><br>
当前展示的是<strong>我的极限</strong>(增加更多细节:西装+领带+眼镜+专业麦克风+3D 阴影),但实际生产时建议看下方<strong>3 种突破方式</strong>选一种。
</div>
<h2>🎨 终极版坐席头像(深色背景 + 3D 立体)</h2>
<div class="demo-block">
<div class="demo-label">4 个尺寸/状态展示(38px / 42px / 60px / 80px)</div>
<div class="avatar-showcase">
<!-- 38px 小尺寸 -->
<div class="avatar-cell">
<svg width="38" height="38" viewBox="0 0 100 100" fill="none">
<circle cx="50" cy="50" r="48" fill="url(#bg-cosmic)"/>
<circle cx="50" cy="48" r="22" fill="url(#skin-3d)"/>
<ellipse cx="50" cy="36" rx="18" ry="10" fill="url(#hair-3d)"/>
<ellipse cx="32" cy="48" rx="6" ry="9" fill="url(#headphone-3d)"/>
<ellipse cx="68" cy="48" rx="6" ry="9" fill="url(#headphone-3d)"/>
<ellipse cx="32" cy="48" rx="3" ry="5" fill="url(#headphone-cushion)"/>
<ellipse cx="68" cy="48" rx="3" ry="5" fill="url(#headphone-cushion)"/>
<circle cx="42" cy="48" r="2" ry="2.5" fill="url(#eye-3d)"/>
<circle cx="58" cy="48" r="2" ry="2.5" fill="url(#eye-3d)"/>
<path d="M44 56 Q50 60 56 56" fill="none" stroke="#7f1d1d" stroke-width="2" stroke-linecap="round"/>
</svg>
<div class="label">38px (小尺寸)</div>
</div>
<!-- 42px 工具栏大小 -->
<div class="avatar-cell">
<svg width="42" height="42" viewBox="0 0 100 100" fill="none">
<circle cx="50" cy="50" r="48" fill="url(#bg-cosmic)"/>
<ellipse cx="50" cy="20" rx="35" ry="8" fill="white" opacity="0.15"/>
<circle cx="50" cy="48" r="24" fill="url(#skin-3d)"/>
<ellipse cx="50" cy="34" rx="20" ry="11" fill="url(#hair-3d)"/>
<ellipse cx="28" cy="50" rx="7" ry="11" fill="url(#headphone-3d)"/>
<ellipse cx="72" cy="50" rx="7" ry="11" fill="url(#headphone-3d)"/>
<ellipse cx="28" cy="50" rx="3.5" ry="6" fill="url(#headphone-cushion)"/>
<ellipse cx="72" cy="50" rx="3.5" ry="6" fill="url(#headphone-cushion)"/>
<circle cx="42" cy="49" r="2.5" ry="3" fill="url(#eye-3d)"/>
<circle cx="58" cy="49" r="2.5" ry="3" fill="url(#eye-3d)"/>
<circle cx="42.7" cy="48" r="0.8" fill="white"/>
<circle cx="58.7" cy="48" r="0.8" fill="white"/>
<path d="M38 45 Q42 43 46 45" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
<path d="M54 45 Q58 43 62 45" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
<path d="M44 57 Q50 61 56 57" fill="none" stroke="#7f1d1d" stroke-width="2" stroke-linecap="round"/>
<path d="M28 58 Q28 64 35 66" fill="none" stroke="url(#mic-arm)" stroke-width="2" stroke-linecap="round"/>
<circle cx="35" cy="66" r="2.5" fill="url(#mic-bubble)"/>
</svg>
<div class="label">42px (工具栏实际)</div>
</div>
<!-- 60px 中等 -->
<div class="avatar-cell">
<svg width="60" height="60" viewBox="0 0 100 100" fill="none">
<circle cx="50" cy="50" r="48" fill="url(#bg-cosmic)"/>
<ellipse cx="50" cy="20" rx="35" ry="8" fill="white" opacity="0.2"/>
<path d="M22 80 Q22 70 32 65 L68 65 Q78 70 78 80 L78 92 L22 92 Z" fill="url(#jacket-3d)"/>
<path d="M40 65 L50 75 L60 65 L60 60 L50 65 L40 60 Z" fill="url(#shirt-3d)"/>
<path d="M48 70 L52 70 L50 80 L48 80 Z" fill="url(#tie-3d)"/>
<rect x="44" y="55" width="12" height="14" fill="url(#skin-3d)"/>
<ellipse cx="42" cy="70" rx="6" ry="3" fill="rgba(244, 63, 94, 0.2)"/>
<ellipse cx="58" cy="70" rx="6" ry="3" fill="rgba(244, 63, 94, 0.2)"/>
<circle cx="50" cy="40" r="20" fill="url(#skin-3d)"/>
<ellipse cx="50" cy="28" rx="14" ry="6" fill="white" opacity="0.4"/>
<path d="M30 38 Q30 22 50 20 Q70 22 70 38 L70 32 Q70 28 65 26 L60 28 Q55 24 50 24 Q45 24 40 28 L35 26 Q30 28 30 32 Z" fill="url(#hair-3d)"/>
<ellipse cx="28" cy="42" rx="6" ry="9" fill="url(#headphone-3d)"/>
<ellipse cx="72" cy="42" rx="6" ry="9" fill="url(#headphone-3d)"/>
<ellipse cx="28" cy="42" rx="3" ry="5" fill="url(#headphone-cushion)"/>
<ellipse cx="72" cy="42" rx="3" ry="5" fill="url(#headphone-cushion)"/>
<ellipse cx="28" cy="40" rx="1" ry="2" fill="white" opacity="0.4"/>
<ellipse cx="72" cy="40" rx="1" ry="2" fill="white" opacity="0.4"/>
<path d="M28 50 Q28 56 35 58" fill="none" stroke="url(#mic-arm)" stroke-width="2.5" stroke-linecap="round"/>
<circle cx="35" cy="58" r="3" fill="url(#mic-bubble)"/>
<circle cx="35" cy="57" r="0.8" fill="white" opacity="0.5"/>
<circle cx="42" cy="40" r="2.2" ry="2.8" fill="url(#eye-3d)"/>
<circle cx="58" cy="40" r="2.2" ry="2.8" fill="url(#eye-3d)"/>
<circle cx="42.7" cy="39" r="0.8" fill="white"/>
<circle cx="58.7" cy="39" r="0.8" fill="white"/>
<circle cx="42" cy="40.5" r="0.4" fill="url(#eye-glint)"/>
<circle cx="58" cy="40.5" r="0.4" fill="url(#eye-glint)"/>
<path d="M38 35 Q42 33 46 35" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
<path d="M54 35 Q58 33 62 35" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
<path d="M50 42 L48 48 L52 48" fill="none" stroke="#d97706" stroke-width="1" stroke-linecap="round" opacity="0.6"/>
<path d="M44 52 Q50 56 56 52" fill="none" stroke="#7f1d1d" stroke-width="1.5" stroke-linecap="round"/>
<path d="M44 54 Q50 60 56 54" fill="none" stroke="url(#mouth-3d)" stroke-width="1" stroke-linecap="round" opacity="0.6"/>
</svg>
<div class="label">60px (中等)</div>
</div>
<!-- 80px 大尺寸 -->
<div class="avatar-cell">
<svg width="80" height="80" viewBox="0 0 100 100" fill="none">
<circle cx="50" cy="50" r="48" fill="url(#bg-cosmic)"/>
<ellipse cx="50" cy="18" rx="36" ry="10" fill="white" opacity="0.22"/>
<circle cx="65" cy="25" r="4" fill="rgba(255, 255, 255, 0.3)"/>
<path d="M22 80 Q22 70 32 65 L68 65 Q78 70 78 80 L78 92 L22 92 Z" fill="url(#jacket-3d)"/>
<path d="M22 80 L22 92 L78 92 L78 80 L70 75 L65 80 L50 92 L35 80 L30 75 Z" fill="url(#jacket-3d)" opacity="0.6"/>
<path d="M40 65 L50 75 L60 65 L60 60 L50 65 L40 60 Z" fill="url(#shirt-3d)"/>
<path d="M48 68 L52 68 L50 84 L48 84 Z" fill="url(#tie-3d)"/>
<path d="M50 70 L48 80 L52 80 L50 70 Z" fill="#fbbf24" opacity="0.4"/>
<rect x="44" y="55" width="12" height="14" fill="url(#skin-3d)"/>
<ellipse cx="42" cy="72" rx="6" ry="2.5" fill="url(#cheek-blush)"/>
<ellipse cx="58" cy="72" rx="6" ry="2.5" fill="url(#cheek-blush)"/>
<circle cx="50" cy="40" r="22" fill="url(#skin-3d)"/>
<ellipse cx="50" cy="26" rx="16" ry="8" fill="url(#highlight)"/>
<path d="M30 36 Q30 20 50 18 Q70 20 70 36 L70 30 Q70 26 65 24 L60 26 Q55 22 50 22 Q45 22 40 26 L35 24 Q30 26 30 30 Z" fill="url(#hair-3d)"/>
<path d="M32 32 Q35 30 38 32" stroke="#1e1b4b" stroke-width="0.5" fill="none" opacity="0.6"/>
<path d="M62 32 Q65 30 68 32" stroke="#1e1b4b" stroke-width="0.5" fill="none" opacity="0.6"/>
<ellipse cx="28" cy="42" rx="7" ry="11" fill="url(#headphone-3d)"/>
<ellipse cx="72" cy="42" rx="7" ry="11" fill="url(#headphone-3d)"/>
<ellipse cx="28" cy="42" rx="3.5" ry="6" fill="url(#headphone-cushion)"/>
<ellipse cx="72" cy="42" rx="3.5" ry="6" fill="url(#headphone-cushion)"/>
<ellipse cx="27" cy="38" rx="1.5" ry="3" fill="white" opacity="0.4"/>
<ellipse cx="71" cy="38" rx="1.5" ry="3" fill="white" opacity="0.4"/>
<path d="M28 50 Q28 58 35 60" fill="none" stroke="url(#mic-arm)" stroke-width="3" stroke-linecap="round"/>
<circle cx="35" cy="60" r="3.5" fill="url(#mic-bubble)"/>
<circle cx="35" cy="58.5" r="1" fill="white" opacity="0.6"/>
<path d="M28 50 L32 50" stroke="url(#mic-arm)" stroke-width="1.5" opacity="0.5"/>
<circle cx="42" cy="40" r="2.5" ry="3.2" fill="url(#eye-3d)"/>
<circle cx="58" cy="40" r="2.5" ry="3.2" fill="url(#eye-3d)"/>
<circle cx="42.7" cy="39" r="1" fill="white"/>
<circle cx="58.7" cy="39" r="1" fill="white"/>
<circle cx="42" cy="40.5" r="0.5" fill="url(#eye-glint)"/>
<circle cx="58" cy="40.5" r="0.5" fill="url(#eye-glint)"/>
<path d="M38 34 Q42 32 46 34" fill="none" stroke="#1e1b4b" stroke-width="1.8" stroke-linecap="round"/>
<path d="M54 34 Q58 32 62 34" fill="none" stroke="#1e1b4b" stroke-width="1.8" stroke-linecap="round"/>
<path d="M50 42 L48 48 L52 48" fill="none" stroke="#d97706" stroke-width="1.2" stroke-linecap="round" opacity="0.6"/>
<path d="M50 48 L50 49" stroke="#d97706" stroke-width="0.6" opacity="0.5"/>
<path d="M44 52 Q50 56 56 52" fill="none" stroke="#7f1d1d" stroke-width="1.8" stroke-linecap="round"/>
<path d="M44 54 Q50 60 56 54" fill="none" stroke="url(#mouth-3d)" stroke-width="1" stroke-linecap="round" opacity="0.6"/>
<path d="M44 58 Q50 56 56 58" fill="rgba(244, 63, 94, 0.15)"/>
</svg>
<div class="label">80px (大尺寸 · 我的 SVG 极限)</div>
</div>
</div>
<p style="font-size: 12px; color: #c7d2fe; margin-top: 12px;">
v0.7 增加的细节: 西装+领带+头发层次+耳罩立体感+眼高光+脸颊红晕+专业麦克风臂+3D 阴影
</p>
</div>
<h2>🎬 6 态切换(80px 大尺寸演示)</h2>
<div class="demo-block">
<div class="state-tabs">
<button class="state-tab active" data-state="active">active</button>
<button class="state-tab" data-state="disabled">disabled</button>
<button class="state-tab" data-state="urgent">urgent</button>
<button class="state-tab" data-state="waiting">waiting</button>
<button class="state-tab" data-state="end">end</button>
<button class="state-tab" data-state="reopen">reopen</button>
</div>
<div class="stage-bg">
<div id="state-stage"></div>
</div>
<div class="state-desc" id="state-desc"></div>
</div>
<h2>🎯 真正"高级"的 3 种突破方式(实施选项)</h2>
<div class="warning">
<strong>关键认知:</strong>无论我用 SVG 怎么精细,SVG 的"高级感"有天花板。要真正"高级",需要下面 3 种方式之一。
</div>
<table class="breakthrough-table">
<thead>
<tr>
<th>突破方式</th>
<th>说明</th>
<th>成本</th>
<th>效果</th>
<th>推荐度</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>A. 专业设计师重画 SVG</strong></td>
<td>找 UI 设计师用 Figma/Illustrator 画专业级 SVG,导出后由工程师集成到 InputBar.vue。可做完整动态表情(6 态 × 表情变化)</td>
<td>中等(1-3 天设计师工时 + 集成 0.5 天)</td>
<td>★★★★★ 顶级</td>
<td class="no">⭐ 推荐</td>
</tr>
<tr>
<td><strong>B. Lottie 动画</strong></td>
<td>设计师用 After Effects 做 Lottie 动画(完整 3D 立体拟人 + 6 态过渡),前端用 lottie-web 库渲染。占用空间大但效果最佳</td>
<td>较高(3-5 天设计师 + 0.5 天集成 + 引入 lottie-web 依赖 ~80KB)</td>
<td>★★★★★+ 顶级 + 动效丰富</td>
<td class="no">⭐ 强烈推荐(如有动画需求)</td>
</tr>
<tr>
<td><strong>C. 真人头像(企微通讯录)</strong></td>
<td>走最简方案:坐席头像从企微通讯录 API 获取真实头像(头像 URL),无头像时降级显示我做的 SVG。最克制但真实感最强</td>
<td>低(后端扩展 1-2 天 + 前端 0.5 天)</td>
<td>★★★★ 真实但失去品牌感</td>
<td class="partial">中等(需后端支持)</td>
</tr>
<tr>
<td><strong>D. 当前 v0.7 SVG 直接实施</strong></td>
<td>我做的 SVG 直接上线(我画的"西装+眼镜+立体感"客服),够用但"高级感"有上限</td>
<td>极低(0.5 天寇豆码实施)</td>
<td>★★★ 中等(我的极限)</td>
<td>不推荐(用户说"不够高级")</td>
</tr>
</tbody>
</table>
<h2>❓ 请你拍板(给主理人明确方向)</h2>
<ol style="margin-left: 20px; line-height: 1.8; color: #e0e7ff;">
<li><strong>接受 SVG 极限</strong>?承认 v0.7 是我的 SVG 上限,选 A/B/C 中的突破方式</li>
<li><strong>选 A/B/C/D 哪种</strong>?
<ul style="margin-left: 20px;">
<li><strong>A. 专业设计师重画 SVG</strong> — 找 Figma 设计师出图,效果顶级(1-3 天)</li>
<li><strong>B. Lottie 动画</strong> — After Effects 动画 + 6 态过渡(3-5 天,效果顶级 + 动效)</li>
<li><strong>C. 真人头像</strong> — 走企微通讯录 API(1-2 天,真实但失去品牌感)</li>
<li><strong>D. 直接用 v0.7</strong> — 不推荐(你已说"不够高级")</li>
</ul>
</li>
<li>如果选 <strong>A 设计师重画</strong>:你能提供设计师资源吗?或需要我帮忙找设计资源?</li>
<li>如果选 <strong>B Lottie</strong>:设计资源(动画师)+ 0.5 天集成 — 是否可承担?</li>
</ol>
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid rgba(255, 255, 255, 0.15); color: #a5b4fc; font-size: 11.5px;">
v0.7 终极版 · 2026-08-04 · Duckula 主理人 · 等待用户拍板突破方式
</p>
<script>
const stateMap = {
active: {
cls: 'is-active',
desc: '<strong>active</strong>: 紫粉渐变(蓝→紫→粉)+ 立体感 3D 拟人客服 — 默认"客服在线"。Cuberto/Spotify 风,品牌感最强。'
},
disabled: {
cls: 'is-disabled',
desc: '<strong>disabled</strong>: 半透明白 + 灰度滤镜 + opacity 0.4 — 表达"不可用",保留立体感头像轮廓但无彩色'
},
urgent: {
cls: 'is-urgent',
desc: '<strong>urgent</strong>: 红色渐变 + 1.6s 发光呼吸(光晕扩散 6px) — 表达"紧急,需关注"'
},
waiting: {
cls: 'is-waiting',
desc: '<strong>waiting</strong>: 橙黄渐变 + 立体感头像 — 表达"排队中"'
},
end: {
cls: 'is-end',
desc: '<strong>end</strong>: 绿色渐变 + 立体感头像 + 麦克风臂突出 — 表达"已接入坐席,通话中"'
},
reopen: {
cls: 'is-reopen',
desc: '<strong>reopen</strong>: 蓝色渐变 + 立体感头像 — 表达"会话已关闭,可重新打开"'
}
};
const svgBig = `<svg width="80" height="80" viewBox="0 0 100 100" fill="none">
<circle cx="50" cy="50" r="48" fill="url(#bg-cosmic)"/>
<ellipse cx="50" cy="18" rx="36" ry="10" fill="white" opacity="0.22"/>
<circle cx="65" cy="25" r="4" fill="rgba(255, 255, 255, 0.3)"/>
<path d="M22 80 Q22 70 32 65 L68 65 Q78 70 78 80 L78 92 L22 92 Z" fill="url(#jacket-3d)"/>
<path d="M40 65 L50 75 L60 65 L60 60 L50 65 L40 60 Z" fill="url(#shirt-3d)"/>
<path d="M48 68 L52 68 L50 84 L48 84 Z" fill="url(#tie-3d)"/>
<rect x="44" y="55" width="12" height="14" fill="url(#skin-3d)"/>
<ellipse cx="42" cy="72" rx="6" ry="2.5" fill="url(#cheek-blush)"/>
<ellipse cx="58" cy="72" rx="6" ry="2.5" fill="url(#cheek-blush)"/>
<circle cx="50" cy="40" r="22" fill="url(#skin-3d)"/>
<ellipse cx="50" cy="26" rx="16" ry="8" fill="url(#highlight)"/>
<path d="M30 36 Q30 20 50 18 Q70 20 70 36 L70 30 Q70 26 65 24 L60 26 Q55 22 50 22 Q45 22 40 26 L35 24 Q30 26 30 30 Z" fill="url(#hair-3d)"/>
<ellipse cx="28" cy="42" rx="7" ry="11" fill="url(#headphone-3d)"/>
<ellipse cx="72" cy="42" rx="7" ry="11" fill="url(#headphone-3d)"/>
<ellipse cx="28" cy="42" rx="3.5" ry="6" fill="url(#headphone-cushion)"/>
<ellipse cx="72" cy="42" rx="3.5" ry="6" fill="url(#headphone-cushion)"/>
<path d="M28 50 Q28 58 35 60" fill="none" stroke="url(#mic-arm)" stroke-width="3" stroke-linecap="round"/>
<circle cx="35" cy="60" r="3.5" fill="url(#mic-bubble)"/>
<circle cx="42" cy="40" r="2.5" ry="3.2" fill="url(#eye-3d)"/>
<circle cx="58" cy="40" r="2.5" ry="3.2" fill="url(#eye-3d)"/>
<circle cx="42.7" cy="39" r="1" fill="white"/>
<circle cx="58.7" cy="39" r="1" fill="white"/>
<path d="M38 34 Q42 32 46 34" fill="none" stroke="#1e1b4b" stroke-width="1.8" stroke-linecap="round"/>
<path d="M54 34 Q58 32 62 34" fill="none" stroke="#1e1b4b" stroke-width="1.8" stroke-linecap="round"/>
<path d="M50 42 L48 48 L52 48" fill="none" stroke="#d97706" stroke-width="1.2" stroke-linecap="round" opacity="0.6"/>
<path d="M44 52 Q50 56 56 52" fill="none" stroke="#7f1d1d" stroke-width="1.8" stroke-linecap="round"/>
<path d="M44 54 Q50 60 56 54" fill="none" stroke="url(#mouth-3d)" stroke-width="1" stroke-linecap="round" opacity="0.6"/>
</svg>`;
const stage = document.getElementById('state-stage');
const desc = document.getElementById('state-desc');
const tabs = document.querySelectorAll('.state-tab');
function render(state) {
const s = stateMap[state];
const gradMap = {
active: 'linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%)',
urgent: 'linear-gradient(135deg, #ef4444 0%, #dc2626 50%, #b91c1c 100%)',
waiting: 'linear-gradient(135deg, #f59e0b 0%, #d97706 50%, #b45309 100%)',
end: 'linear-gradient(135deg, #10b981 0%, #059669 50%, #047857 100%)',
reopen: 'linear-gradient(135deg, #3b82f6 0%, #2563eb 50%, #1d4ed8 100%)'
};
const bg = state === 'disabled' ? 'rgba(255, 255, 255, 0.1)' : (gradMap[state] || gradMap.active);
const filter = state === 'disabled' ? 'filter: grayscale(1);' : '';
const animation = state === 'urgent' ? 'animation: agentGlow 1.6s ease-in-out infinite;' : '';
stage.innerHTML = `<div style="width: 80px; height: 80px; border-radius: 50%; background: ${bg}; border: 2px solid rgba(255, 255, 255, 0.3); display: flex; align-items: center; justify-content: center; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); ${filter} ${animation}">${svgBig}</div>`;
desc.innerHTML = s.desc;
}
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
render(tab.dataset.state);
});
});
render('active');
</script>
</body>
</html>