Files
Thing/music-redesign-mockup.html
T
2026-09-12 15:47:16 +08:00

431 lines
23 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>音乐模块 · 界面改版对照稿</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
:root{
--bg:#f4f4f5; --panel:#ffffff; --panel-2:#fafafa; --line:#e7e7e9; --line-2:#f0f0f1;
--fg:#18181b; --fg-2:#71717a; --fg-3:#a1a1aa;
--primary:#18181b; --primary-fg:#fafafa; --accent:#f4f4f5;
--ok:#0f7b4f; --warn:#9a3412; --err:#b91c1c;
}
body{
font-family: system-ui,-apple-system,"Segoe UI","Microsoft YaHei","PingFang SC",sans-serif;
background:var(--bg); color:var(--fg); font-size:13px; line-height:1.55; padding:28px 20px 60px;
-webkit-font-smoothing:antialiased;
}
.wrap{ max-width:1180px; margin:0 auto; }
h1{ font-size:19px; font-weight:600; letter-spacing:-.01em; }
.sub{ color:var(--fg-2); font-size:12.5px; margin-top:4px; }
.toolbar{ display:flex; align-items:center; gap:10px; margin:18px 0 14px; flex-wrap:wrap; }
.seg{ display:inline-flex; background:#e9e9eb; border-radius:8px; padding:3px; gap:2px; }
.seg button{
border:0; background:transparent; font:inherit; font-size:12.5px; color:var(--fg-2);
padding:6px 14px; border-radius:6px; cursor:pointer; transition:.15s;
}
.seg button.on{ background:#fff; color:var(--fg); font-weight:500; box-shadow:0 1px 2px rgba(0,0,0,.08); }
.hint{ color:var(--fg-3); font-size:12px; }
/* ---------- window frame ---------- */
.win{
background:var(--panel); border:1px solid var(--line); border-radius:11px; overflow:hidden;
box-shadow:0 8px 28px rgba(0,0,0,.07); display:flex; flex-direction:column; height:640px;
}
.titlebar{
height:38px; flex:0 0 38px; display:flex; align-items:center; gap:8px; padding:0 12px;
background:var(--panel-2); border-bottom:1px solid var(--line);
}
.dots{ display:flex; gap:5px; }
.dots i{ width:9px; height:9px; border-radius:50%; background:#dcdce0; display:block; }
.tb-title{ font-size:12px; color:var(--fg-2); margin-left:6px; }
.tb-tabs{ margin-left:auto; display:flex; gap:4px; }
.tb-tabs span{ font-size:11px; color:var(--fg-2); padding:3px 9px; border-radius:5px; }
.tb-tabs span.on{ background:#e9e9eb; color:var(--fg); }
.body{ flex:1; display:flex; min-height:0; }
/* ---------- left module rail ---------- */
.rail{
width:52px; flex:0 0 52px; border-right:1px solid var(--line); background:var(--panel-2);
display:flex; flex-direction:column; align-items:center; gap:4px; padding:10px 0;
}
.rail i{
width:32px; height:32px; border-radius:8px; background:#ececed; display:grid; place-items:center;
font-size:12px; color:var(--fg-2); font-style:normal;
}
.rail i.on{ background:var(--primary); color:#fff; }
/* ---------- source tree ---------- */
.tree{ width:186px; flex:0 0 186px; border-right:1px solid var(--line); padding:12px 10px; background:var(--panel); }
.tree h4{ font-size:11px; color:var(--fg-3); font-weight:500; padding:6px 8px 4px; letter-spacing:.03em; }
.tree a{
display:flex; align-items:center; gap:8px; padding:6px 8px; border-radius:6px;
color:var(--fg-2); text-decoration:none; font-size:12.5px; margin-bottom:1px;
}
.tree a.on{ background:#ececed; color:var(--fg); font-weight:500; }
.tree a b{ margin-left:auto; font-weight:400; font-size:11px; color:var(--fg-3); }
/* ---------- main ---------- */
.main{ flex:1; min-width:0; display:flex; flex-direction:column; background:var(--panel); }
.main-head{ padding:12px 16px 10px; border-bottom:1px solid var(--line-2); display:flex; align-items:center; gap:8px; }
.field{
height:30px; border:1px solid var(--line); border-radius:7px; background:#fff;
display:flex; align-items:center; padding:0 10px; color:var(--fg-3); font-size:12.5px; flex:1; max-width:330px;
}
.btn{ height:30px; padding:0 12px; border-radius:7px; border:1px solid var(--line); background:#fff; color:var(--fg); font-size:12.5px; display:inline-flex; align-items:center; gap:5px; }
.btn.dark{ background:var(--primary); color:#fff; border-color:var(--primary); }
.main-body{ flex:1; min-height:0; overflow:hidden; }
.thead{
display:grid; grid-template-columns:34px 44px minmax(0,3fr) minmax(0,2fr) 52px 34px;
gap:10px; align-items:center; padding:6px 16px; border-bottom:1px solid var(--line-2);
font-size:11px; color:var(--fg-3);
}
.row{
display:grid; grid-template-columns:34px 44px minmax(0,3fr) minmax(0,2fr) 52px 34px;
gap:10px; align-items:center; padding:5px 16px; height:44px; border-bottom:1px solid var(--line-2);
}
.row:hover{ background:var(--accent); }
.row.on{ background:#f4f4f5; }
.row.on .t1{ color:var(--fg); font-weight:500; }
.idx{ font-size:11.5px; color:var(--fg-3); text-align:right; }
.eq{ display:flex; align-items:flex-end; gap:2px; height:12px; }
.eq i{ width:2.5px; background:var(--primary); border-radius:1px; display:block; }
.eq i:nth-child(1){ height:5px } .eq i:nth-child(2){ height:11px } .eq i:nth-child(3){ height:8px }
.cov{ width:36px; height:36px; border-radius:6px; background:#e9e9eb; }
.t1{ font-size:13px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.t2{ font-size:11.5px; color:var(--fg-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.tag{ font-size:10px; padding:1px 6px; border-radius:4px; border:1px solid var(--line); color:var(--fg-2); white-space:nowrap; }
.tag.solid{ background:#ececed; border-color:transparent; }
.dur{ font-size:11.5px; color:var(--fg-3); font-variant-numeric:tabular-nums; text-align:right; }
.more{ color:var(--fg-3); text-align:center; opacity:0; }
.row:hover .more{ opacity:1; }
/* ---------- right now playing ---------- */
.np{ width:250px; flex:0 0 250px; border-left:1px solid var(--line); padding:16px; display:flex; flex-direction:column; gap:12px; background:var(--panel); }
.np-cover{ width:100%; aspect-ratio:1; border-radius:10px; background:linear-gradient(150deg,#e8e8ea,#d6d6da); }
.np h3{ font-size:14px; font-weight:500; }
.np p{ font-size:12px; color:var(--fg-2); }
.lyric{ display:flex; flex-direction:column; gap:7px; margin-top:4px; }
.lyric span{ font-size:12.5px; color:var(--fg-3); }
.lyric span.on{ font-size:14px; color:var(--fg); font-weight:500; }
/* ---------- player bar ---------- */
.player{
flex:0 0 72px; height:72px; border-top:1px solid var(--line); background:rgba(255,255,255,.92);
backdrop-filter:blur(12px); display:flex; align-items:center; gap:14px; padding:0 16px;
}
.pl-left{ width:236px; flex:0 0 236px; display:flex; align-items:center; gap:10px; min-width:0; }
.pl-left .cov{ width:44px; height:44px; border-radius:6px; }
.pl-mid{ flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; gap:4px; }
.pl-ctrl{ display:flex; align-items:center; gap:16px; color:var(--fg-2); }
.pl-play{ width:34px; height:34px; border-radius:50%; background:var(--primary); color:#fff; display:grid; place-items:center; font-size:11px; }
.pl-seek{ width:100%; max-width:520px; display:flex; align-items:center; gap:8px; }
.pl-seek .time{ font-size:10.5px; color:var(--fg-3); font-variant-numeric:tabular-nums; width:34px; }
.track{ flex:1; height:4px; border-radius:2px; background:#e4e4e7; position:relative; }
.track .buf{ position:absolute; inset:0 auto 0 0; width:34%; background:#d4d4d8; border-radius:2px; }
.track .fill{ position:absolute; inset:0 auto 0 0; width:22%; background:var(--primary); border-radius:2px; }
.track .knob{ position:absolute; left:22%; top:50%; width:10px; height:10px; margin:-5px 0 0 -5px; border-radius:50%; background:var(--primary); }
.pl-right{ width:196px; flex:0 0 196px; display:flex; align-items:center; justify-content:flex-end; gap:10px; color:var(--fg-2); }
.vol{ width:76px; height:4px; border-radius:2px; background:#e4e4e7; position:relative; }
.vol i{ position:absolute; inset:0 auto 0 0; width:70%; background:var(--primary); border-radius:2px; display:block; }
/* ---------- before view ---------- */
.before-pad{ padding:22px 22px 0; flex:1; min-height:0; display:flex; flex-direction:column; gap:14px; overflow:hidden; }
.b-tabs{ display:grid; grid-template-columns:repeat(4,1fr); max-width:430px; background:#ececed; border-radius:8px; padding:3px; font-size:12.5px; text-align:center; }
.b-tabs span{ padding:5px 0; border-radius:6px; color:var(--fg-2); }
.b-tabs span.on{ background:#fff; color:var(--fg); font-weight:500; }
.b-card{ border:1px solid var(--line); border-radius:9px; padding:9px 12px; display:flex; align-items:center; gap:10px; font-size:12.5px; }
.b-card.muted{ background:#fafafa; }
.b-row{ border:1px solid var(--line); border-radius:9px; padding:9px 11px; display:flex; align-items:center; gap:11px; margin-bottom:7px; }
.b-sub{ display:inline-flex; gap:3px; background:#ececed; border-radius:7px; padding:3px; font-size:12px; }
.b-sub span{ padding:4px 11px; border-radius:5px; color:var(--fg-2); }
.b-sub span.on{ background:var(--primary); color:#fff; }
.b-player{ border-top:1px solid var(--line); margin:0 22px; padding:10px 0; display:flex; align-items:center; gap:12px; }
.mark{
width:17px; height:17px; border-radius:50%; background:#b91c1c; color:#fff; font-size:10.5px;
display:inline-grid; place-items:center; flex:0 0 17px; font-weight:500;
}
.mark.g{ background:#0f7b4f; }
.mark.amber{ background:#b45309; }
/* ---------- legend ---------- */
.legend{ margin-top:20px; display:grid; grid-template-columns:repeat(auto-fit,minmax(310px,1fr)); gap:10px; }
.li{ background:#fff; border:1px solid var(--line); border-radius:9px; padding:11px 13px; display:flex; gap:10px; }
.li b{ display:block; font-size:12.5px; font-weight:500; margin-bottom:2px; }
.li p{ font-size:12px; color:var(--fg-2); }
.hide{ display:none !important; }
.note{ font-size:11.5px; color:var(--fg-3); margin-top:6px; }
</style>
</head>
<body>
<div class="wrap">
<h1>音乐模块 · 界面改版对照稿</h1>
<p class="sub">左边是当前实现的实际问题,右边是按建议方案重排后的目标形态。改版要点见下方图例。</p>
<div class="toolbar">
<div class="seg" id="seg">
<button data-v="before" class="on">当前实现</button>
<button data-v="after">建议方案</button>
</div>
<span class="hint" id="hint">红/橙标记 = 缺陷位置</span>
</div>
<!-- ================= BEFORE ================= -->
<div class="win" id="view-before">
<div class="titlebar">
<div class="dots"><i></i><i></i><i></i></div>
<span class="tb-title">Thing</span>
<div class="tb-tabs"><span class="on">我的音乐</span><span>发现音乐</span><span>下载任务</span><span>设置</span></div>
</div>
<div class="body">
<div class="rail">
<i class="on"></i><i></i><i></i><i></i><i></i>
</div>
<div class="before-pad">
<div style="display:flex;align-items:center;gap:10px">
<div class="b-tabs">
<span class="on">我的音乐</span><span>发现音乐</span><span>下载任务</span><span>设置</span>
</div>
</div>
<div style="display:flex;align-items:center;gap:10px">
<span class="b-sub"><span class="on">飞牛曲库</span><span>本地曲库</span><span>我的歌单</span></span>
<span class="hint">← 第二套切换控件,与上一行风格不同</span>
<span class="mark" style="margin-left:auto">3</span>
</div>
<div class="b-card">
<span class="hint">下载到</span>
<span class="tag">本地目录 ▾</span>
<span class="hint">下载到本地目录(musicdl</span>
<span class="mark" style="margin-left:auto">1</span>
</div>
<div style="display:flex;gap:8px;align-items:center">
<div class="field" style="max-width:none">输入歌名 / 歌手 / 专辑关键词</div>
<span class="tag">已选 3 个源 ▾</span>
<span class="btn dark">搜索</span>
</div>
<div class="b-card muted">
<span class="hint">粘贴歌单链接(网易云 / QQ 音乐等)</span>
<span class="btn" style="margin-left:auto">解析歌单</span>
</div>
<div style="margin-top:2px">
<div class="b-row">
<span class="tag"></span><div class="cov" style="width:38px;height:38px"></div>
<div style="flex:1;min-width:0">
<div class="t1">海阔天空 <span class="tag" style="color:#7c3aed">无损 flac 32.4 MB</span> <span class="tag" style="color:#0369a1">320K mp3</span> <span class="tag">+2</span></div>
<div class="t2">Beyond · 乐与怒</div>
</div>
<span class="tag">05:21</span><span class="tag"></span><span class="tag"></span>
<span class="mark">2</span><span class="mark">5</span>
</div>
<div class="b-row">
<span class="tag"></span><div class="cov" style="width:38px;height:38px"></div>
<div style="flex:1;min-width:0">
<div class="t1">光辉岁月 <span class="tag" style="color:#b45309">Hi-Res flac 96.1 MB</span> <span class="tag" style="color:#a16207">192K mp3</span></div>
<div class="t2">Beyond · 命运派对</div>
</div>
<span class="tag">04:58</span><span class="tag"></span><span class="tag"></span>
<span class="mark">2</span>
</div>
<div class="b-row">
<span class="tag"></span><div class="cov" style="width:38px;height:38px"></div>
<div style="flex:1;min-width:0">
<div class="t1">喜欢你</div><div class="t2">Beyond · 秘密警察</div>
</div>
<span class="tag">04:35</span><span class="tag"></span><span class="tag"></span>
<span class="mark">6</span>
</div>
<span class="note">每行都是独立圆角卡片 + 8px 间距;一行内 6~8 个视觉元素,彩色徽标抢过歌名。</span>
</div>
</div>
</div>
<div class="b-player">
<div class="cov" style="width:44px;height:44px;border-radius:6px"></div>
<div style="min-width:0;max-width:150px">
<div class="t1">未播放</div><div class="t2">选择一首歌曲开始播放</div>
</div>
<div style="flex:1;display:flex;flex-direction:column;align-items:center;gap:4px">
<div class="pl-ctrl" style="font-size:13px"><span></span><span></span><span class="pl-play"></span><span></span><span></span></div>
<div class="pl-seek" style="max-width:360px">
<span class="time">--:--</span>
<div class="track"><div class="fill" style="width:0"></div><div class="knob" style="left:0"></div></div>
<span class="time">--:--</span>
</div>
</div>
<div class="pl-right"><span>🔊</span><div class="vol"><i></i></div><span></span><span></span></div>
<span class="mark" style="position:absolute">4</span>
</div>
<div style="position:relative">
<span class="mark" style="position:absolute;right:14px;bottom:44px">7</span>
<span class="mark" style="position:absolute;left:14px;bottom:60px">8</span>
</div>
</div>
<!-- ================= AFTER ================= -->
<div class="win hide" id="view-after">
<div class="titlebar">
<div class="dots"><i></i><i></i><i></i></div>
<span class="tb-title">Thing</span>
<div class="tb-tabs"><span class="on">曲库</span><span>发现音乐</span><span>下载任务</span><span>设置</span></div>
<span class="mark g" style="margin-left:8px">3</span>
</div>
<div class="body">
<div class="rail">
<i class="on"></i><i></i><i></i><i></i><i></i>
</div>
<div class="tree">
<h4>曲库</h4>
<a class="on">飞牛曲库 <b>1.2k</b></a>
<a>本地曲库 <b>318</b></a>
<a>我的歌单 <b>7</b></a>
<h4>其他</h4>
<a>发现音乐</a>
<a>下载任务 <b>2</b></a>
<a>设置</a>
<span class="mark g" style="margin:10px 0 0 8px">3</span>
</div>
<div class="main">
<div class="main-head">
<div class="field">搜索歌名 / 歌手 / 专辑</div>
<span class="tag">全部来源 ▾</span>
<span class="tag">全部音质 ▾</span>
<span class="btn" style="margin-left:auto">排序 ▾</span>
<span class="btn">扫描本地</span>
<span class="btn dark">▶ 播放全部</span>
<span class="mark g" style="margin-left:6px">1</span>
</div>
<div class="main-body">
<div class="thead">
<span style="text-align:right">#</span><span></span><span>标题</span><span>专辑</span><span style="text-align:right">时长</span><span></span>
</div>
<div class="row on">
<span class="idx"><span class="eq"><i></i><i></i><i></i></span></span>
<div class="cov"></div>
<div style="min-width:0">
<div class="t1">海阔天空</div>
<div class="t2">Beyond · 1993</div>
</div>
<div class="t2">乐与怒</div>
<span class="dur">05:21</span>
<span class="more"></span>
</div>
<div class="row">
<span class="idx">2</span>
<div class="cov"></div>
<div style="min-width:0"><div class="t1">光辉岁月</div><div class="t2">Beyond</div></div>
<div class="t2">命运派对</div>
<span class="dur">04:58</span>
<span class="more"></span>
</div>
<div class="row">
<span class="idx">3</span>
<div class="cov"></div>
<div style="min-width:0"><div class="t1">喜欢你</div><div class="t2">Beyond</div></div>
<div class="t2">秘密警察</div>
<span class="dur">04:35</span>
<span class="more"></span>
</div>
<div class="row">
<span class="idx">4</span>
<div class="cov"></div>
<div style="min-width:0"><div class="t1">冷雨夜</div><div class="t2">Beyond</div></div>
<div class="t2">现代舞台</div>
<span class="dur">04:12</span>
<span class="more"></span>
</div>
<div class="row">
<span class="idx">5</span>
<div class="cov"></div>
<div style="min-width:0"><div class="t1">真的爱你</div><div class="t2">Beyond</div></div>
<div class="t2">Beyond IV</div>
<span class="dur">04:41</span>
<span class="more"></span>
</div>
<div style="padding:8px 16px" class="note">
行高 44px、无独立边框、hover 高亮、双击整行播放;播放中行用主色竖条 + 均衡器表示,不再用“选中框”。
<span class="mark g">2</span>
</div>
</div>
</div>
<div class="np">
<div class="np-cover"></div>
<div>
<h3>海阔天空</h3>
<p>Beyond · 乐与怒</p>
</div>
<div class="track" style="height:4px"><div class="fill" style="width:38%"></div><div class="knob" style="left:38%"></div></div>
<div class="lyric">
<span>今天我 寒夜里看雪飘过</span>
<span>怀着冷却了的心窝漂远方</span>
<span class="on">风雨里追赶 雾里分不清影踪</span>
<span>天空海阔你与我</span>
<span>可会变(谁没在变)</span>
</div>
<span class="note">右栏“正在播放”可折叠(窄窗口自动收起)</span>
</div>
</div>
<div class="player">
<div class="pl-left">
<div class="cov"></div>
<div style="min-width:0">
<div class="t1">海阔天空</div>
<div class="t2">Beyond · 乐与怒</div>
</div>
<span class="mark g" style="margin-left:auto">4</span>
</div>
<div class="pl-mid">
<div class="pl-ctrl"><span>🔀</span><span></span><span class="pl-play">❚❚</span><span></span><span></span></div>
<div class="pl-seek">
<span class="time">01:12</span>
<div class="track"><div class="buf"></div><div class="fill"></div><div class="knob"></div></div>
<span class="time">05:21</span>
</div>
<span class="note" style="margin:0">拖动只更新预览,松手才 seek;轨道含缓冲层,hover 加粗到 8px</span>
</div>
<div class="pl-right">
<span class="mark g">5</span>
<span>🔊</span><div class="vol"><i></i></div><span></span><span></span>
</div>
</div>
</div>
<div class="legend" id="legend">
<div class="li"><span class="mark">1</span><div><b>首屏信息层级</b><p>“下载到 本地/飞牛”不再独占一行卡片,收进工具栏;搜索框回到首行黄金位置。</p></div></div>
<div class="li"><span class="mark">2</span><div><b>列表密度与徽标降噪</b><p>卡片堆 → 44px 紧凑表格行;音质徽标从 5 色降为 1 类中性 outline,档位详情收进 ⋯ 菜单。</p></div></div>
<div class="li"><span class="mark">3</span><div><b>两级横向 Tab → 左侧来源树</b><p>模块级 Tab + 子 Tab 合并为一条来源树,导航层级从三层降到两层。</p></div></div>
<div class="li"><span class="mark g">4</span><div><b>播放条全宽贴底</b><p>MiniPlayer 提升到 App 全局层:任何模块都能控制播放;离开音乐模块不再丢失控制入口。</p></div></div>
<div class="li"><span class="mark g">5</span><div><b>进度与音量交互</b><p>提交式 seek + 缓冲进度层;音量图标可点静音;滑块配色改走主题 token(原为硬编码纯白)。</p></div></div>
<div class="li"><span class="mark">6</span><div><b>来源与来源标识统一</b><p>本地/NAS/歌单混排时用统一图标标识来源,不再靠行内小标签。</p></div></div>
<div class="li"><span class="mark">7</span><div><b>内边距不对称</b><p>模块左 28px / 右 40px(含滚动条),卡片右边距明显偏窄;统一为 24px 并保留滚动条槽位。</p></div></div>
<div class="li"><span class="mark">8</span><div><b>播放条未贴底</b><p>被模块 p-6 包住,分隔线左右各缩进 24px,读作“漂浮卡片”而非底部坞站。</p></div></div>
</div>
</div>
<script>
var seg = document.getElementById('seg');
var before = document.getElementById('view-before');
var after = document.getElementById('view-after');
var hint = document.getElementById('hint');
seg.addEventListener('click', function (e) {
var b = e.target.closest('button');
if (!b) return;
var v = b.getAttribute('data-v');
seg.querySelectorAll('button').forEach(function (x) { x.classList.toggle('on', x === b); });
before.classList.toggle('hide', v !== 'before');
after.classList.toggle('hide', v !== 'after');
hint.textContent = v === 'before' ? '红/橙标记 = 缺陷位置' : '绿色标记 = 改版要点';
});
</script>
</body>
</html>