feat(RenderWindowInteractor): add optional mouseWheelSpinYBuffering - #3623
feat(RenderWindowInteractor): add optional mouseWheelSpinYBuffering#3623yehor-murza-lx wants to merge 1 commit into
Conversation
High-frequency wheel devices (e.g. trackpads) can emit many small fractional spinY deltas in quick succession, causing jittery or overly sensitive zoom/ rotate interactions in consumers of vtkRenderWindowInteractor. Add an opt-in mouseWheelSpinYBuffering flag (default false) that, when enabled, accumulates fractional spinY deltas per interactor instance and only dispatches a mouseWheelEvent once the buffered spin reaches a full step. The buffer resets on direction change and on wheel-end. Also add a configurable wheelEndDebounceDelay (default 200, matching the previous hardcoded value) so consumers can tune how long to wait after the last wheel event before firing the wheel-end event. Both properties default to the existing behavior, so this change is fully backward compatible.
| callData.spinY = Math.sign(scrollBuffer); | ||
| scrollBuffer -= callData.spinY; | ||
| publicAPI.mouseWheelEvent(callData); | ||
| } |
There was a problem hiding this comment.
Let's move things around to cleanup the logic:
If (wheeleventid ==) {
Startmousewheelevent();
} Else {
ClearTimeout();
}
If (not wheelbuferring or ...)
Mousewheelevent();
}
...
| model.mouseWheelSpinYBuffering && | ||
| Math.abs(scrollBuffer) >= SCROLL_THRESHOLD | ||
| ) { | ||
| callData.spinY = Math.sign(scrollBuffer); |
There was a problem hiding this comment.
I think spinY should be 3 (and not 1) if the scroll buffer is 3.2 (maybe the last event added 2.3 to the buffer)
| model.wheelTimeoutID = setTimeout(() => { | ||
| publicAPI.extendAnimation(600); | ||
| publicAPI.endMouseWheelEvent(); | ||
| model.wheelTimeoutID = 0; |
There was a problem hiding this comment.
Can you please take the opportunity to move wheeltimeoutid out of model?
| 'preventDefaultOnPointerDown', | ||
| 'preventDefaultOnPointerUp', | ||
| 'mouseScrollDebounceByPass', | ||
| 'wheelEndDebounceDelay', |
There was a problem hiding this comment.
I like the idea of exposing the delay. But in such a case it duplicates the debouncebypass. Please consolidate both (e.g. a delay of null or 0 is equivalent to a debounce by pass). Let's not break the api for now and simply create a warning that the debounce by pass is now obsolete.
|
We now have a case when a startmousewheelevent may not be followed by a mouse event. Please check in the code base that it is fine. I think I remember that assumption to be expected |
Motivation
High-frequency wheel input devices (e.g. trackpads) can emit many small fractional spinY deltas in quick succession. Consumers of �tkRenderWindowInteractor that map wheel events directly to camera zoom/dolly can end up with jittery or overly sensitive interactions as a result.
Change
Backward compatibility
Both new properties default to values that reproduce the current behavior exactly (mouseWheelSpinYBuffering: false disables buffering entirely; wheelEndDebounceDelay: 200 matches the previous hardcoded timeout), so no existing consumer behavior changes unless they opt in.
Testing
pm run reformat and lint (oxlint) pass with no issues.