按钮颜色

This commit is contained in:
tianmo committed 2026-09-19 19:01:49 +08:00
1 parent b258d736fd
commit 5808e3dfce
5 files changed
+57 -6

No files matched your search

@@ -77,6 +77,21 @@
button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
button.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
button:disabled { cursor: default; opacity: .55; }
#groupThumbBtn { position: relative; background: #2e7d32; color: #fff; border-color: #2e7d32; }
#groupThumbBtn:hover { background: #256628; }
#thumbBtn { position: relative; background: #1976d2; color: #fff; border-color: #1976d2; }
#thumbBtn:hover { background: #155fa8; }
#groupThumbBtn::after, #thumbBtn::after {
content: attr(data-tooltip); position: absolute; top: calc(100% + 8px); z-index: 30;
width: max-content; max-width: min(620px, calc(100vw - 24px)); padding: 6px 10px;
color: var(--text); font-size: 12px; font-weight: 500; line-height: 1.4; white-space: normal;
background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
box-shadow: 0 4px 14px rgba(0, 0, 0, .35); pointer-events: none;
opacity: 0; visibility: hidden;
}
#groupThumbBtn::after { left: 0; background: #256628; border-color: #256628; color: #fff; }
#thumbBtn::after { right: 0; background: #155fa8; border-color: #155fa8; color: #fff; }
#groupThumbBtn:hover::after, #thumbBtn:hover::after { opacity: 1; visibility: visible; }
.thumb-dialog {
position: absolute; inset: 0; z-index: 40; display: flex;
align-items: center; justify-content: center; padding: 24px;
@@ -29,8 +29,8 @@
<span data-i18n="viewer.suffix">尾缀</span>
<select id="suffixSelect"></select>
</label>
<button id="groupThumbBtn" data-i18n="viewer.groupThumbnail" data-i18n-title="viewer.groupThumbnailTitle" title="左键点击生成静态缩略图,右键点击生成动态缩略图">为关联资源生成缩略图</button>
<button id="thumbBtn" data-i18n="viewer.thumbnail" data-i18n-title="viewer.thumbnailTitle" title="左键点击生成静态缩略图,右键点击生成动态缩略图">设为当前素材缩略图</button>
<button id="groupThumbBtn" data-i18n="viewer.groupThumbnail" data-i18n-title="viewer.groupThumbnailTitle" data-instant-tooltip data-tooltip="左键点击生成静态缩略图,右键点击生成动态缩略图">为关联资源生成缩略图</button>
<button id="thumbBtn" data-i18n="viewer.thumbnail" data-i18n-title="viewer.thumbnailTitle" data-instant-tooltip data-tooltip="左键点击生成静态缩略图,右键点击生成动态缩略图">设为当前素材缩略图</button>
<label id="verLabel" style="color: var(--text-dim);" data-i18n-title="viewer.versionTitle" title="Spine 版本"></label>
<button id="reloadBtn" title="重新加载目录" data-i18n-title="viewer.reloadTitle">↻</button>
</div>
@@ -241,7 +241,11 @@
function applyStaticI18n(root) {
const scope = root || document;
for (const el of scope.querySelectorAll('[data-i18n]')) el.textContent = t(el.dataset.i18n);
for (const el of scope.querySelectorAll('[data-i18n-title]')) el.title = t(el.dataset.i18nTitle);
for (const el of scope.querySelectorAll('[data-i18n-title]')) {
const text = t(el.dataset.i18nTitle);
if (el.hasAttribute('data-instant-tooltip')) el.dataset.tooltip = text;
else el.title = text;
}
for (const el of scope.querySelectorAll('[data-i18n-aria-label]')) el.setAttribute('aria-label', t(el.dataset.i18nAriaLabel));
}
applyStaticI18n();
+13
View File
@@ -7,8 +7,21 @@ const { createRequire } = require('node:module');
const roots = ['.', 'release/UNIVERSAL_SpineViewer'];
for (const root of roots) {
const html = fs.readFileSync(path.join(root, 'viewer/spine.html'), 'utf8');
const css = fs.readFileSync(path.join(root, 'viewer/spine.css'), 'utf8');
const script = html.match(/<script>([\s\S]*?)<\/script>/)[1];
new vm.Script(script);
for (const id of ['groupThumbBtn', 'thumbBtn']) {
const button = html.match(new RegExp(`<button id="${id}"[^>]*>`))[0];
assert.match(button, /data-instant-tooltip/);
assert.match(button, /data-tooltip=/);
assert.doesNotMatch(button, /\stitle=/);
}
assert.match(css, /#groupThumbBtn:hover::after, #thumbBtn:hover::after \{ opacity: 1; visibility: visible; \}/);
assert.match(css, /#groupThumbBtn \{[^}]*background: #2e7d32;/);
assert.match(css, /#thumbBtn \{[^}]*background: #1976d2;/);
assert.match(css, /#groupThumbBtn::after \{[^}]*background: #256628;/);
assert.match(css, /#thumbBtn::after \{[^}]*background: #155fa8;/);
assert.match(script, /if \(el\.hasAttribute\('data-instant-tooltip'\)\) el\.dataset\.tooltip = text;/);
const i18n = script.slice(script.indexOf('\tconst I18N_LANGUAGES'), script.indexOf('\tapplyStaticI18n();'));
const markers = script.slice(script.indexOf('\tfunction renderKeyframeMarkers('), script.indexOf('\tfunction seekTo('));
const manifest = JSON.parse(fs.readFileSync(path.join(root, 'manifest.json'), 'utf8'));
+15
View File
@@ -77,6 +77,21 @@
button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
button.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
button:disabled { cursor: default; opacity: .55; }
#groupThumbBtn { position: relative; background: #2e7d32; color: #fff; border-color: #2e7d32; }
#groupThumbBtn:hover { background: #256628; }
#thumbBtn { position: relative; background: #1976d2; color: #fff; border-color: #1976d2; }
#thumbBtn:hover { background: #155fa8; }
#groupThumbBtn::after, #thumbBtn::after {
content: attr(data-tooltip); position: absolute; top: calc(100% + 8px); z-index: 30;
width: max-content; max-width: min(620px, calc(100vw - 24px)); padding: 6px 10px;
color: var(--text); font-size: 12px; font-weight: 500; line-height: 1.4; white-space: normal;
background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
box-shadow: 0 4px 14px rgba(0, 0, 0, .35); pointer-events: none;
opacity: 0; visibility: hidden;
}
#groupThumbBtn::after { left: 0; background: #256628; border-color: #256628; color: #fff; }
#thumbBtn::after { right: 0; background: #155fa8; border-color: #155fa8; color: #fff; }
#groupThumbBtn:hover::after, #thumbBtn:hover::after { opacity: 1; visibility: visible; }
.thumb-dialog {
position: absolute; inset: 0; z-index: 40; display: flex;
align-items: center; justify-content: center; padding: 24px;
+7 -3
View File
@@ -29,8 +29,8 @@
<span data-i18n="viewer.suffix">尾缀</span>
<select id="suffixSelect"></select>
</label>
<button id="groupThumbBtn" data-i18n="viewer.groupThumbnail" data-i18n-title="viewer.groupThumbnailTitle" title="左键点击生成静态缩略图,右键点击生成动态缩略图">为关联资源生成缩略图</button>
<button id="thumbBtn" data-i18n="viewer.thumbnail" data-i18n-title="viewer.thumbnailTitle" title="左键点击生成静态缩略图,右键点击生成动态缩略图">设为当前素材缩略图</button>
<button id="groupThumbBtn" data-i18n="viewer.groupThumbnail" data-i18n-title="viewer.groupThumbnailTitle" data-instant-tooltip data-tooltip="左键点击生成静态缩略图,右键点击生成动态缩略图">为关联资源生成缩略图</button>
<button id="thumbBtn" data-i18n="viewer.thumbnail" data-i18n-title="viewer.thumbnailTitle" data-instant-tooltip data-tooltip="左键点击生成静态缩略图,右键点击生成动态缩略图">设为当前素材缩略图</button>
<label id="verLabel" style="color: var(--text-dim);" data-i18n-title="viewer.versionTitle" title="Spine 版本"></label>
<button id="reloadBtn" title="重新加载目录" data-i18n-title="viewer.reloadTitle">↻</button>
</div>
@@ -241,7 +241,11 @@
function applyStaticI18n(root) {
const scope = root || document;
for (const el of scope.querySelectorAll('[data-i18n]')) el.textContent = t(el.dataset.i18n);
for (const el of scope.querySelectorAll('[data-i18n-title]')) el.title = t(el.dataset.i18nTitle);
for (const el of scope.querySelectorAll('[data-i18n-title]')) {
const text = t(el.dataset.i18nTitle);
if (el.hasAttribute('data-instant-tooltip')) el.dataset.tooltip = text;
else el.title = text;
}
for (const el of scope.querySelectorAll('[data-i18n-aria-label]')) el.setAttribute('aria-label', t(el.dataset.i18nAriaLabel));
}
applyStaticI18n();