I’m having trouble with handling scroll events. I’m scaling the object based on scrolling event using IScrollHandler.
This works well with most mice and touchpads however, logitech has this “smooth scroll” function. Which by default is active. It floods the scroll handler implementation with a lot of values usually < -1 and > 1 over time.
How would you handle such an event flood? With track pads the values are atleast of lower values and if they’re past -1 or 1 I already clamp them. Which works for track pads but not for the smooth scrolling function of Logitech. They just flood the event with high values rather than smoothing -1 ~ +1 over time -insert facepalm-.
Things I’ve tried is limiting the amount of events per second. But that’ll limit the regular mouse / track pad events as well. Which is undesired as they do give normal values.
Implementation is for WebGL, but should be a cross platform solution. So I got to handle it with the event data I get. But I’m uncertain how to solve this, any idea?
I would try to use average of last 4 or 8 values maybe with weights like 1 / (i + 1) to set scroller “target” value and then lerp current scroller position. If this won’t help, I’d like to look at the real sequence to figure out something
Wouldn’t that only slow down movement values over N events
trackpads which do give correct values would be slowed down even more.
Here’s a snippet:
public Transform Target;
public float MinimumScale = 0.5f;
public float MaximumScale = 3f;
public float ScaleStep = 0.2f;
private float scale = 1f;
public void OnScroll(PointerEventData eventData)
{
// Scroll Event Value * ScaleStep
var scrollDeltaY = Mathf.Clamp(eventData.scrollDelta.y, -1f, 1f) * ScaleStep;
// Clamp the scale value within boundaries
var newScale = Mathf.Clamp(scale + scrollDeltaY, MinimumScale, MaximumScale);
// If we already reached minimum / maximum the scale stays the same
if (newScale.Equals(scale)) return;
// Set the new scale
scale = newScale;
// Apply the new scale
// DOTween.DoScale will scale all axis with the given value over N amount of time.
// In this case it will tween the scale to the new value over 0.15 second linearly.
Target.DOScale(scale, 0.15f).SetEase(Ease.Linear);
}
In case of a trackpad on a laptop or keyboard with trackpad the OnScroll method gets called with values such as
-1, -2 ~ 1, 2. If it is more precise it would give smaller vallues but more events (0.025, 0.034 etc)
The amount of events would depend on the trackpad detecting movement between 2 touches.
In case of a normal mouse:
Getting -1, -2 ~ 1, 2 each time the scroll wheel makes a step (can feel the force of each scroll) only 1 event is sent per physical scroll.
In case of the Logitech mouse:
1 physical scroll sends out 30+ events over 1 ~ 2 seconds. each -1 or +1 (or higher depending on the force given with multiple scrolls)
So in case of the logitech mouse the scale will reach minimum / maximum due to the amount of events + values sent.
I cannot limit the amount of events because that would disrupt the functionality of a trackpad. It could send out the same amount of events but with smaller values.
I cannot check the deltatime between events as the trackpad events could possibly be very precise but lower values and thus more events are sent.
Also the Logitech events don’t have a specific delta time. It’s pretty random with random values too it seems.
Did you ever find a solution to this? Dealing with the same issue