Files
xianyan/docs/preview/widescreen-nav-options.html
Developer 5a49d20c8a chore: 完成项目品牌域名批量替换与功能迭代
本次提交包含多项核心更新:
1. 全量替换项目内所有xianyan.app域名变更为s2ss.com,包含配置文件、路由、隐私政策等
2. 重构图表库从fl_chart迁移至syncfusion_flutter_charts,优化图表渲染效果
3. 新增宽屏分屏布局支持,包含右侧面板注册表与可拖拽分割线
4. 完善触觉反馈服务与认证感知Mixin,修复多处内存泄漏问题
5. 合并勋章墙与金币记录入口至成就中心,简化个人中心导航
6. 新增收藏与时间线数据合并导入功能
7. 修复多处UI样式问题,统一主题颜色使用规范
8. 新增日历同步与跨平台触觉反馈依赖库
9. 修复BotToast初始化流程,避免路由切换时的弹窗崩溃
2026-05-29 10:06:55 +08:00

635 lines
17 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=1440">
<title>闲言 - 导航栏停靠位置选项</title>
<style>
:root {
--primary: #007AFF;
--primary-light: rgba(0,122,255,0.12);
--secondary: #5856D6;
--background: #FAFAFA;
--surface: #FFFFFF;
--surface-secondary: #F2F2F7;
--text: #1C1C1E;
--text-secondary: #8E8E93;
--text-tertiary: #AEAEB2;
--separator: rgba(60,60,67,0.12);
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--space-1: 4px;
--space-2: 8px;
--space-3: 16px;
--space-4: 24px;
--space-5: 32px;
--font-family: -apple-system, system-ui, 'SF Pro Display', 'Segoe UI', sans-serif;
--glass-bg: rgba(255,255,255,0.72);
--glass-blur: 20px;
--card-bg: rgba(255,255,255,0.8);
--red: #FF3B30;
--orange: #FF9500;
--green: #34C759;
--teal: #5AC8FA;
--nav-w: 72px;
--nav-h: 64px;
}
[data-theme="dark"] {
--background: #1A1A2E;
--surface: #16213E;
--surface-secondary: #0F3460;
--text: #F5F5F7;
--text-secondary: #98989D;
--text-tertiary: #636366;
--separator: rgba(84,84,88,0.65);
--glass-bg: rgba(30,30,50,0.72);
--card-bg: rgba(30,30,50,0.8);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: var(--font-family);
background: var(--background);
color: var(--text);
height: 100vh;
overflow: hidden;
transition: background 0.3s, color 0.3s;
}
.page-layout {
display: flex;
height: 100vh;
width: 100%;
}
.control-panel {
width: 320px;
min-width: 320px;
background: var(--surface);
border-right: 1px solid var(--separator);
display: flex;
flex-direction: column;
overflow-y: auto;
padding: var(--space-4);
}
.control-title {
font-size: 24px;
font-weight: 700;
margin-bottom: var(--space-2);
}
.control-subtitle {
font-size: 13px;
color: var(--text-secondary);
margin-bottom: var(--space-5);
}
.control-section {
margin-bottom: var(--space-5);
}
.control-label {
font-size: 13px;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: var(--space-3);
}
.position-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-2);
}
.position-btn {
padding: var(--space-3);
border-radius: var(--radius-xl);
border: 2px solid var(--separator);
background: var(--surface);
color: var(--text);
font-family: var(--font-family);
font-size: 14px;
font-weight: 500;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-1);
transition: all 0.25s ease;
}
.position-btn:hover { border-color: var(--primary); background: var(--primary-light); }
.position-btn.active {
border-color: var(--primary);
background: var(--primary-light);
color: var(--primary);
box-shadow: 0 0 0 3px rgba(0,122,255,0.15);
}
.position-btn .pos-icon { font-size: 24px; }
.position-btn .pos-label { font-size: 12px; }
.theme-toggle-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-3);
background: var(--card-bg);
border-radius: var(--radius-xl);
border: 1px solid var(--separator);
}
.toggle-switch {
width: 51px; height: 31px;
border-radius: 16px;
background: var(--surface-secondary);
border: 1px solid var(--separator);
position: relative; cursor: pointer;
transition: all 0.3s;
}
.toggle-switch.on { background: var(--green); border-color: var(--green); }
.toggle-switch::after {
content: '';
width: 27px; height: 27px;
border-radius: 50%;
background: #fff;
position: absolute; top: 1px; left: 1px;
transition: transform 0.3s;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.toggle-switch.on::after { transform: translateX(20px); }
.info-card {
background: var(--primary-light);
border-radius: var(--radius-xl);
padding: var(--space-3);
border: 1px solid rgba(0,122,255,0.2);
margin-top: var(--space-3);
}
.info-card-title {
font-size: 13px;
font-weight: 600;
color: var(--primary);
margin-bottom: var(--space-1);
}
.info-card-text {
font-size: 12px;
color: var(--text-secondary);
line-height: 1.5;
}
.preview-area {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: var(--space-5);
background: var(--background);
position: relative;
}
.device-frame {
width: 100%;
max-width: 960px;
height: 600px;
background: var(--surface);
border-radius: var(--radius-xl);
border: 1px solid var(--separator);
overflow: hidden;
box-shadow: var(--shadow-lg);
position: relative;
display: flex;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.device-frame.nav-left { flex-direction: row; }
.device-frame.nav-right { flex-direction: row-reverse; }
.device-frame.nav-top { flex-direction: column; }
.device-frame.nav-bottom { flex-direction: column-reverse; }
.nav-bar {
background: var(--glass-bg);
backdrop-filter: blur(var(--glass-blur));
-webkit-backdrop-filter: blur(var(--glass-blur));
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 5;
}
.nav-left .nav-bar,
.nav-right .nav-bar {
width: var(--nav-w);
flex-direction: column;
padding: var(--space-3) 0;
border-right: 1px solid var(--separator);
}
.nav-right .nav-bar {
border-right: none;
border-left: 1px solid var(--separator);
}
.nav-top .nav-bar,
.nav-bottom .nav-bar {
height: var(--nav-h);
flex-direction: row;
padding: 0 var(--space-4);
border-bottom: 1px solid var(--separator);
}
.nav-bottom .nav-bar {
border-bottom: none;
border-top: 1px solid var(--separator);
}
.nav-item {
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
cursor: pointer;
border-radius: var(--radius-lg);
transition: all 0.2s;
color: var(--text-secondary);
text-decoration: none;
position: relative;
}
.nav-left .nav-item,
.nav-right .nav-item {
width: 48px;
height: 48px;
flex-direction: column;
font-size: 9px;
}
.nav-top .nav-item,
.nav-bottom .nav-item {
height: 44px;
padding: 0 var(--space-3);
flex-direction: row;
font-size: 12px;
}
.nav-item .nav-icon { font-size: 20px; line-height: 1; }
.nav-item .nav-label { font-weight: 500; }
.nav-item:hover { background: var(--primary-light); color: var(--primary); }
.nav-item.active { background: var(--primary-light); color: var(--primary); }
.nav-left .nav-item.active::before,
.nav-right .nav-item.active::before {
content: '';
position: absolute;
width: 3px; height: 20px;
background: var(--primary);
border-radius: 0 2px 2px 0;
}
.nav-left .nav-item.active::before { left: -12px; }
.nav-right .nav-item.active::before { right: -12px; border-radius: 2px 0 0 2px; }
.nav-top .nav-item.active::after,
.nav-bottom .nav-item.active::after {
content: '';
position: absolute;
width: 20px; height: 3px;
background: var(--primary);
border-radius: 2px 2px 0 0;
}
.nav-top .nav-item.active::after { top: -10px; }
.nav-bottom .nav-item.active::after { bottom: -10px; border-radius: 0 0 2px 2px; }
.nav-logo {
display: flex; align-items: center; justify-content: center;
font-size: 20px; color: #fff;
border-radius: var(--radius-lg);
background: linear-gradient(135deg, var(--primary), var(--secondary));
box-shadow: var(--shadow-md);
transition: all 0.3s;
}
.nav-left .nav-logo,
.nav-right .nav-logo {
width: 40px; height: 40px;
margin-bottom: var(--space-3);
}
.nav-top .nav-logo,
.nav-bottom .nav-logo {
width: 36px; height: 36px;
margin-right: var(--space-4);
}
.nav-spacer { flex: 1; }
.content-area {
flex: 1;
display: flex;
background: var(--background);
overflow: hidden;
}
.master-view {
width: 40%;
min-width: 200px;
border-right: 1px solid var(--separator);
display: flex;
flex-direction: column;
overflow: hidden;
}
.master-header {
padding: var(--space-3) var(--space-4);
background: var(--glass-bg);
backdrop-filter: blur(var(--glass-blur));
border-bottom: 1px solid var(--separator);
}
.master-title { font-size: 20px; font-weight: 700; }
.item-list {
flex: 1;
overflow-y: auto;
padding: var(--space-2);
}
.list-item {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-3);
border-radius: var(--radius-lg);
cursor: pointer;
transition: background 0.15s;
margin-bottom: var(--space-1);
}
.list-item:hover { background: var(--primary-light); }
.list-item.selected { background: var(--primary-light); }
.list-item-icon {
width: 32px; height: 32px;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-size: 16px; color: #fff;
flex-shrink: 0;
}
.list-item-text { flex: 1; min-width: 0; }
.list-item-title { font-size: 14px; font-weight: 500; }
.list-item-subtitle { font-size: 11px; color: var(--text-secondary); }
.detail-view {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--space-4);
}
.detail-placeholder {
text-align: center;
color: var(--text-tertiary);
}
.detail-placeholder-icon { font-size: 48px; margin-bottom: var(--space-3); }
.detail-placeholder-text { font-size: 16px; font-weight: 500; }
.detail-placeholder-sub { font-size: 13px; margin-top: var(--space-1); }
.preview-badge {
position: absolute;
top: var(--space-3);
right: var(--space-3);
padding: var(--space-1) var(--space-3);
border-radius: 20px;
background: var(--glass-bg);
backdrop-filter: blur(var(--glass-blur));
border: 1px solid var(--separator);
font-size: 12px;
font-weight: 600;
color: var(--primary);
z-index: 10;
}
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--text-tertiary); border-radius: 3px; }
</style>
</head>
<body data-theme="light">
<div class="page-layout">
<div class="control-panel">
<div class="control-title">🧭 导航栏位置</div>
<div class="control-subtitle">选择导航栏的停靠位置,实时预览效果</div>
<div class="control-section">
<div class="control-label">停靠位置</div>
<div class="position-grid">
<button class="position-btn active" onclick="setNavPosition('left', this)">
<span class="pos-icon">⬅️</span>
<span class="pos-label">左侧</span>
</button>
<button class="position-btn" onclick="setNavPosition('right', this)">
<span class="pos-icon">➡️</span>
<span class="pos-label">右侧</span>
</button>
<button class="position-btn" onclick="setNavPosition('top', this)">
<span class="pos-icon">⬆️</span>
<span class="pos-label">顶部</span>
</button>
<button class="position-btn" onclick="setNavPosition('bottom', this)">
<span class="pos-icon">⬇️</span>
<span class="pos-label">底部</span>
</button>
</div>
</div>
<div class="control-section">
<div class="control-label">外观</div>
<div class="theme-toggle-row">
<div>
<div style="font-size:15px;font-weight:500">深色模式</div>
<div style="font-size:12px;color:var(--text-secondary)">切换浅色/深色主题</div>
</div>
<div class="toggle-switch" id="themeToggle" onclick="toggleTheme()"></div>
</div>
</div>
<div class="control-section">
<div class="control-label">毛玻璃效果</div>
<div class="theme-toggle-row">
<div>
<div style="font-size:15px;font-weight:500">启用毛玻璃</div>
<div style="font-size:12px;color:var(--text-secondary)">导航栏背景模糊效果</div>
</div>
<div class="toggle-switch on" id="glassToggle" onclick="toggleGlass()"></div>
</div>
</div>
<div class="info-card">
<div class="info-card-title">💡 提示</div>
<div class="info-card-text">
左侧导航适合宽屏桌面使用,顶部导航适合平板横屏,底部导航适合手机竖屏。导航栏位置可在通用设置中随时调整。
</div>
</div>
<div class="info-card" style="margin-top:12px">
<div class="info-card-title">📐 设计规范</div>
<div class="info-card-text">
垂直导航栏宽度72px<br>
水平导航栏高度64px<br>
导航项图标22px<br>
导航项标签9-12px<br>
激活指示器3px 宽/高
</div>
</div>
</div>
<div class="preview-area">
<div class="preview-badge" id="posBadge">← 左侧导航</div>
<div class="device-frame nav-left" id="deviceFrame">
<div class="nav-bar" id="navBar">
<div class="nav-logo">💬</div>
<a class="nav-item active">
<span class="nav-icon">💬</span>
<span class="nav-label">闲言</span>
</a>
<a class="nav-item">
<span class="nav-icon">🧭</span>
<span class="nav-label">发现</span>
</a>
<a class="nav-item">
<span class="nav-icon">👤</span>
<span class="nav-label">我的</span>
</a>
<div class="nav-spacer"></div>
</div>
<div class="content-area">
<div class="master-view">
<div class="master-header">
<div class="master-title">闲言</div>
</div>
<div class="item-list">
<div class="list-item selected">
<div class="list-item-icon" style="background:linear-gradient(135deg,#007AFF,#5856D6)">🌙</div>
<div class="list-item-text">
<div class="list-item-title">长风破浪会有时</div>
<div class="list-item-subtitle">李白 · 3分钟前</div>
</div>
</div>
<div class="list-item">
<div class="list-item-icon" style="background:linear-gradient(135deg,#FF9500,#FF3B30)">🍂</div>
<div class="list-item-text">
<div class="list-item-title">一蓑烟雨任平生</div>
<div class="list-item-subtitle">苏轼 · 15分钟前</div>
</div>
</div>
<div class="list-item">
<div class="list-item-icon" style="background:linear-gradient(135deg,#34C759,#007AFF)">🌿</div>
<div class="list-item-text">
<div class="list-item-title">行到水穷处</div>
<div class="list-item-subtitle">王维 · 1小时前</div>
</div>
</div>
<div class="list-item">
<div class="list-item-icon" style="background:linear-gradient(135deg,#5856D6,#FF2D55)">🌸</div>
<div class="list-item-text">
<div class="list-item-title">寻寻觅觅</div>
<div class="list-item-subtitle">李清照 · 2小时前</div>
</div>
</div>
</div>
</div>
<div class="detail-view">
<div class="detail-placeholder">
<div class="detail-placeholder-icon">📖</div>
<div class="detail-placeholder-text">选择一个句子查看详情</div>
<div class="detail-placeholder-sub">右侧面板将显示完整内容</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
let currentPos = 'left';
function setNavPosition(pos, btn) {
currentPos = pos;
const frame = document.getElementById('deviceFrame');
frame.className = 'device-frame nav-' + pos;
document.querySelectorAll('.position-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const labels = {
left: '← 左侧导航',
right: '→ 右侧导航',
top: '↑ 顶部导航',
bottom: '↓ 底部导航'
};
document.getElementById('posBadge').textContent = labels[pos];
}
function toggleTheme() {
const body = document.body;
const toggle = document.getElementById('themeToggle');
if (body.dataset.theme === 'light') {
body.dataset.theme = 'dark';
toggle.classList.add('on');
} else {
body.dataset.theme = 'light';
toggle.classList.remove('on');
}
}
function toggleGlass() {
const toggle = document.getElementById('glassToggle');
const navBar = document.getElementById('navBar');
toggle.classList.toggle('on');
if (toggle.classList.contains('on')) {
navBar.style.backdropFilter = 'blur(20px)';
navBar.style.webkitBackdropFilter = 'blur(20px)';
} else {
navBar.style.backdropFilter = 'none';
navBar.style.webkitBackdropFilter = 'none';
}
}
document.querySelectorAll('.list-item').forEach(item => {
item.addEventListener('click', () => {
document.querySelectorAll('.list-item').forEach(i => i.classList.remove('selected'));
item.classList.add('selected');
});
});
document.querySelectorAll('.nav-item').forEach(item => {
item.addEventListener('click', () => {
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
item.classList.add('active');
});
});
</script>
</body>
</html>