diff --git a/src/MarbleGame.hx b/src/MarbleGame.hx index 56cbc3ac..583de8d3 100644 --- a/src/MarbleGame.hx +++ b/src/MarbleGame.hx @@ -167,7 +167,7 @@ class MarbleGame { }); pointercontainer.addEventListener('touchend', (e:js.html.TouchEvent) -> { - // @:privateAccess Key.keyPressed[Key.MOUSE_LEFT] = -Key.getFrame(); + @:privateAccess Key.keyPressed[Key.MOUSE_LEFT] = -Key.getFrame(); }); pointercontainer.addEventListener('touchmove', (e:js.html.TouchEvent) -> { diff --git a/src/gui/GuiConsoleScrollCtrl.hx b/src/gui/GuiConsoleScrollCtrl.hx index b4fae0e2..4312c095 100644 --- a/src/gui/GuiConsoleScrollCtrl.hx +++ b/src/gui/GuiConsoleScrollCtrl.hx @@ -10,6 +10,7 @@ import h2d.Tile; import h2d.Graphics; import src.MarbleGame; import src.Util; +import haxe.Timer; class GuiConsoleScrollCtrl extends GuiControl { public var scrollY:Float = 0; @@ -43,6 +44,11 @@ class GuiConsoleScrollCtrl extends GuiControl { var scrollUpButton:GuiButton; var scrollDownButton:GuiButton; + var scrollVelocity:Float = 0; + var lastMoveStamp:Float = 0; + var momentumActive:Bool = false; + + static inline var MOMENTUM_DAMPING:Float = 8; public function new(scrollBar:Tile) { super(); @@ -261,6 +267,9 @@ class GuiConsoleScrollCtrl extends GuiControl { this.dirty = true; this.updateScrollVisual(); this.prevMousePos = mouseState.position; + this.scrollVelocity = 0; + this.momentumActive = false; + this.lastMoveStamp = Timer.stamp(); } } @@ -269,6 +278,18 @@ class GuiConsoleScrollCtrl extends GuiControl { this.pressed = false; this.dirty = true; this.updateScrollVisual(); + this.momentumActive = Math.abs(scrollVelocity) > 0.01; + this.lastMoveStamp = 0; + } + } + + public override function onMouseLeave(mouseState:MouseState) { + if (Util.isTouchDevice()) { + this.pressed = false; + this.dirty = true; + this.updateScrollVisual(); + this.momentumActive = Math.abs(scrollVelocity) > 0.01; + this.lastMoveStamp = 0; } } @@ -276,14 +297,42 @@ class GuiConsoleScrollCtrl extends GuiControl { if (Util.isTouchDevice()) { super.onMouseMove(mouseState); if (this.pressed) { - var dy = mouseState.position.y - this.prevMousePos.y; + var renderRect = this.getRenderRectangle(); + var scrollExtentY = renderRect.extent.y - 34 * Settings.uiScale; + var dy = (mouseState.position.y - this.prevMousePos.y) / ((maxScrollY * Settings.uiScale) / scrollExtentY); this.scrollY -= dy; this.prevMousePos = mouseState.position; + var now = Timer.stamp(); + if (lastMoveStamp > 0) { + var dt = now - lastMoveStamp; + if (dt > 0) + scrollVelocity = -dy / dt; + } + lastMoveStamp = now; + momentumActive = false; this.updateScrollVisual(); } } } + public override function update(dt:Float, mouseState:MouseState) { + super.update(dt, mouseState); + if (!pressed && momentumActive) { + var damping = Math.exp(-MOMENTUM_DAMPING * dt); + scrollVelocity *= damping; + if (Math.abs(scrollVelocity) < 0.01) { + scrollVelocity = 0; + momentumActive = false; + return; + } + var before = scrollY; + scrollY += scrollVelocity * dt; + updateScrollVisual(); + if (scrollY == 0 || scrollY == before) + momentumActive = false; + } + } + // public override function onMouseDown(mouseState:MouseState) { // var renderRect = this.getHitTestRect(); // if (mouseState.position.x >= renderRect.position.x + renderRect.extent.x - 10) {