Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

smooth scroll/inertial scrolling/momentum scroll

I have an OpenGL ES View in Android thats controlled by a matrix for translation. Im trying to figure out a way to get a hint of momentum scrolling as seen in the google maps app or the iPhone. Thanks.

like image 689
jfisk Avatar asked Feb 03 '23 23:02

jfisk


2 Answers

If your problem is in 2d, it is quite simple

  1. You need to get the elapsed time in each frame
  2. Your onTouch function will find the acceleration of your finger. I forgot the formula on how to get the acceleration from a distance. It should be the second derivative of position with a time variable. But you should always convert your deltaX, deltaY in acceleration. To make it easy you don't really need to put something accurate there. Edit: I don't know why I didn't see it but the function was all there...

    acceleration.x = 2(newposition.x - position.x - speed.x * elapsedTime) / (elapsedTime * elapsedTime);

  3. Once you have your acceleration you can set your new position with that code. This is simple physic dynamics in 2d. With your acceleration you can find your speed and with your speed you can find your next position.

    speed.x = (float) (mass * acceleration.x * elapsed + speed.x);
    speed.y = (float) (mass * acceleration.y * elapsed + speed.y);
    
    
    position.x += mass * acceleration.x / 2 * elapsed * elapsed + speed.x * elapsed;
    position.y += mass * acceleration.y / 2 * elapsed * elapsed + speed.y * elapsed;
    
    
    speed.x *= friction;
    speed.y *= friction;
    

Mass and friction will let you define how fast it goes and how fast it will slow down by itself. You probably will have to tweak the code because this dynamic isn't exactly nice if you have to have to scroll backward to slow down.

At the end of each frame, you will have to reset your acceleration to (0,0). And on each new frame after a touch even, the acceleration should be set to something. It should work very well :)

like image 118
Loïc Faure-Lacroix Avatar answered Feb 06 '23 16:02

Loïc Faure-Lacroix


  1. Measure the speed that the view is scrolling at.
  2. Detect when the user stops scrolling.
  3. Gradually decrease the speed that the scroll view is scrolling at.

Something like this:

public void redraw() {
    myScrollView.ySpeed = myScrollView.lastY-myScrollView.y;
    myScrollView.xSpeed = myScrollView.lastX-myScrollView.x;
    if (!userIsScrolling && ySpeed > 0) {
        ySpeed--;
    }
    if (!userIsScrolling && xSpeed > 0) {
        xSpeed--;
    }
    myScrollView.lastY = myScrollView.y;
    myScrollView.y += ySpeed;
    myScrollView.lastX = myScrollView.x;
    myScrollView.x += xSpeed;
}

public void userStoppedScrolling() {
    userIsScrolling = false;
}
like image 37
Jumhyn Avatar answered Feb 06 '23 16:02

Jumhyn