fix: wheel zoom behavior for LoRA Manager widgets

- Add forwardWheelToCanvas() utility for vanilla JS widgets
- Implement wheel event handling in Vue widgets (LoraCyclerWidget, LoraRandomizerWidget, LoraPoolWidget)
- Update SingleSlider and DualRangeSlider to stop event propagation after value adjustment
- Ensure consistent behavior: slider adjusts value only, other areas trigger canvas zoom
- Support pinch-to-zoom (Ctrl+wheel) and horizontal scroll forwarding
This commit is contained in:
Will Miao
2026-03-28 22:42:26 +08:00
parent dcc7bd33b5
commit 89b1675ec7
10 changed files with 399 additions and 96 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div class="lora-randomizer-widget">
<div class="lora-randomizer-widget" @wheel="onWheel">
<LoraRandomizerSettingsView
:count-mode="state.countMode.value"
:count-fixed="state.countFixed.value"
@@ -154,6 +154,53 @@ const handleReuseLast = () => {
}
}
/**
* Handle mouse wheel events on the widget.
* Forwards the event to the ComfyUI canvas for zooming when appropriate.
*/
const onWheel = (event: WheelEvent) => {
// Check if the event originated from a slider component
// Sliders have data-capture-wheel="true" attribute
const target = event.target as HTMLElement
if (target?.closest('[data-capture-wheel="true"]')) {
// Event is from a slider, slider already handled it
// Just stop propagation to prevent canvas zoom
event.stopPropagation()
return
}
// Access ComfyUI app from global window
const app = (window as any).app
if (!app || !app.canvas || typeof app.canvas.processMouseWheel !== 'function') {
return
}
const deltaX = event.deltaX
const deltaY = event.deltaY
const isHorizontal = Math.abs(deltaX) > Math.abs(deltaY)
// 1. Handle pinch-to-zoom (ctrlKey is true for pinch-to-zoom on most browsers)
if (event.ctrlKey) {
event.preventDefault()
event.stopPropagation()
app.canvas.processMouseWheel(event)
return
}
// 2. Horizontal scroll: pass to canvas (widgets usually don't scroll horizontally)
if (isHorizontal) {
event.preventDefault()
event.stopPropagation()
app.canvas.processMouseWheel(event)
return
}
// 3. Vertical scrolling: forward to canvas
event.preventDefault()
event.stopPropagation()
app.canvas.processMouseWheel(event)
}
// Watch for changes to the loras widget to track current loras
watch(() => props.node.widgets?.find((w: any) => w.name === 'loras')?.value, (newVal) => {
// Only update after component is mounted