- 新增壁纸图库相关组件(WallpaperGalleryView/WallpaperSearchBar等) - 优化编辑器主题服务和系统UI管理 - 新增虚线边框和拖拽描边风格支持 - 完善今日诗词服务和阅读报告功能 - 修复多个UI问题和空指针异常 - 更新依赖库版本和SVG资源 - 优化交互动画和状态管理 - 补充文档和API测试脚本
1116 lines
31 KiB
HTML
1116 lines
31 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||
<title>编辑器底部工具栏 — iOS 26 设计方案</title>
|
||
<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=SF+Pro+Display:wght@300;400;500;600;700&display=swap');
|
||
|
||
:root {
|
||
--bg-primary: #1C1C1E;
|
||
--bg-glass: rgba(28, 28, 30, 0.88);
|
||
--bg-glass-deep: rgba(28, 28, 30, 0.95);
|
||
--border-subtle: rgba(255, 255, 255, 0.06);
|
||
--border-light: rgba(255, 255, 255, 0.12);
|
||
--text-primary: rgba(255, 255, 255, 0.85);
|
||
--text-secondary: rgba(255, 255, 255, 0.50);
|
||
--text-tertiary: rgba(255, 255, 255, 0.30);
|
||
--accent: #40C4FF;
|
||
--accent-deep: #0091EA;
|
||
--accent-glow: rgba(64, 196, 255, 0.25);
|
||
--accent-gradient-start: #00B0FF;
|
||
--accent-gradient-end: #40C4FF;
|
||
--radius-lg: 16px;
|
||
--radius-md: 12px;
|
||
--radius-sm: 8px;
|
||
--safe-bottom: 34px;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
|
||
|
||
body {
|
||
font-family: -apple-system, 'SF Pro Display', 'Helvetica Neue', sans-serif;
|
||
background: #000;
|
||
color: var(--text-primary);
|
||
overflow: hidden;
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.phone-frame {
|
||
width: 393px;
|
||
height: 852px;
|
||
margin: auto;
|
||
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
|
||
border-radius: 44px;
|
||
overflow: hidden;
|
||
position: relative;
|
||
box-shadow: 0 0 0 3px #333, 0 0 0 6px #1a1a1a, 0 30px 80px rgba(0,0,0,0.6);
|
||
}
|
||
|
||
.editor-canvas {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.editor-canvas-text {
|
||
color: rgba(255,255,255,0.15);
|
||
font-size: 48px;
|
||
font-weight: 700;
|
||
letter-spacing: -1px;
|
||
}
|
||
|
||
/* ─── 方案标签 ─── */
|
||
.scheme-tabs {
|
||
position: absolute;
|
||
top: 60px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
display: flex;
|
||
gap: 8px;
|
||
z-index: 100;
|
||
}
|
||
|
||
.scheme-tab {
|
||
padding: 6px 16px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
border: 1px solid var(--border-light);
|
||
background: rgba(28, 28, 30, 0.7);
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.scheme-tab.active {
|
||
background: var(--accent);
|
||
color: #fff;
|
||
border-color: var(--accent);
|
||
box-shadow: 0 2px 12px var(--accent-glow);
|
||
}
|
||
|
||
/* ─── 底部工具栏容器 ─── */
|
||
.bottom-toolbar {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 50;
|
||
transition: transform 0.4s cubic-bezier(0.32, 0.72, 0, 1);
|
||
}
|
||
|
||
.toolbar-glass {
|
||
background: var(--bg-glass);
|
||
backdrop-filter: blur(50px) saturate(180%);
|
||
-webkit-backdrop-filter: blur(50px) saturate(180%);
|
||
border-top: 0.5px solid var(--border-subtle);
|
||
}
|
||
|
||
/* ─── 方案A: 滑动工具栏 + 紧凑状态行 ─── */
|
||
.scheme-a .tool-scroll-area {
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
scroll-snap-type: x mandatory;
|
||
-webkit-overflow-scrolling: touch;
|
||
scrollbar-width: none;
|
||
padding: 6px 8px 4px;
|
||
}
|
||
|
||
.scheme-a .tool-scroll-area::-webkit-scrollbar { display: none; }
|
||
|
||
.scheme-a .tool-track {
|
||
display: flex;
|
||
gap: 4px;
|
||
align-items: flex-end;
|
||
padding: 0 4px;
|
||
}
|
||
|
||
.scheme-a .tool-btn {
|
||
flex-shrink: 0;
|
||
width: 56px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 3px;
|
||
padding: 8px 4px 6px;
|
||
border-radius: var(--radius-md);
|
||
cursor: pointer;
|
||
transition: all 0.25s cubic-bezier(0.32, 0.72, 0, 1);
|
||
position: relative;
|
||
scroll-snap-align: start;
|
||
}
|
||
|
||
.scheme-a .tool-btn:active {
|
||
transform: scale(0.88);
|
||
}
|
||
|
||
.scheme-a .tool-btn:hover {
|
||
background: rgba(255, 255, 255, 0.06);
|
||
}
|
||
|
||
.scheme-a .tool-btn .emoji {
|
||
font-size: 24px;
|
||
line-height: 1;
|
||
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3));
|
||
}
|
||
|
||
.scheme-a .tool-btn:active .emoji {
|
||
transform: scale(1.25);
|
||
}
|
||
|
||
.scheme-a .tool-btn .label {
|
||
font-size: 9px;
|
||
font-weight: 500;
|
||
color: var(--text-secondary);
|
||
letter-spacing: 0.2px;
|
||
}
|
||
|
||
.scheme-a .tool-btn.active .label {
|
||
color: var(--accent);
|
||
}
|
||
|
||
.scheme-a .tool-btn.active::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 2px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 4px;
|
||
height: 4px;
|
||
border-radius: 50%;
|
||
background: var(--accent);
|
||
box-shadow: 0 0 6px var(--accent-glow);
|
||
}
|
||
|
||
.scheme-a .tool-btn.toolbox-btn {
|
||
width: 60px;
|
||
padding: 6px;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.scheme-a .tool-btn.toolbox-btn .emoji {
|
||
font-size: 28px;
|
||
}
|
||
|
||
.scheme-a .tool-btn.toolbox-btn .toolbox-ring {
|
||
position: absolute;
|
||
inset: 2px;
|
||
border-radius: 16px;
|
||
border: 1.5px solid transparent;
|
||
background: linear-gradient(135deg, var(--accent-gradient-start), var(--accent-gradient-end)) border-box;
|
||
-webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
|
||
mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
|
||
-webkit-mask-composite: xor;
|
||
mask-composite: exclude;
|
||
opacity: 0.7;
|
||
}
|
||
|
||
/* 方案A 状态行 */
|
||
.scheme-a .status-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 4px 16px 2px;
|
||
border-top: 0.5px solid var(--border-subtle);
|
||
min-height: 26px;
|
||
}
|
||
|
||
.scheme-a .status-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
font-size: 10px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.scheme-a .status-center {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 10px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.scheme-a .status-center .version-tag {
|
||
font-weight: 600;
|
||
letter-spacing: 0.8px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.scheme-a .status-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.scheme-a .panel-toggle {
|
||
width: 28px;
|
||
height: 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 6px;
|
||
font-size: 12px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.scheme-a .panel-toggle.active {
|
||
background: rgba(64, 196, 255, 0.1);
|
||
color: var(--accent);
|
||
border: 0.5px solid rgba(64, 196, 255, 0.2);
|
||
}
|
||
|
||
.scheme-a .home-indicator {
|
||
width: 134px;
|
||
height: 5px;
|
||
margin: 4px auto 6px;
|
||
border-radius: 3px;
|
||
background: rgba(255, 255, 255, 0.15);
|
||
}
|
||
|
||
/* ─── 方案B: 分页滑动 + 浮动工具箱 ─── */
|
||
.scheme-b .tool-pages {
|
||
position: relative;
|
||
overflow: hidden;
|
||
padding: 8px 0 4px;
|
||
}
|
||
|
||
.scheme-b .tool-page {
|
||
display: none;
|
||
padding: 0 12px;
|
||
}
|
||
|
||
.scheme-b .tool-page.active {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: flex-end;
|
||
animation: pageSlideIn 0.35s cubic-bezier(0.32, 0.72, 0, 1);
|
||
}
|
||
|
||
@keyframes pageSlideIn {
|
||
from { transform: translateX(40px); opacity: 0; }
|
||
to { transform: translateX(0); opacity: 1; }
|
||
}
|
||
|
||
.scheme-b .tool-btn {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 4px;
|
||
padding: 10px 8px 8px;
|
||
border-radius: var(--radius-md);
|
||
cursor: pointer;
|
||
transition: all 0.25s cubic-bezier(0.32, 0.72, 0, 1);
|
||
position: relative;
|
||
min-width: 52px;
|
||
}
|
||
|
||
.scheme-b .tool-btn:active {
|
||
transform: scale(0.85);
|
||
}
|
||
|
||
.scheme-b .tool-btn .emoji {
|
||
font-size: 26px;
|
||
line-height: 1;
|
||
transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
filter: drop-shadow(0 2px 6px rgba(0,0,0,0.4));
|
||
}
|
||
|
||
.scheme-b .tool-btn:active .emoji {
|
||
transform: scale(1.3) translateY(-2px);
|
||
}
|
||
|
||
.scheme-b .tool-btn .label {
|
||
font-size: 9px;
|
||
font-weight: 500;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.scheme-b .tool-btn.active .label {
|
||
color: var(--accent);
|
||
}
|
||
|
||
.scheme-b .tool-btn.active::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 3px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 5px;
|
||
height: 5px;
|
||
border-radius: 50%;
|
||
background: var(--accent);
|
||
box-shadow: 0 0 8px var(--accent-glow);
|
||
}
|
||
|
||
.scheme-b .page-dots {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
padding: 4px 0;
|
||
}
|
||
|
||
.scheme-b .page-dot {
|
||
width: 6px;
|
||
height: 6px;
|
||
border-radius: 3px;
|
||
background: var(--text-tertiary);
|
||
transition: all 0.3s;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.scheme-b .page-dot.active {
|
||
width: 18px;
|
||
background: var(--accent);
|
||
box-shadow: 0 0 8px var(--accent-glow);
|
||
}
|
||
|
||
/* 方案B 浮动工具箱按钮 */
|
||
.scheme-b .floating-toolbox {
|
||
position: absolute;
|
||
bottom: 90px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 56px;
|
||
height: 56px;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, var(--accent-gradient-start), var(--accent-gradient-end));
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 26px;
|
||
cursor: pointer;
|
||
box-shadow: 0 4px 20px var(--accent-glow), 0 0 40px rgba(64, 196, 255, 0.1);
|
||
transition: all 0.3s cubic-bezier(0.32, 0.72, 0, 1);
|
||
z-index: 60;
|
||
}
|
||
|
||
.scheme-b .floating-toolbox:active {
|
||
transform: translateX(-50%) scale(0.9);
|
||
}
|
||
|
||
.scheme-b .floating-toolbox:hover {
|
||
box-shadow: 0 6px 30px rgba(64, 196, 255, 0.4), 0 0 60px rgba(64, 196, 255, 0.15);
|
||
}
|
||
|
||
/* 方案B 状态行 */
|
||
.scheme-b .status-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 4px 16px 2px;
|
||
border-top: 0.5px solid var(--border-subtle);
|
||
min-height: 26px;
|
||
}
|
||
|
||
.scheme-b .status-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
font-size: 10px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.scheme-b .status-center {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 10px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.scheme-b .status-center .version-tag {
|
||
font-weight: 600;
|
||
letter-spacing: 0.8px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.scheme-b .status-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.scheme-b .panel-toggle {
|
||
width: 28px;
|
||
height: 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 6px;
|
||
font-size: 12px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.scheme-b .panel-toggle.active {
|
||
background: rgba(64, 196, 255, 0.1);
|
||
color: var(--accent);
|
||
border: 0.5px solid rgba(64, 196, 255, 0.2);
|
||
}
|
||
|
||
.scheme-b .home-indicator {
|
||
width: 134px;
|
||
height: 5px;
|
||
margin: 4px auto 6px;
|
||
border-radius: 3px;
|
||
background: rgba(255, 255, 255, 0.15);
|
||
}
|
||
|
||
/* ─── 方案C: 伸缩面板 + 弹性按钮 ─── */
|
||
.scheme-c .tool-area {
|
||
padding: 8px 8px 4px;
|
||
}
|
||
|
||
.scheme-c .tool-row {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
}
|
||
|
||
.scheme-c .tool-btn {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 3px;
|
||
padding: 8px 6px 6px;
|
||
border-radius: var(--radius-md);
|
||
cursor: pointer;
|
||
transition: all 0.3s cubic-bezier(0.32, 0.72, 0, 1);
|
||
position: relative;
|
||
min-width: 44px;
|
||
}
|
||
|
||
.scheme-c .tool-btn:active {
|
||
transform: scale(0.82);
|
||
}
|
||
|
||
.scheme-c .tool-btn .emoji {
|
||
font-size: 22px;
|
||
line-height: 1;
|
||
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3));
|
||
}
|
||
|
||
.scheme-c .tool-btn:active .emoji {
|
||
transform: scale(1.35) translateY(-3px);
|
||
}
|
||
|
||
.scheme-c .tool-btn .label {
|
||
font-size: 9px;
|
||
font-weight: 500;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.scheme-c .tool-btn.active .label {
|
||
color: var(--accent);
|
||
}
|
||
|
||
.scheme-c .tool-btn.active::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 1px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 4px;
|
||
height: 4px;
|
||
border-radius: 50%;
|
||
background: var(--accent);
|
||
box-shadow: 0 0 6px var(--accent-glow);
|
||
}
|
||
|
||
.scheme-c .tool-btn.toolbox-btn {
|
||
position: relative;
|
||
}
|
||
|
||
.scheme-c .tool-btn.toolbox-btn .emoji {
|
||
font-size: 24px;
|
||
}
|
||
|
||
.scheme-c .tool-btn.toolbox-btn .toolbox-bg {
|
||
position: absolute;
|
||
inset: 4px;
|
||
border-radius: 14px;
|
||
background: linear-gradient(135deg, rgba(0, 176, 255, 0.15), rgba(64, 196, 255, 0.08));
|
||
border: 1px solid rgba(64, 196, 255, 0.2);
|
||
}
|
||
|
||
/* 方案C 分隔线 */
|
||
.scheme-c .divider-line {
|
||
height: 0.5px;
|
||
background: var(--border-subtle);
|
||
margin: 0 16px;
|
||
}
|
||
|
||
/* 方案C 状态行 — 更紧凑 */
|
||
.scheme-c .status-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 5px 16px 3px;
|
||
min-height: 24px;
|
||
gap: 8px;
|
||
}
|
||
|
||
.scheme-c .status-bar .info-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
font-size: 10px;
|
||
color: var(--text-tertiary);
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
background: rgba(255, 255, 255, 0.04);
|
||
}
|
||
|
||
.scheme-c .status-bar .version-chip {
|
||
font-weight: 600;
|
||
letter-spacing: 0.6px;
|
||
color: var(--text-secondary);
|
||
background: rgba(64, 196, 255, 0.06);
|
||
border: 0.5px solid rgba(64, 196, 255, 0.1);
|
||
}
|
||
|
||
.scheme-c .status-bar .spacer { flex: 1; }
|
||
|
||
.scheme-c .panel-toggle {
|
||
width: 26px;
|
||
height: 22px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 5px;
|
||
font-size: 11px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.scheme-c .panel-toggle.active {
|
||
background: rgba(64, 196, 255, 0.1);
|
||
color: var(--accent);
|
||
}
|
||
|
||
.scheme-c .home-indicator {
|
||
width: 134px;
|
||
height: 5px;
|
||
margin: 3px auto 5px;
|
||
border-radius: 3px;
|
||
background: rgba(255, 255, 255, 0.15);
|
||
}
|
||
|
||
/* ─── 滑动提示动画 ─── */
|
||
.scroll-hint {
|
||
position: absolute;
|
||
right: 8px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 2px;
|
||
opacity: 0;
|
||
animation: hintPulse 2s ease-in-out 1s 3;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.scroll-hint .arrow {
|
||
font-size: 10px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
@keyframes hintPulse {
|
||
0%, 100% { opacity: 0; transform: translateY(-50%) translateX(0); }
|
||
50% { opacity: 0.6; transform: translateY(-50%) translateX(4px); }
|
||
}
|
||
|
||
/* ─── 滑动渐隐遮罩 ─── */
|
||
.scroll-fade-right {
|
||
position: absolute;
|
||
right: 0;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 40px;
|
||
background: linear-gradient(to right, transparent, var(--bg-glass));
|
||
pointer-events: none;
|
||
z-index: 2;
|
||
transition: opacity 0.3s;
|
||
}
|
||
|
||
/* ─── 交互提示 ─── */
|
||
.interaction-hint {
|
||
position: absolute;
|
||
top: 110px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
font-size: 11px;
|
||
color: var(--text-tertiary);
|
||
background: rgba(28, 28, 30, 0.7);
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
padding: 6px 14px;
|
||
border-radius: 12px;
|
||
border: 0.5px solid var(--border-subtle);
|
||
white-space: nowrap;
|
||
z-index: 100;
|
||
}
|
||
|
||
/* ─── 方案说明卡片 ─── */
|
||
.scheme-desc {
|
||
position: absolute;
|
||
top: 140px;
|
||
left: 16px;
|
||
right: 16px;
|
||
padding: 12px 16px;
|
||
background: rgba(28, 28, 30, 0.7);
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
border-radius: var(--radius-md);
|
||
border: 0.5px solid var(--border-subtle);
|
||
z-index: 100;
|
||
display: none;
|
||
}
|
||
|
||
.scheme-desc.visible { display: block; }
|
||
|
||
.scheme-desc h3 {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.scheme-desc p {
|
||
font-size: 11px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.scheme-desc .feature-list {
|
||
list-style: none;
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.scheme-desc .feature-list li {
|
||
font-size: 11px;
|
||
color: var(--text-secondary);
|
||
padding: 2px 0;
|
||
}
|
||
|
||
.scheme-desc .feature-list li::before {
|
||
content: '✦ ';
|
||
color: var(--accent);
|
||
}
|
||
|
||
/* ─── 按钮按下涟漪 ─── */
|
||
.ripple {
|
||
position: absolute;
|
||
border-radius: 50%;
|
||
background: rgba(64, 196, 255, 0.2);
|
||
transform: scale(0);
|
||
animation: rippleAnim 0.5s ease-out;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@keyframes rippleAnim {
|
||
to { transform: scale(2.5); opacity: 0; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="phone-frame" id="phone">
|
||
<div class="editor-canvas">
|
||
<div class="editor-canvas-text">编辑区域</div>
|
||
</div>
|
||
|
||
<div class="scheme-tabs">
|
||
<div class="scheme-tab active" data-scheme="a" onclick="switchScheme('a')">方案A 横滑</div>
|
||
<div class="scheme-tab" data-scheme="b" onclick="switchScheme('b')">方案B 分页</div>
|
||
<div class="scheme-tab" data-scheme="c" onclick="switchScheme('c')">方案C 紧凑</div>
|
||
</div>
|
||
|
||
<div class="interaction-hint" id="hint">← 左右滑动工具栏试试 →</div>
|
||
|
||
<!-- 方案A: 横向滑动工具栏 -->
|
||
<div class="bottom-toolbar scheme-a" id="schemeA">
|
||
<div class="toolbar-glass">
|
||
<div class="tool-scroll-area" id="scrollAreaA">
|
||
<div class="tool-track">
|
||
<div class="tool-btn active" onclick="tapTool(this)">
|
||
<span class="emoji">🖌️</span>
|
||
<span class="label">画笔</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">📝</span>
|
||
<span class="label">文字</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">✂️</span>
|
||
<span class="label">裁剪</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎨</span>
|
||
<span class="label">色调</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🔍</span>
|
||
<span class="label">滤镜</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🌫️</span>
|
||
<span class="label">模糊</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">😀</span>
|
||
<span class="label">表情</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎭</span>
|
||
<span class="label">贴纸</span>
|
||
</div>
|
||
<div class="tool-btn toolbox-btn" onclick="tapTool(this)">
|
||
<div class="toolbox-ring"></div>
|
||
<span class="emoji">🧰</span>
|
||
<span class="label">工具箱</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🖼️</span>
|
||
<span class="label">壁纸</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🌈</span>
|
||
<span class="label">渐变</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">💧</span>
|
||
<span class="label">水印</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">✨</span>
|
||
<span class="label">Shader</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="scroll-fade-right" id="fadeRight"></div>
|
||
<div class="status-bar">
|
||
<div class="status-left">
|
||
<span>🖼️</span>
|
||
<span>PNG · 1080×1920</span>
|
||
</div>
|
||
<div class="status-center">
|
||
<span class="version-tag">xycard 1.0</span>
|
||
<span style="color:var(--text-tertiary)">ℹ️</span>
|
||
</div>
|
||
<div class="status-right">
|
||
<div class="panel-toggle active" onclick="togglePanel(this)">📍</div>
|
||
<div class="panel-toggle" onclick="togglePanel(this)">⏳</div>
|
||
</div>
|
||
</div>
|
||
<div class="home-indicator"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 方案B: 分页滑动 + 浮动工具箱 -->
|
||
<div class="bottom-toolbar scheme-b" id="schemeB" style="display:none">
|
||
<div class="floating-toolbox" onclick="alert('打开工具箱')">🧰</div>
|
||
<div class="toolbar-glass">
|
||
<div class="tool-pages">
|
||
<div class="tool-page active" id="page1">
|
||
<div class="tool-btn active" onclick="tapTool(this)">
|
||
<span class="emoji">🖌️</span>
|
||
<span class="label">画笔</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">📝</span>
|
||
<span class="label">文字</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">✂️</span>
|
||
<span class="label">裁剪</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎨</span>
|
||
<span class="label">色调</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🔍</span>
|
||
<span class="label">滤镜</span>
|
||
</div>
|
||
</div>
|
||
<div class="tool-page" id="page2">
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🌫️</span>
|
||
<span class="label">模糊</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">😀</span>
|
||
<span class="label">表情</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎭</span>
|
||
<span class="label">贴纸</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🖼️</span>
|
||
<span class="label">壁纸</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🌈</span>
|
||
<span class="label">渐变</span>
|
||
</div>
|
||
</div>
|
||
<div class="tool-page" id="page3">
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">💧</span>
|
||
<span class="label">水印</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">✨</span>
|
||
<span class="label">Shader</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">📐</span>
|
||
<span class="label">画布</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎯</span>
|
||
<span class="label">取色</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎨</span>
|
||
<span class="label">主题</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="page-dots">
|
||
<div class="page-dot active" onclick="switchPage(0)"></div>
|
||
<div class="page-dot" onclick="switchPage(1)"></div>
|
||
<div class="page-dot" onclick="switchPage(2)"></div>
|
||
</div>
|
||
<div class="status-bar">
|
||
<div class="status-left">
|
||
<span>🖼️</span>
|
||
<span>PNG · 1080×1920</span>
|
||
</div>
|
||
<div class="status-center">
|
||
<span class="version-tag">xycard 1.0</span>
|
||
<span style="color:var(--text-tertiary)">ℹ️</span>
|
||
</div>
|
||
<div class="status-right">
|
||
<div class="panel-toggle active" onclick="togglePanel(this)">📍</div>
|
||
<div class="panel-toggle" onclick="togglePanel(this)">⏳</div>
|
||
</div>
|
||
</div>
|
||
<div class="home-indicator"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 方案C: 紧凑一行 + 状态行合并 -->
|
||
<div class="bottom-toolbar scheme-c" id="schemeC" style="display:none">
|
||
<div class="toolbar-glass">
|
||
<div class="tool-area">
|
||
<div class="tool-row">
|
||
<div class="tool-btn active" onclick="tapTool(this)">
|
||
<span class="emoji">🖌️</span>
|
||
<span class="label">画笔</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">📝</span>
|
||
<span class="label">文字</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">✂️</span>
|
||
<span class="label">裁剪</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎨</span>
|
||
<span class="label">色调</span>
|
||
</div>
|
||
<div class="tool-btn toolbox-btn" onclick="tapTool(this)">
|
||
<div class="toolbox-bg"></div>
|
||
<span class="emoji">🧰</span>
|
||
<span class="label">工具箱</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🔍</span>
|
||
<span class="label">滤镜</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🌫️</span>
|
||
<span class="label">模糊</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">😀</span>
|
||
<span class="label">表情</span>
|
||
</div>
|
||
<div class="tool-btn" onclick="tapTool(this)">
|
||
<span class="emoji">🎭</span>
|
||
<span class="label">贴纸</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="divider-line"></div>
|
||
<div class="status-bar">
|
||
<span class="info-chip">🖼️ PNG · 1080×1920</span>
|
||
<span class="info-chip version-chip">xycard 1.0</span>
|
||
<span class="spacer"></span>
|
||
<div class="panel-toggle active" onclick="togglePanel(this)">📍</div>
|
||
<div class="panel-toggle" onclick="togglePanel(this)">⏳</div>
|
||
</div>
|
||
<div class="home-indicator"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 方案说明 -->
|
||
<div class="scheme-desc visible" id="descA">
|
||
<h3>方案A — 横向滑动工具栏</h3>
|
||
<p>所有工具一字排开,支持横向滑动浏览,工具箱内嵌在滑动列表中</p>
|
||
<ul class="feature-list">
|
||
<li>横向自由滑动,scroll-snap 对齐</li>
|
||
<li>右侧渐隐遮罩提示可滑动</li>
|
||
<li>工具箱按钮带渐变边框环</li>
|
||
<li>状态行紧凑:图片信息 | xycard 1.0 | 面板开关</li>
|
||
<li>无多余空白,home-indicator 紧贴底部</li>
|
||
</ul>
|
||
</div>
|
||
<div class="scheme-desc" id="descB">
|
||
<h3>方案B — 分页滑动 + 浮动工具箱</h3>
|
||
<p>工具分3页,左右滑动切换,工具箱浮动在工具栏上方</p>
|
||
<ul class="feature-list">
|
||
<li>3页分页:核心工具 / 效果工具 / 高级工具</li>
|
||
<li>分页指示器 (圆点)</li>
|
||
<li>工具箱浮动按钮,渐变光晕</li>
|
||
<li>每页5个按钮,尺寸更大更突出</li>
|
||
<li>页面切换带滑入动画</li>
|
||
</ul>
|
||
</div>
|
||
<div class="scheme-desc" id="descC">
|
||
<h3>方案C — 紧凑一行 + 芯片状态行</h3>
|
||
<p>9个工具一行排列(含工具箱),状态行用芯片样式紧凑展示</p>
|
||
<ul class="feature-list">
|
||
<li>一行展示所有核心工具 + 工具箱</li>
|
||
<li>工具箱带半透明渐变背景</li>
|
||
<li>状态行用 chip 样式,更紧凑</li>
|
||
<li>分割线分隔工具区和状态区</li>
|
||
<li>整体高度最矮,编辑区域最大化</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
let currentScheme = 'a';
|
||
let currentPage = 0;
|
||
|
||
function switchScheme(scheme) {
|
||
currentScheme = scheme;
|
||
document.querySelectorAll('.scheme-tab').forEach(t => t.classList.remove('active'));
|
||
document.querySelector(`[data-scheme="${scheme}"]`).classList.add('active');
|
||
|
||
document.getElementById('schemeA').style.display = scheme === 'a' ? '' : 'none';
|
||
document.getElementById('schemeB').style.display = scheme === 'b' ? '' : 'none';
|
||
document.getElementById('schemeC').style.display = scheme === 'c' ? '' : 'none';
|
||
|
||
document.getElementById('descA').classList.toggle('visible', scheme === 'a');
|
||
document.getElementById('descB').classList.toggle('visible', scheme === 'b');
|
||
document.getElementById('descC').classList.toggle('visible', scheme === 'c');
|
||
|
||
const hints = {
|
||
a: '← 左右滑动工具栏试试 →',
|
||
b: '← 滑动切换分页 · 点击浮动🧰 →',
|
||
c: '9个工具一行排列 · 点击试试'
|
||
};
|
||
document.getElementById('hint').textContent = hints[scheme];
|
||
}
|
||
|
||
function tapTool(el) {
|
||
const parent = el.closest('.tool-track, .tool-page, .tool-row');
|
||
if (parent) {
|
||
parent.querySelectorAll('.tool-btn').forEach(b => b.classList.remove('active'));
|
||
}
|
||
el.classList.add('active');
|
||
|
||
const ripple = document.createElement('div');
|
||
ripple.className = 'ripple';
|
||
const rect = el.getBoundingClientRect();
|
||
const size = Math.max(rect.width, rect.height);
|
||
ripple.style.width = ripple.style.height = size + 'px';
|
||
ripple.style.left = (rect.width / 2 - size / 2) + 'px';
|
||
ripple.style.top = (rect.height / 2 - size / 2) + 'px';
|
||
el.style.position = 'relative';
|
||
el.style.overflow = 'hidden';
|
||
el.appendChild(ripple);
|
||
setTimeout(() => ripple.remove(), 500);
|
||
}
|
||
|
||
function togglePanel(el) {
|
||
el.classList.toggle('active');
|
||
}
|
||
|
||
function switchPage(idx) {
|
||
currentPage = idx;
|
||
document.querySelectorAll('.tool-page').forEach((p, i) => {
|
||
p.classList.toggle('active', i === idx);
|
||
});
|
||
document.querySelectorAll('.page-dot').forEach((d, i) => {
|
||
d.classList.toggle('active', i === idx);
|
||
});
|
||
}
|
||
|
||
// 方案B: 支持滑动切换分页
|
||
let touchStartX = 0;
|
||
let touchEndX = 0;
|
||
|
||
const schemeBEl = document.getElementById('schemeB');
|
||
schemeBEl.addEventListener('touchstart', e => {
|
||
touchStartX = e.changedTouches[0].screenX;
|
||
}, { passive: true });
|
||
|
||
schemeBEl.addEventListener('touchend', e => {
|
||
touchEndX = e.changedTouches[0].screenX;
|
||
const diff = touchStartX - touchEndX;
|
||
if (Math.abs(diff) > 40) {
|
||
if (diff > 0 && currentPage < 2) switchPage(currentPage + 1);
|
||
else if (diff < 0 && currentPage > 0) switchPage(currentPage - 1);
|
||
}
|
||
}, { passive: true });
|
||
|
||
// 方案A: 滑动渐隐遮罩
|
||
const scrollArea = document.getElementById('scrollAreaA');
|
||
const fadeRight = document.getElementById('fadeRight');
|
||
|
||
function updateFade() {
|
||
if (!scrollArea || !fadeRight) return;
|
||
const maxScroll = scrollArea.scrollWidth - scrollArea.clientWidth;
|
||
const atEnd = scrollArea.scrollLeft >= maxScroll - 10;
|
||
fadeRight.style.opacity = atEnd ? '0' : '1';
|
||
}
|
||
|
||
if (scrollArea) {
|
||
scrollArea.addEventListener('scroll', updateFade, { passive: true });
|
||
setTimeout(updateFade, 100);
|
||
}
|
||
|
||
// 自动隐藏提示
|
||
setTimeout(() => {
|
||
const hint = document.getElementById('hint');
|
||
if (hint) hint.style.transition = 'opacity 0.5s';
|
||
if (hint) hint.style.opacity = '0';
|
||
setTimeout(() => { if (hint) hint.style.display = 'none'; }, 500);
|
||
}, 5000);
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|