mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-26 07:35:44 -03:00
feat(showcase): add wheel navigation, horizontal thumbnail rail scroll, and image counter
- Add horizontal scroll to thumbnail rail on wheel event - Add wheel-based image navigation in main image area (150 threshold) - Add image counter showing current position (e.g., "1 / 12") - Use tabular-nums and min-width: 2ch to prevent counter layout shift - Respect params panel scrolling when using wheel navigation
This commit is contained in:
@@ -227,6 +227,44 @@
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Image counter */
|
||||||
|
.showcase__counter {
|
||||||
|
position: absolute;
|
||||||
|
top: var(--space-2);
|
||||||
|
left: var(--space-2);
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
color: white;
|
||||||
|
padding: var(--space-1) var(--space-2);
|
||||||
|
border-radius: var(--border-radius-xs);
|
||||||
|
font-size: 0.85em;
|
||||||
|
font-weight: 500;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-1);
|
||||||
|
opacity: 0.8;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showcase__image-wrapper:hover .showcase__counter {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showcase__counter-current {
|
||||||
|
font-weight: 600;
|
||||||
|
min-width: 2ch;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showcase__counter-separator {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showcase__counter-total {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
.showcase__image-wrapper:hover .showcase__controls {
|
.showcase__image-wrapper:hover .showcase__controls {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
|
|||||||
@@ -209,6 +209,12 @@ export class Showcase {
|
|||||||
<!-- Media will be loaded here -->
|
<!-- Media will be loaded here -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="showcase__counter">
|
||||||
|
<span class="showcase__counter-current">1</span>
|
||||||
|
<span class="showcase__counter-separator">/</span>
|
||||||
|
<span class="showcase__counter-total">${this.images.length}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="showcase__controls">
|
<div class="showcase__controls">
|
||||||
<button class="showcase__control-btn ${this.hasNsfwContent() ? '' : 'hidden'}"
|
<button class="showcase__control-btn ${this.hasNsfwContent() ? '' : 'hidden'}"
|
||||||
data-action="toggle-global-blur"
|
data-action="toggle-global-blur"
|
||||||
@@ -425,6 +431,41 @@ export class Showcase {
|
|||||||
fileInput?.click();
|
fileInput?.click();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Thumbnail rail horizontal scroll on wheel
|
||||||
|
const thumbnailRail = this.element.querySelector('.thumbnail-rail');
|
||||||
|
if (thumbnailRail) {
|
||||||
|
thumbnailRail.addEventListener('wheel', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
thumbnailRail.scrollLeft += e.deltaY;
|
||||||
|
}, { passive: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main image navigation on wheel (with threshold to prevent accidental switching)
|
||||||
|
const mainImageWrapper = this.element.querySelector('.showcase__image-wrapper');
|
||||||
|
if (mainImageWrapper) {
|
||||||
|
let wheelAccumulated = 0;
|
||||||
|
const WHEEL_THRESHOLD = 150;
|
||||||
|
|
||||||
|
mainImageWrapper.addEventListener('wheel', (e) => {
|
||||||
|
// Don't interfere with params panel scrolling
|
||||||
|
const paramsPanel = this.element.querySelector('.showcase__params.visible');
|
||||||
|
if (paramsPanel && paramsPanel.contains(e.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
wheelAccumulated += e.deltaY;
|
||||||
|
|
||||||
|
if (wheelAccumulated > WHEEL_THRESHOLD) {
|
||||||
|
this.nextImage();
|
||||||
|
wheelAccumulated = 0;
|
||||||
|
} else if (wheelAccumulated < -WHEEL_THRESHOLD) {
|
||||||
|
this.prevImage();
|
||||||
|
wheelAccumulated = 0;
|
||||||
|
}
|
||||||
|
}, { passive: false });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -637,10 +678,27 @@ export class Showcase {
|
|||||||
item.classList.toggle('active', i === index);
|
item.classList.toggle('active', i === index);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update counter
|
||||||
|
this.updateCounter();
|
||||||
|
|
||||||
// Update params
|
// Update params
|
||||||
this.updateParams(image);
|
this.updateParams(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update image counter display
|
||||||
|
*/
|
||||||
|
updateCounter() {
|
||||||
|
const counterCurrent = this.element.querySelector('.showcase__counter-current');
|
||||||
|
const counterTotal = this.element.querySelector('.showcase__counter-total');
|
||||||
|
if (counterCurrent) {
|
||||||
|
counterCurrent.textContent = this.currentIndex + 1;
|
||||||
|
}
|
||||||
|
if (counterTotal) {
|
||||||
|
counterTotal.textContent = this.images.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render media element (image or video)
|
* Render media element (image or video)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user