processVelocity
Parameters
- self:*ScrollContainerWidget
- *ScrollContainerWidget
Source
Implementation
pub fn processVelocity(self: *ScrollContainerWidget) void {
// velocity is only for touch currently
// damp the current velocity
// exponential decay: v *= damping^secs_since
// tweak the damping so we brake harder as the velocity slows down
if (!self.finger_down) {
const before = self.si.viewport.topLeft();
{
const damping = 0.0001 + @min(1.0, @abs(self.si.velocity.x) / 50.0) * (0.7 - 0.0001);
self.si.velocity.x *= @exp(@log(damping) * dvui.secondsSinceLastFrame());
if (@abs(self.si.velocity.x) > 1) {
//std.debug.print("vel x {d}\n", .{self.si.velocity.x});
self.si.viewport.x += self.si.velocity.x * 50 * dvui.secondsSinceLastFrame();
dvui.refresh(null, @src(), self.data().id);
} else {
self.si.velocity.x = 0;
}
}
{
const damping = 0.0001 + @min(1.0, @abs(self.si.velocity.y) / 50.0) * (0.7 - 0.0001);
self.si.velocity.y *= @exp(@log(damping) * dvui.secondsSinceLastFrame());
if (@abs(self.si.velocity.y) > 1) {
//std.debug.print("vel y {d}\n", .{self.si.velocity.y});
self.si.viewport.y += self.si.velocity.y * 50 * dvui.secondsSinceLastFrame();
dvui.refresh(null, @src(), self.data().id);
} else {
self.si.velocity.y = 0;
}
}
if (self.init_opts.user_scroll) |us| us.* = us.*.plus(self.si.viewport.topLeft().diff(before));
}
// bounce back if we went too far
// bounce back does not count for user_scroll
{
const max_scroll = self.si.scrollMax(.horizontal);
if (self.si.viewport.x < 0) {
self.si.velocity.x = 0;
self.si.viewport.x = @min(0, @max(-20, self.si.viewport.x + 250 * dvui.secondsSinceLastFrame()));
if (self.si.viewport.x < 0) {
dvui.refresh(null, @src(), self.data().id);
}
} else if (self.si.viewport.x > max_scroll) {
self.si.velocity.x = 0;
self.si.viewport.x = @max(max_scroll, @min(max_scroll + 20, self.si.viewport.x - 250 * dvui.secondsSinceLastFrame()));
if (self.si.viewport.x > max_scroll) {
dvui.refresh(null, @src(), self.data().id);
}
}
}
{
const max_scroll = self.si.scrollMax(.vertical);
if (self.si.viewport.y < 0) {
self.si.velocity.y = 0;
self.si.viewport.y = @min(0, @max(-20, self.si.viewport.y + 250 * dvui.secondsSinceLastFrame()));
if (self.si.viewport.y < 0) {
dvui.refresh(null, @src(), self.data().id);
}
} else if (self.si.viewport.y > max_scroll) {
self.si.velocity.y = 0;
self.si.viewport.y = @max(max_scroll, @min(max_scroll + 20, self.si.viewport.y - 250 * dvui.secondsSinceLastFrame()));
if (self.si.viewport.y > max_scroll) {
dvui.refresh(null, @src(), self.data().id);
}
}
}
// might have changed
self.frame_viewport = self.init_opts.frame_viewport orelse self.si.viewport.topLeft();
}