mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
Add header drag functionality for proportional strength adjustment of LoRAs
This commit is contained in:
@@ -11,7 +11,7 @@ import {
|
|||||||
CONTAINER_PADDING,
|
CONTAINER_PADDING,
|
||||||
EMPTY_CONTAINER_HEIGHT
|
EMPTY_CONTAINER_HEIGHT
|
||||||
} from "./loras_widget_utils.js";
|
} from "./loras_widget_utils.js";
|
||||||
import { initDrag, createContextMenu } from "./loras_widget_events.js";
|
import { initDrag, createContextMenu, initHeaderDrag } from "./loras_widget_events.js";
|
||||||
|
|
||||||
export function addLorasWidget(node, name, opts, callback) {
|
export function addLorasWidget(node, name, opts, callback) {
|
||||||
// Create container for loras
|
// Create container for loras
|
||||||
@@ -83,7 +83,8 @@ export function addLorasWidget(node, name, opts, callback) {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
padding: "4px 8px",
|
padding: "4px 8px",
|
||||||
borderBottom: "1px solid rgba(226, 232, 240, 0.2)",
|
borderBottom: "1px solid rgba(226, 232, 240, 0.2)",
|
||||||
marginBottom: "5px"
|
marginBottom: "5px",
|
||||||
|
position: "relative" // Added for positioning the drag hint
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add toggle all control
|
// Add toggle all control
|
||||||
@@ -118,7 +119,7 @@ export function addLorasWidget(node, name, opts, callback) {
|
|||||||
toggleContainer.appendChild(toggleAll);
|
toggleContainer.appendChild(toggleAll);
|
||||||
toggleContainer.appendChild(toggleLabel);
|
toggleContainer.appendChild(toggleLabel);
|
||||||
|
|
||||||
// Strength label
|
// Strength label with drag hint
|
||||||
const strengthLabel = document.createElement("div");
|
const strengthLabel = document.createElement("div");
|
||||||
strengthLabel.textContent = "Strength";
|
strengthLabel.textContent = "Strength";
|
||||||
Object.assign(strengthLabel.style, {
|
Object.assign(strengthLabel.style, {
|
||||||
@@ -129,11 +130,36 @@ export function addLorasWidget(node, name, opts, callback) {
|
|||||||
WebkitUserSelect: "none",
|
WebkitUserSelect: "none",
|
||||||
MozUserSelect: "none",
|
MozUserSelect: "none",
|
||||||
msUserSelect: "none",
|
msUserSelect: "none",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center"
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add drag hint icon next to strength label
|
||||||
|
const dragHint = document.createElement("span");
|
||||||
|
dragHint.innerHTML = "↔"; // Simple left-right arrow as drag indicator
|
||||||
|
Object.assign(dragHint.style, {
|
||||||
|
marginLeft: "5px",
|
||||||
|
fontSize: "11px",
|
||||||
|
opacity: "0.6",
|
||||||
|
transition: "opacity 0.2s ease"
|
||||||
|
});
|
||||||
|
strengthLabel.appendChild(dragHint);
|
||||||
|
|
||||||
|
// Add hover effect to improve discoverability
|
||||||
|
header.addEventListener("mouseenter", () => {
|
||||||
|
dragHint.style.opacity = "1";
|
||||||
|
});
|
||||||
|
|
||||||
|
header.addEventListener("mouseleave", () => {
|
||||||
|
dragHint.style.opacity = "0.6";
|
||||||
});
|
});
|
||||||
|
|
||||||
header.appendChild(toggleContainer);
|
header.appendChild(toggleContainer);
|
||||||
header.appendChild(strengthLabel);
|
header.appendChild(strengthLabel);
|
||||||
container.appendChild(header);
|
container.appendChild(header);
|
||||||
|
|
||||||
|
// Initialize the header drag functionality
|
||||||
|
initHeaderDrag(header, widget, renderLoras);
|
||||||
|
|
||||||
// Track the total visible entries for height calculation
|
// Track the total visible entries for height calculation
|
||||||
let totalVisibleEntries = lorasData.length;
|
let totalVisibleEntries = lorasData.length;
|
||||||
|
|||||||
@@ -46,6 +46,55 @@ export function handleStrengthDrag(name, initialStrength, initialX, event, widge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to handle proportional strength adjustment for all LoRAs via header dragging
|
||||||
|
export function handleAllStrengthsDrag(initialStrengths, initialX, event, widget) {
|
||||||
|
// Define sensitivity (less sensitive than individual adjustment)
|
||||||
|
const sensitivity = 0.0005;
|
||||||
|
|
||||||
|
// Get current mouse position
|
||||||
|
const currentX = event.clientX;
|
||||||
|
|
||||||
|
// Calculate the distance moved
|
||||||
|
const deltaX = currentX - initialX;
|
||||||
|
|
||||||
|
// Calculate adjustment factor (1.0 means no change, >1.0 means increase, <1.0 means decrease)
|
||||||
|
// For positive deltaX, we want to increase strengths, for negative we want to decrease
|
||||||
|
const adjustmentFactor = 1.0 + (deltaX * sensitivity);
|
||||||
|
|
||||||
|
// Ensure adjustment factor is reasonable (prevent extreme changes)
|
||||||
|
const limitedFactor = Math.max(0.01, Math.min(3.0, adjustmentFactor));
|
||||||
|
|
||||||
|
// Get current loras data
|
||||||
|
const lorasData = parseLoraValue(widget.value);
|
||||||
|
|
||||||
|
// Apply the adjustment factor to each LoRA's strengths
|
||||||
|
lorasData.forEach((loraData, index) => {
|
||||||
|
// Get initial strengths for this LoRA
|
||||||
|
const initialModelStrength = initialStrengths[index].modelStrength;
|
||||||
|
const initialClipStrength = initialStrengths[index].clipStrength;
|
||||||
|
|
||||||
|
// Apply the adjustment factor to both strengths
|
||||||
|
let newModelStrength = (initialModelStrength * limitedFactor).toFixed(2);
|
||||||
|
let newClipStrength = (initialClipStrength * limitedFactor).toFixed(2);
|
||||||
|
|
||||||
|
// Limit the values to reasonable bounds (-10 to 10)
|
||||||
|
newModelStrength = Math.max(-10, Math.min(10, newModelStrength));
|
||||||
|
newClipStrength = Math.max(-10, Math.min(10, newClipStrength));
|
||||||
|
|
||||||
|
// Update strengths
|
||||||
|
lorasData[index].strength = Number(newModelStrength);
|
||||||
|
lorasData[index].clipStrength = Number(newClipStrength);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update widget value
|
||||||
|
widget.value = formatLoraValue(lorasData);
|
||||||
|
|
||||||
|
// Force re-render via callback
|
||||||
|
if (widget.callback) {
|
||||||
|
widget.callback(widget.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Function to initialize drag operation
|
// Function to initialize drag operation
|
||||||
export function initDrag(dragEl, name, widget, isClipStrength = false, previewTooltip, renderFunction) {
|
export function initDrag(dragEl, name, widget, isClipStrength = false, previewTooltip, renderFunction) {
|
||||||
let isDragging = false;
|
let isDragging = false;
|
||||||
@@ -119,6 +168,65 @@ export function initDrag(dragEl, name, widget, isClipStrength = false, previewTo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to initialize header drag for proportional strength adjustment
|
||||||
|
export function initHeaderDrag(headerEl, widget, renderFunction) {
|
||||||
|
let isDragging = false;
|
||||||
|
let initialX = 0;
|
||||||
|
let initialStrengths = [];
|
||||||
|
|
||||||
|
// Add cursor style to indicate draggable
|
||||||
|
headerEl.style.cursor = 'ew-resize';
|
||||||
|
|
||||||
|
// Create a drag handler
|
||||||
|
headerEl.addEventListener('mousedown', (e) => {
|
||||||
|
// Skip if clicking on toggle or other interactive elements
|
||||||
|
if (e.target.closest('.comfy-lora-toggle') ||
|
||||||
|
e.target.closest('input')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store initial X position
|
||||||
|
initialX = e.clientX;
|
||||||
|
|
||||||
|
// Store initial strengths of all LoRAs
|
||||||
|
const lorasData = parseLoraValue(widget.value);
|
||||||
|
initialStrengths = lorasData.map(lora => ({
|
||||||
|
modelStrength: Number(lora.strength),
|
||||||
|
clipStrength: Number(lora.clipStrength)
|
||||||
|
}));
|
||||||
|
|
||||||
|
isDragging = true;
|
||||||
|
|
||||||
|
// Add class to body to enforce cursor style globally
|
||||||
|
document.body.classList.add('comfy-lora-dragging');
|
||||||
|
|
||||||
|
// Prevent text selection during drag
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle mouse move for dragging
|
||||||
|
document.addEventListener('mousemove', (e) => {
|
||||||
|
if (!isDragging) return;
|
||||||
|
|
||||||
|
// Call the strength adjustment function
|
||||||
|
handleAllStrengthsDrag(initialStrengths, initialX, e, widget);
|
||||||
|
|
||||||
|
// Force re-render to show updated strength values
|
||||||
|
if (renderFunction) {
|
||||||
|
renderFunction(widget.value, widget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle mouse up to end dragging
|
||||||
|
document.addEventListener('mouseup', () => {
|
||||||
|
if (isDragging) {
|
||||||
|
isDragging = false;
|
||||||
|
// Remove the class to restore normal cursor behavior
|
||||||
|
document.body.classList.remove('comfy-lora-dragging');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Function to create context menu
|
// Function to create context menu
|
||||||
export function createContextMenu(x, y, loraName, widget, previewTooltip, renderFunction) {
|
export function createContextMenu(x, y, loraName, widget, previewTooltip, renderFunction) {
|
||||||
// Hide preview tooltip first
|
// Hide preview tooltip first
|
||||||
|
|||||||
Reference in New Issue
Block a user