style(workbench): move filmstrip to left rail and enlarge thumbnail cards
This commit is contained in:
+1
-1
@@ -75,7 +75,7 @@ DOM or live LiteGraph state.
|
||||
primary model-browser surfaces.
|
||||
- `ui_gallery_detail.js` owns the full-screen / studio Image Detail Workbench,
|
||||
multi-dimensional image navigation (keyboard shortcuts, floating glass arrows,
|
||||
bottom filmstrip rail), and segmented Bento parameter inspection with ComfyUI
|
||||
left vertical thumbnail rail), and segmented Bento parameter inspection with ComfyUI
|
||||
canvas injection (`app.loadGraphData`).
|
||||
- `ui_notebooks.js`, `ui_recipes.js`, and `ui_recipe_detail.js` own Workspace
|
||||
presentation, featuring Bento-style visual cards, quick spec tags, real-time environment readiness indicators (🟢/🟡/🔴), one-click batch model matching, and lazy DOM rendering for node parameter trees.
|
||||
|
||||
@@ -88,7 +88,7 @@ export const i18n = {
|
||||
workbenchCopySuccess: '✅ 分享文本已复制',
|
||||
workbenchNext: '下一张 (→)',
|
||||
workbenchPrev: '上一张 (←)',
|
||||
workbenchFilmstrip: '底栏缩略图',
|
||||
workbenchFilmstrip: '侧栏缩略图',
|
||||
workbenchTabOverview: '核心参数',
|
||||
workbenchTabPrompts: '提示词工坊',
|
||||
workbenchTabModels: '模型资产',
|
||||
@@ -954,7 +954,7 @@ export const i18n = {
|
||||
workbenchCopySuccess: '✅ Share text copied',
|
||||
workbenchNext: 'Next (→)',
|
||||
workbenchPrev: 'Previous (←)',
|
||||
workbenchFilmstrip: 'Filmstrip',
|
||||
workbenchFilmstrip: 'Thumbnail Rail',
|
||||
workbenchTabOverview: 'Key Specs',
|
||||
workbenchTabPrompts: 'Prompts',
|
||||
workbenchTabModels: 'Models & LoRA',
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Features:
|
||||
* - Fullscreen studio workspace / windowed modal toggle
|
||||
* - Prev / Next image navigation (keyboard arrows, floating glass arrows, counter jump)
|
||||
* - Collapsible bottom thumbnail filmstrip with smooth auto-centering
|
||||
* - Collapsible left thumbnail rail with smooth vertical auto-centering
|
||||
* - High-speed in-memory LRU metadata cache (imageMetadataCache)
|
||||
* - Preloading of adjacent images and AbortController request cancellation
|
||||
* - Segmented Bento Inspector: Key Specs Bento grid, Prompts Station, Models & LoRA with weight pills, Node structure
|
||||
@@ -225,7 +225,7 @@ function buildWorkbenchHeader(item, index, total, onNavigate) {
|
||||
? 'anomalous-workbench-tool-btn is-active'
|
||||
: 'anomalous-workbench-tool-btn';
|
||||
filmstripToggle.innerHTML = '🎞️';
|
||||
filmstripToggle.title = t('workbenchFilmstrip') || '底栏缩略图';
|
||||
filmstripToggle.title = t('workbenchFilmstrip') || (window.anomalous_browser_lang === 'zh' ? '侧栏缩略图' : 'Thumbnail Rail');
|
||||
filmstripToggle.onclick = () => {
|
||||
wb.isFilmstripVisible = !wb.isFilmstripVisible;
|
||||
filmstripToggle.classList.toggle('is-active', wb.isFilmstripVisible);
|
||||
@@ -338,11 +338,14 @@ function setupStagePanZoom(stage, img) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Bottom Filmstrip Rail
|
||||
* Build Left Vertical Filmstrip Rail
|
||||
*/
|
||||
function buildFilmstripRail(items, currentIndex, onNavigate) {
|
||||
const rail = document.createElement('div');
|
||||
rail.className = 'anomalous-workbench-filmstrip';
|
||||
if (wb && wb.isFilmstripVisible === false) {
|
||||
rail.classList.add('is-hidden');
|
||||
}
|
||||
|
||||
const track = document.createElement('div');
|
||||
track.className = 'anomalous-workbench-filmstrip-track';
|
||||
@@ -360,6 +363,11 @@ function buildFilmstripRail(items, currentIndex, onNavigate) {
|
||||
thumbImg.alt = '';
|
||||
thumbWrap.appendChild(thumbImg);
|
||||
|
||||
const badge = document.createElement('span');
|
||||
badge.className = 'anomalous-workbench-thumb-index';
|
||||
badge.textContent = String(idx + 1);
|
||||
thumbWrap.appendChild(badge);
|
||||
|
||||
thumbWrap.onclick = (e) => {
|
||||
e.stopPropagation();
|
||||
if (idx !== currentIndex) onNavigate(idx);
|
||||
@@ -367,10 +375,12 @@ function buildFilmstripRail(items, currentIndex, onNavigate) {
|
||||
|
||||
track.appendChild(thumbWrap);
|
||||
|
||||
// Auto-center active thumbnail
|
||||
// Auto-center active thumbnail vertically
|
||||
if (idx === currentIndex) {
|
||||
requestAnimationFrame(() => {
|
||||
thumbWrap.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
|
||||
setTimeout(() => {
|
||||
thumbWrap.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
|
||||
}, 40);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -758,7 +768,7 @@ async function loadWorkbenchImage(index) {
|
||||
thumbs.forEach((el, i) => {
|
||||
el.classList.toggle('is-active', i === index);
|
||||
if (i === index) {
|
||||
el.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
|
||||
el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1321,14 +1331,15 @@ export async function showImageWorkbench(owner, sourceImage, imageUrl, options =
|
||||
zoomBar.append(fitBtn, actualBtn, zoomOutBtn, zoomInBtn);
|
||||
stageArea.appendChild(zoomBar);
|
||||
|
||||
// Bottom Filmstrip
|
||||
// 4A. Left Vertical Filmstrip Rail
|
||||
const filmstripRail = buildFilmstripRail(items, currentIndex, (idx) => loadWorkbenchImage(idx));
|
||||
wb.filmstripEl = filmstripRail;
|
||||
stageArea.appendChild(filmstripRail);
|
||||
bodyContainer.appendChild(filmstripRail);
|
||||
|
||||
// 4B. Center Canvas Stage Area
|
||||
bodyContainer.appendChild(stageArea);
|
||||
|
||||
// 4B. Right Inspector Panel
|
||||
// 4C. Right Inspector Panel
|
||||
const inspector = document.createElement('div');
|
||||
inspector.className = 'anomalous-workbench-inspector';
|
||||
|
||||
|
||||
+76
-30
@@ -5556,10 +5556,10 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* Main Body: Stage Area + Inspector */
|
||||
/* Main Body: Left Thumbnail Rail + Center Stage Area + Right Inspector */
|
||||
.anomalous-workbench-body {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.45fr) minmax(460px, 0.95fr);
|
||||
grid-template-columns: auto minmax(0, 1.45fr) minmax(460px, 0.95fr);
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
@@ -5635,7 +5635,7 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
/* Floating Zoom Bar */
|
||||
.anomalous-workbench-zoom-bar {
|
||||
position: absolute;
|
||||
bottom: 86px;
|
||||
bottom: 18px;
|
||||
right: 18px;
|
||||
z-index: 12;
|
||||
display: flex;
|
||||
@@ -5666,45 +5666,69 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Bottom Filmstrip Rail */
|
||||
/* Left Filmstrip Rail */
|
||||
.anomalous-workbench-filmstrip {
|
||||
flex: 0 0 82px;
|
||||
height: 82px;
|
||||
padding: 8px 16px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: #0b0d13;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
transition: all 0.22s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
width: 116px;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
padding: 12px 10px;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: #080a0f;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
transition: width 0.22s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
padding 0.22s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
opacity 0.18s ease;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip.is-hidden {
|
||||
flex: 0 0 0px;
|
||||
height: 0px;
|
||||
padding: 0;
|
||||
border-top: none;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
width: 0 !important;
|
||||
min-width: 0 !important;
|
||||
padding: 0 !important;
|
||||
border-right: none !important;
|
||||
overflow: hidden !important;
|
||||
opacity: 0 !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.14);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(45, 212, 191, 0.45);
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip-track {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
height: 100%;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip-thumb {
|
||||
position: relative;
|
||||
flex: 0 0 64px;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 8px;
|
||||
flex: 0 0 92px;
|
||||
width: 92px;
|
||||
height: 92px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
background: #141720;
|
||||
background: #12151e;
|
||||
cursor: pointer;
|
||||
transition: all 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
box-sizing: border-box;
|
||||
transition: border-color 0.18s ease, transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.18s ease;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip-thumb img {
|
||||
@@ -5715,14 +5739,36 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip-thumb:hover {
|
||||
border-color: rgba(255, 255, 255, 0.35);
|
||||
transform: translateY(-2px);
|
||||
border-color: rgba(255, 255, 255, 0.45);
|
||||
transform: scale(1.04);
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip-thumb.is-active {
|
||||
border-color: #2dd4bf;
|
||||
box-shadow: 0 0 14px rgba(45, 212, 191, 0.5);
|
||||
transform: scale(1.06);
|
||||
box-shadow: 0 0 16px rgba(45, 212, 191, 0.55), inset 0 0 0 1px #2dd4bf;
|
||||
transform: scale(1.04);
|
||||
}
|
||||
|
||||
.anomalous-workbench-thumb-index {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
color: #94a3b8;
|
||||
background: rgba(10, 13, 20, 0.82);
|
||||
backdrop-filter: blur(4px);
|
||||
padding: 2px 5px;
|
||||
border-radius: 4px;
|
||||
pointer-events: none;
|
||||
transition: color 0.15s, background 0.15s;
|
||||
}
|
||||
|
||||
.anomalous-workbench-filmstrip-thumb.is-active .anomalous-workbench-thumb-index {
|
||||
color: #2dd4bf;
|
||||
background: rgba(13, 23, 27, 0.92);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
/* Right Inspector Panel */
|
||||
|
||||
Reference in New Issue
Block a user