Files
wecom_it_smart_desk/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-工具栏统一设计v0.9-3按钮居中.archive.html
T
2026-08-11 14:16:24 +08:00

499 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>工具栏统一设计 v0.9 - 3 按钮居中 + 高级感</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, #e0e7ff 0%, #f3e8ff 50%, #fce7f3 100%);
color: #1a1a1a;
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: #1a1a1a; }
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 40px 0 12px; color: #1a1a1a; }
h3 { font-size: 14px; font-weight: 600; margin: 16px 0 8px; color: #333; }
.meta { color: #6b7280; font-size: 12.5px; margin-bottom: 24px; }
/* === InputBar 容器模拟 === */
.inputbar-mock {
width: 100%;
max-width: 800px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.8);
border-radius: 20px;
padding: 16px;
box-shadow:
0 1px 0 rgba(255, 255, 255, 1) inset,
0 -1px 0 rgba(99, 102, 241, 0.08) inset,
0 4px 8px rgba(99, 102, 241, 0.05),
0 16px 32px rgba(99, 102, 241, 0.1);
}
.inputbar-mock-field {
width: 100%;
min-height: 80px;
background: rgba(255, 255, 255, 0.4);
border: 1px solid rgba(99, 102, 241, 0.12);
border-radius: 12px;
padding: 12px 16px;
font-size: 13px;
color: #9ca3af;
line-height: 1.6;
margin-top: 12px;
}
/* === 3 按钮居中工具栏(v0.5 玻璃拟态) === */
.glass-toolbar {
display: flex;
align-items: center;
justify-content: center; /* 居中 */
gap: 8px;
padding: 8px 16px;
margin: 0 auto 4px;
width: fit-content;
background: rgba(255, 255, 255, 0.55);
backdrop-filter: blur(28px) saturate(180%);
-webkit-backdrop-filter: blur(28px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.7);
border-radius: 18px;
box-shadow:
0 1px 0 rgba(255, 255, 255, 0.9) inset,
0 -1px 0 rgba(99, 102, 241, 0.08) inset,
0 2px 4px rgba(99, 102, 241, 0.05),
0 8px 16px rgba(99, 102, 241, 0.08),
0 24px 48px rgba(99, 102, 241, 0.05);
position: relative;
}
.glass-toolbar::before {
content: "";
position: absolute;
inset: 0;
border-radius: 18px;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.1) 40%, transparent 60%);
pointer-events: none;
}
.glass-toolbar::after {
content: "";
position: absolute;
inset: 0;
border-radius: 18px;
background: radial-gradient(circle at 20% 20%, rgba(99, 102, 241, 0.15) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(236, 72, 153, 0.12) 0%, transparent 50%);
pointer-events: none;
z-index: 0;
}
/* === 3 按钮(38px 圆 · 高级感渐变) === */
.glass-btn {
width: 38px;
height: 38px;
border: 1px solid rgba(255, 255, 255, 0.6);
background: rgba(255, 255, 255, 0.55);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
-webkit-tap-highlight-color: transparent;
position: relative;
z-index: 2;
box-shadow:
0 1px 0 rgba(255, 255, 255, 0.9) inset,
0 -1px 0 rgba(0, 0, 0, 0.04) inset,
0 1px 2px rgba(0, 0, 0, 0.04),
0 2px 4px rgba(0, 0, 0, 0.04);
overflow: visible;
}
.glass-btn:hover {
background: rgba(255, 255, 255, 0.75);
transform: translateY(-1px) scale(1.06);
box-shadow:
0 1px 0 rgba(255, 255, 255, 1) inset,
0 -1px 0 rgba(0, 0, 0, 0.04) inset,
0 2px 4px rgba(0, 0, 0, 0.06),
0 8px 16px rgba(99, 102, 241, 0.15);
}
.glass-btn:active { transform: translateY(0) scale(0.95); }
.glass-btn svg { width: 22px; height: 22px; display: block; }
/* === 3 按钮高亮态(active) === */
.glass-btn.is-active-emoji { background: linear-gradient(135deg, rgba(251, 191, 36, 0.9) 0%, rgba(245, 158, 11, 0.9) 100%); border-color: rgba(255, 255, 255, 0.4); }
.glass-btn.is-active-emoji::before { content: ""; position: absolute; inset: 1px; border-radius: 50%; background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, transparent 50%); pointer-events: none; }
.glass-btn.is-active-file { background: linear-gradient(135deg, rgba(59, 130, 246, 0.9) 0%, rgba(37, 99, 235, 0.9) 100%); border-color: rgba(255, 255, 255, 0.4); }
.glass-btn.is-active-file::before { content: ""; position: absolute; inset: 1px; border-radius: 50%; background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, transparent 50%); pointer-events: none; }
.glass-btn.is-active-voice { background: linear-gradient(135deg, rgba(139, 92, 246, 0.9) 0%, rgba(124, 58, 237, 0.9) 100%); border-color: rgba(255, 255, 255, 0.4); }
.glass-btn.is-active-voice::before { content: ""; position: absolute; inset: 1px; border-radius: 50%; background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, transparent 50%); pointer-events: none; }
/* 录音中态(语音) */
.glass-btn.is-recording {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.95) 0%, rgba(220, 38, 38, 0.95) 100%);
border-color: rgba(255, 255, 255, 0.4);
animation: recordingPulse 1.5s ease-in-out infinite;
}
@keyframes recordingPulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0), 0 1px 0 rgba(255, 255, 255, 0.9) inset; }
50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0.15), 0 1px 0 rgba(255, 255, 255, 0.9) inset; }
}
/* === 演示容器 === */
.demo-block {
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.7);
border-radius: 18px;
padding: 32px;
margin-bottom: 20px;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 8px 16px rgba(99, 102, 241, 0.06);
}
.demo-label { font-size: 11.5px; color: #6b7280; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 14px; font-weight: 500; }
/* === 状态切换 tab === */
.state-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid rgba(99, 102, 241, 0.12); }
.state-tab {
padding: 6px 12px;
border: 1px solid rgba(99, 102, 241, 0.2);
background: rgba(255, 255, 255, 0.6);
border-radius: 8px;
cursor: pointer;
font-size: 12.5px;
color: #4b5563;
transition: all 0.15s;
font-family: inherit;
}
.state-tab:hover { background: rgba(255, 255, 255, 0.8); }
.state-tab.active { background: linear-gradient(135deg, #6366f1, #8b5cf6); color: #fff; border-color: transparent; }
.stage-bg {
background: linear-gradient(135deg, #fafbfc 0%, #f0f1f5 100%);
border-radius: 10px;
padding: 32px;
min-height: 90px;
display: flex;
align-items: center;
justify-content: center;
}
.state-desc { color: #4b5563; font-size: 12.5px; line-height: 1.7; background: rgba(255, 255, 255, 0.5); padding: 12px 14px; border-radius: 10px; border-left: 2px solid #6366f1; margin-top: 12px; backdrop-filter: blur(10px); }
.state-desc strong { color: #1a1a1a; }
.note { background: rgba(254, 243, 199, 0.6); border-left: 3px solid #d97706; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #78350f; margin: 16px 0; backdrop-filter: blur(10px); }
/* === 设计对比表 === */
.cmp-table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12.5px; }
.cmp-table th, .cmp-table td { border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px 10px; text-align: left; }
.cmp-table th { background: rgba(255, 255, 255, 0.6); font-weight: 600; }
.yes { color: #059669; }
.no { color: #dc2626; }
.partial { color: #d97706; }
</style>
</head>
<body>
<svg width="0" height="0" style="position: absolute;">
<defs>
<!-- 表情 · 立体渐变(高级感) -->
<linearGradient id="g-emoji" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#fde68a"/><stop offset="60%" stop-color="#fbbf24"/><stop offset="100%" stop-color="#d97706"/>
</linearGradient>
<radialGradient id="g-emoji-blush" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="rgba(244, 63, 94, 0.4)"/>
<stop offset="100%" stop-color="rgba(244, 63, 94, 0)"/>
</radialGradient>
<linearGradient id="g-highlight" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="white" stop-opacity="0.7"/>
<stop offset="100%" stop-color="white" stop-opacity="0"/>
</linearGradient>
<!-- 文件 · 立体渐变 -->
<linearGradient id="g-doc-body" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#ffffff"/><stop offset="100%" stop-color="#dbeafe"/>
</linearGradient>
<linearGradient id="g-doc-fold" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#c7d2fe"/><stop offset="100%" stop-color="#6366f1"/>
</linearGradient>
<linearGradient id="g-doc-text" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#6366f1"/><stop offset="100%" stop-color="#a855f7"/>
</linearGradient>
<!-- 语音 · 立体渐变 -->
<linearGradient id="g-mic-body" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#c4b5fd"/><stop offset="50%" stop-color="#8b5cf6"/><stop offset="100%" stop-color="#6d28d9"/>
</linearGradient>
<linearGradient id="g-mic-shine" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="white" stop-opacity="0.65"/><stop offset="100%" stop-color="white" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>
<h1>工具栏统一设计 v0.9 — 3 按钮居中 + 高级感</h1>
<p class="meta">表情/文件/语音输入 · v0.5 玻璃拟态 · 居中布局 · 高级感 SVG(渐变+高光+阴影)· 2026-08-04 凌晨</p>
<div class="note">
📌 本版核心改动(对比 v0.8):<br>
<strong>3 按钮</strong>(不是 4 按钮) — 客服按钮不在 InputBar 工具栏,只在<strong>整合区</strong>(v0.8 双入口设计)<br>
<strong>整体居中布局</strong> — 沿用 v0.8 位置(`justify-content: center`)<br>
• v0.5 玻璃拟态✅ 沿用<br>
<strong>高级感 SVG</strong> — 每个按钮都用渐变填充+顶部高光+阴影(v0.6 升级版)
</div>
<h2>🎨 3 按钮 InputBar 工具栏(居中布局)</h2>
<div class="demo-block">
<div class="demo-label">InputBar 工具栏 · 整体居中 · 3 按钮(表情/文件/语音)</div>
<div class="inputbar-mock">
<!-- 居中的整体工具栏 -->
<div class="glass-toolbar">
<!-- 1. 表情(高级感) -->
<button class="glass-btn" title="表情">
<svg viewBox="0 0 24 24" fill="none">
<!-- 脸(立体渐变) -->
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
<!-- 顶部高光 -->
<ellipse cx="12" cy="6" rx="6" ry="2.5" fill="url(#g-highlight)"/>
<!-- 脸颊红晕 -->
<ellipse cx="6.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
<ellipse cx="17.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
<!-- 立体眼睛(双高光) -->
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
<circle cx="8.3" cy="11.5" r="0.3" fill="white" opacity="0.6"/>
<circle cx="15.7" cy="11.5" r="0.3" fill="white" opacity="0.6"/>
<!-- 嘴(立体感) -->
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
<path d="M8 15 Q12 17 16 15" fill="rgba(244, 63, 94, 0.2)"/>
</svg>
</button>
<!-- 2. 文件(高级感) -->
<button class="glass-btn" title="文件">
<svg viewBox="0 0 24 24" fill="none">
<!-- 文档主体(立体渐变) -->
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
<!-- 折角(渐变) -->
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
<!-- 顶部高光 -->
<ellipse cx="10" cy="4" rx="5" ry="0.8" fill="url(#g-highlight)"/>
<!-- 文字行(渐变) -->
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
<rect x="7" y="14" width="8" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.7"/>
<rect x="7" y="16.5" width="6" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.5"/>
</svg>
</button>
<!-- 3. 语音输入(高级感) -->
<button class="glass-btn" title="语音输入">
<svg viewBox="0 0 24 24" fill="none">
<!-- 麦克风主体(深紫渐变) -->
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
<!-- 顶部高光(立体感) -->
<rect x="9" y="3" width="2" height="11" rx="1" fill="url(#g-mic-shine)"/>
<!-- 麦克风网格(细节) -->
<line x1="10.5" y1="6" x2="10.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
<line x1="12" y1="5" x2="12" y2="12" stroke="white" stroke-width="0.3" opacity="0.4"/>
<line x1="13.5" y1="6" x2="13.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
<!-- 底座弧线(渐变) -->
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
<!-- 支柱 -->
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
<line x1="8" y1="22" x2="16" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
</svg>
</button>
</div>
<!-- 输入框(在工具栏下方) -->
<div class="inputbar-mock-field">
请输入消息...(输入框在工具栏下方)
</div>
</div>
</div>
<h2>🎨 3 按钮不同状态对比(高亮 + 录音中)</h2>
<div class="demo-block">
<div class="state-tabs">
<button class="state-tab active" data-state="default">默认</button>
<button class="state-tab" data-state="emoji-active">表情激活</button>
<button class="state-tab" data-state="file-active">文件激活</button>
<button class="state-tab" data-state="voice-active">语音激活</button>
<button class="state-tab" data-state="voice-recording">语音录音中</button>
</div>
<div class="stage-bg">
<div class="glass-toolbar" id="state-stage"></div>
</div>
<div class="state-desc" id="state-desc"></div>
</div>
<h2>📊 与之前版本对比</h2>
<table class="cmp-table">
<thead>
<tr>
<th>维度</th>
<th>v0.1 方块</th>
<th>v0.2 灵动岛</th>
<th>v0.3 克制</th>
<th>v0.4 圆形渐变</th>
<th>v0.5 玻璃</th>
<th>v0.8 4按钮居中</th>
<th><strong>v0.9 3按钮居中</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>按钮数</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td class="yes">4</td>
<td class="yes"><strong>3</strong></td>
</tr>
<tr>
<td>布局</td>
<td>左上</td>
<td>左上</td>
<td>左上</td>
<td>左上</td>
<td>左上</td>
<td>居中</td>
<td class="yes"><strong>居中</strong></td>
</tr>
<tr>
<td>背景</td>
<td></td>
<td></td>
<td></td>
<td>白底</td>
<td>玻璃</td>
<td>玻璃</td>
<td class="yes"><strong>玻璃</strong></td>
</tr>
<tr>
<td>图标</td>
<td>emoji</td>
<td>卡通</td>
<td>简单</td>
<td>抽象</td>
<td>立体</td>
<td>立体+图片</td>
<td class="yes"><strong>高级感渐变+高光</strong></td>
</tr>
<tr>
<td>客服按钮</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>✓ (图片)</td>
<td class="no"><strong>✗(只在整合区)</strong></td>
</tr>
</tbody>
</table>
<h2>❓ 待你拍板</h2>
<ol style="margin-left: 20px; line-height: 1.8;">
<li><strong>3 按钮(表情/文件/语音)</strong>符合期望吗?客服按钮<strong>只在整合区</strong>(v0.8 双入口设计)</li>
<li><strong>居中布局</strong>OK 吗?</li>
<li><strong>高级感图标</strong>(渐变填充+高光+阴影+红晕)OK 吗?如需更精致(更复杂 SVG 或真 3D),需设计师</li>
<li>激活态(表情打开/文件选/语音录)的<strong>渐变色</strong>(黄/蓝/紫)OK 吗?</li>
</ol>
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid rgba(99, 102, 241, 0.15); color: #6b7280; font-size: 11.5px;">
v0.9 3 按钮居中 · 2026-08-04 · Duckula 主理人 · 等待用户拍板
</p>
<script>
const stateMap = {
'default': {
emoji: '', file: '', voice: '',
desc: '<strong>默认状态</strong>: 3 按钮默认(浅玻璃) — 表情/文件/语音都未激活,等待用户操作'
},
'emoji-active': {
emoji: 'is-active-emoji', file: '', voice: '',
desc: '<strong>表情激活</strong>: 表情按钮变<strong>黄橙渐变</strong>(顶部高光) — 表情面板已打开'
},
'file-active': {
emoji: '', file: 'is-active-file', voice: '',
desc: '<strong>文件激活</strong>: 文件按钮变<strong>蓝紫渐变</strong> — 文件选择器已打开'
},
'voice-active': {
emoji: '', file: '', voice: 'is-active-voice',
desc: '<strong>语音激活</strong>: 语音按钮变<strong>紫粉渐变</strong> — 准备录音(可点击开始)'
},
'voice-recording': {
emoji: '', file: '', voice: 'is-recording',
desc: '<strong>语音录音中</strong>: 语音按钮变<strong>红色渐变 + 1.5s 发光呼吸</strong> — 正在录音(点击停止)'
}
};
const svgEmoji = `<svg viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
<ellipse cx="12" cy="6" rx="6" ry="2.5" fill="url(#g-highlight)"/>
<ellipse cx="6.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
<ellipse cx="17.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
<circle cx="8.3" cy="11.5" r="0.3" fill="white" opacity="0.6"/>
<circle cx="15.7" cy="11.5" r="0.3" fill="white" opacity="0.6"/>
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
<path d="M8 15 Q12 17 16 15" fill="rgba(244, 63, 94, 0.2)"/>
</svg>`;
const svgFile = `<svg viewBox="0 0 24 24" fill="none">
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
<ellipse cx="10" cy="4" rx="5" ry="0.8" fill="url(#g-highlight)"/>
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
<rect x="7" y="14" width="8" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.7"/>
<rect x="7" y="16.5" width="6" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.5"/>
</svg>`;
const svgVoice = `<svg viewBox="0 0 24 24" fill="none">
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
<rect x="9" y="3" width="2" height="11" rx="1" fill="url(#g-mic-shine)"/>
<line x1="10.5" y1="6" x2="10.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
<line x1="12" y1="5" x2="12" y2="12" stroke="white" stroke-width="0.3" opacity="0.4"/>
<line x1="13.5" y1="6" x2="13.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
<line x1="8" y1="22" x2="16" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
</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];
stage.innerHTML = `
<button class="glass-btn ${s.emoji}" title="表情">${svgEmoji}</button>
<button class="glass-btn ${s.file}" title="文件">${svgFile}</button>
<button class="glass-btn ${s.voice}" title="语音">${svgVoice}</button>
`;
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('default');
</script>
</body>
</html>