Files
SpineViewer/viewer/spine.css
T
2026-09-12 22:17:52 +08:00

252 lines
11 KiB
CSS
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.
:root {
--bg: #1e1e1e;
--panel: #252526;
--panel-2: #2d2d30;
--text: #e6e6e6;
--text-dim: #9d9d9d;
--accent: #4fc1ff;
--border: #3c3c3c;
--error: #f14c4c;
/* 悬浮层填充与滚动条配色。Eagle 内置 Electron 22 / Chromium 108 不支持 color-mix(),
这些必须写成 rgba(),否则整条颜色声明会被丢弃。 */
--hover-fill: rgba(255, 255, 255, .07);
--scroll-thumb: rgba(255, 255, 255, .34);
--scroll-thumb-hover: rgba(255, 255, 255, .55);
--scroll-thumb-active: rgba(255, 255, 255, .72);
--scroll-track: rgba(255, 255, 255, .07);
--panel-glass: rgba(37, 37, 38, .92); /* #toolbar / #animationPanel / #timelineBar 底色 */
--active-item-fill: rgb(45, 68, 81); /* .animation-item.active 底色 */
--list-thumb: rgba(157, 157, 157, .58); /* 动画列表滚动条,与预览区各自独立 */
--list-thumb-hover: rgba(157, 157, 157, .82);
}
[data-theme="light"] {
--bg: #f3f4f6;
--panel: #ffffff;
--panel-2: #f0f0f0;
--text: #1f1f1f;
--text-dim: #6b6b6b;
--accent: #0078d4;
--border: #ddd;
--error: #d13438;
--hover-fill: rgba(0, 0, 0, .06);
--scroll-thumb: rgba(0, 0, 0, .30);
--scroll-thumb-hover: rgba(0, 0, 0, .46);
--scroll-thumb-active: rgba(0, 0, 0, .62);
--scroll-track: rgba(0, 0, 0, .06);
--panel-glass: rgba(255, 255, 255, .92);
--active-item-fill: rgb(204, 228, 246);
--list-thumb: rgba(107, 107, 107, .58);
--list-thumb-hover: rgba(107, 107, 107, .82);
}
* {
box-sizing: border-box;
-webkit-user-select: none;
user-select: none;
}
html, body {
margin: 0; padding: 0; height: 100%; overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
background: var(--bg); color: var(--text);
font-size: 13px;
}
#app {
position: relative; height: 100%;
--toolbar-height: 46px; --timeline-height: 68px;
}
#toolbar {
position: absolute; top: 12px; left: 12px; right: 12px;
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
padding: 8px 12px;
background: var(--panel-glass);
border: 1px solid var(--border); border-radius: 8px;
box-shadow: 0 5px 18px rgba(0, 0, 0, .25);
backdrop-filter: blur(8px); z-index: 10;
}
#toolbar .spacer { flex: 1; }
#toolbar label { color: var(--text-dim); display: flex; align-items: center; gap: 4px; }
select, input[type="range"] {
background: var(--panel-2); color: var(--text);
border: 1px solid var(--border); border-radius: 4px; padding: 4px 6px;
}
button {
background: var(--panel-2); color: var(--text);
border: 1px solid var(--border); border-radius: 4px; padding: 5px 10px;
cursor: pointer; white-space: nowrap;
}
button:hover { background: var(--border); }
button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
#stage { position: absolute; inset: 0; display: flex; overflow: hidden; }
#animationPanel {
position: absolute;
top: calc(22px + var(--toolbar-height)); left: 12px; z-index: 9;
width: max-content; min-width: 128px; max-width: min(260px, 34vw);
max-height: calc(100% - var(--toolbar-height) - var(--timeline-height) - 56px);
display: none; flex-direction: column; overflow: hidden;
background: var(--panel-glass);
border: 1px solid var(--border); border-radius: 7px;
box-shadow: 0 5px 18px rgba(0, 0, 0, .28);
backdrop-filter: blur(8px);
}
#animationPanelTitle {
padding: 8px 10px; color: var(--text-dim); font-size: 12px;
border-bottom: 1px solid var(--border); flex: none;
}
#animationList {
width: max-content; min-width: 100%; max-width: 100%; min-height: 0;
overflow: auto; padding: 5px;
scrollbar-width: thin;
scrollbar-color: var(--list-thumb) transparent;
}
#animationList::-webkit-scrollbar { width: 8px; height: 8px; }
#animationList::-webkit-scrollbar-track { background: transparent; }
#animationList::-webkit-scrollbar-thumb {
min-height: 28px; border: 2px solid transparent; border-radius: 999px;
background: var(--list-thumb);
background-clip: padding-box;
}
#animationList::-webkit-scrollbar-thumb:hover {
background: var(--list-thumb-hover);
background-clip: padding-box;
}
#animationList::-webkit-scrollbar-corner { background: transparent; }
.animation-item {
display: block; width: 100%; min-width: 116px; max-width: 248px;
padding: 6px 8px; margin: 0 0 2px;
border: 0; border-radius: 4px; background: transparent;
color: var(--text); text-align: left; overflow: hidden;
text-overflow: ellipsis; cursor: pointer;
}
.animation-item:hover { background: var(--panel-2); }
.animation-item.active {
background: var(--active-item-fill);
color: var(--accent); box-shadow: inset 3px 0 0 var(--accent);
}
#viewport { position: relative; width: 100%; min-width: 0; flex: 1; overflow: hidden; }
canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#status {
position: absolute; bottom: calc(22px + var(--timeline-height)); left: 12px; color: var(--text-dim);
font-size: 12px; pointer-events: none; text-shadow: 0 1px 2px rgba(0,0,0,.3);
}
#timelineBar {
position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 10;
display: flex; align-items: center; gap: 10px;
padding: 6px 12px;
background: var(--panel-glass);
border: 1px solid var(--border); border-radius: 8px;
box-shadow: 0 -4px 18px rgba(0, 0, 0, .22);
backdrop-filter: blur(8px);
}
#timelineLabels {
display: flex; flex-direction: column; justify-content: space-between;
align-self: stretch; min-width: 136px; padding: 8px 0 1px;
}
#timelineBar .tl-label { color: var(--text-dim); font-size: 12px; white-space: nowrap; }
#keyframeLegend {
display: flex; align-items: center; gap: 6px; color: var(--text-dim);
font-size: 11px; white-space: nowrap; cursor: help;
}
#keyframeLegend::before {
content: ''; width: 10px; height: 7px; border-radius: 1px;
background: var(--accent); opacity: .7;
}
#timelineBar .tl-wrap { position: relative; flex: 1; padding-top: 20px; }
#timelineBar input[type="range"] {
display: block; width: 100%; margin: 0; accent-color: var(--accent);
outline: none; box-shadow: none; -webkit-tap-highlight-color: transparent;
}
#timelineBar input[type="range"]:focus,
#timelineBar input[type="range"]:focus-visible {
outline: none; box-shadow: none; border-color: var(--border);
}
#timeRuler { position: absolute; top: 0; left: 7px; right: 7px; height: 19px; }
#timeRuler .tick {
position: absolute; bottom: 0; width: 1px; height: 5px;
background: var(--border); transform: translateX(-.5px);
}
#timeRuler .tick.major { height: 9px; background: var(--text-dim); }
#timeRuler .tick-label {
position: absolute; bottom: 8px; color: var(--text-dim); font-size: 10px;
font-variant-numeric: tabular-nums; transform: translateX(-50%); white-space: nowrap;
}
#timeRuler .tick-label.first { transform: none; }
#timeRuler .tick-label.last { transform: translateX(-100%); }
#keyframes { position: relative; height: 8px; margin-top: 2px; }
#keyframes span {
position: absolute; top: 0; width: 3px; height: 8px;
background: var(--accent); opacity: .62; transform: translateX(-1.5px);
cursor: help; transition: opacity .12s, transform .12s;
}
#keyframes span:hover { opacity: 1; transform: translateX(-1.5px) scaleY(1.35); }
#timeLabel {
color: var(--text-dim); font-size: 12px; min-width: 178px;
text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
#overlay {
position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
background: var(--bg); z-index: 5; text-align: center;
}
#overlay .box { max-width: 520px; padding: 20px; }
#overlay .title { font-size: 16px; margin-bottom: 8px; color: var(--error); }
#overlay .msg { color: var(--text-dim); white-space: pre-wrap; word-break: break-all; }
#overlay.text-preview { align-items: stretch; justify-content: stretch; text-align: left; }
#overlay.text-preview .box { width: 100%; max-width: none; padding: 24px; overflow: auto; }
#overlay.text-preview .title { color: var(--text); font-size: 13px; font-weight: 600; }
#overlay.text-preview .msg {
font: 12px/1.6 "SFMono-Regular", Consolas, "Liberation Mono", monospace;
color: var(--text-dim); white-space: pre; word-break: normal;
}
/* 纯文本 / 普通 JSON 预览允许拖动选择与 Ctrl+C 复制;画布与查看器控件仍保持不可选中 */
#overlay.text-preview .title,
#overlay.text-preview .msg {
-webkit-user-select: text; user-select: text;
}
#overlay.text-preview .msg { cursor: text; }
/* 预览区滚动条:不使用原生样式。宽度 14px、滑块可见 8px,保证看得清。
颜色走 --scroll-* 变量(rgba 写死),不能用 color-mix():Eagle 内置 Chromium 108
不支持该函数,声明会整条失效,滑块就变成看不见。也不要写 scrollbar-width /
scrollbar-color,那两个标准属性在 108 上无效且易与 ::-webkit-scrollbar 混淆。 */
#overlay.text-preview .box::-webkit-scrollbar { width: 14px; height: 14px; }
#overlay.text-preview .box::-webkit-scrollbar-track { background: var(--scroll-track); }
#overlay.text-preview .box::-webkit-scrollbar-thumb {
min-height: 36px;
border: 3px solid transparent; border-radius: 999px;
background: var(--scroll-thumb);
background-clip: padding-box;
}
#overlay.text-preview .box::-webkit-scrollbar-thumb:hover {
background: var(--scroll-thumb-hover);
background-clip: padding-box;
}
#overlay.text-preview .box::-webkit-scrollbar-thumb:active {
background: var(--scroll-thumb-active);
background-clip: padding-box;
}
#overlay.text-preview .box::-webkit-scrollbar-corner { background: transparent; }
/* JSON 字段树:折叠标记与计数只用符号 / 数字,无需新增界面文案 */
#overlay.json-preview .msg { white-space: normal; }
.jt-node > summary {
list-style: none; cursor: pointer; border-radius: 4px;
}
.jt-node > summary::-webkit-details-marker { display: none; }
.jt-node > summary:hover { background: var(--hover-fill); }
.jt-node > summary::before {
content: '▾'; display: inline-block; width: 14px; color: var(--text-dim);
}
.jt-node:not([open]) > summary::before { content: '▸'; }
.jt-children { margin-left: 7px; padding-left: 11px; border-left: 1px solid var(--border); }
.jt-leaf { padding-left: 14px; }
.jt-key { color: var(--accent); }
.jt-str { color: var(--text); }
.jt-brace, .jt-count { color: var(--text-dim); }
.jt-count { margin: 0 3px; font-size: 11px; }
#overlay.hidden { display: none; }
#loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 4; background: var(--bg); }
#loading.hidden { display: none; }
.spinner {
width: 34px; height: 34px; border: 3px solid var(--border);
border-top-color: var(--accent); border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
#hideOthers { display: none; }