平滑滚动/惯性滚动/动量滚动

发布于 2024-10-09 15:25:17 字数 96 浏览 0 评论 0原文

我在 Android 中有一个由翻译矩阵控制的 OpenGL ES 视图。我试图找出一种方法来获得一点动力滚动的感觉,就像在谷歌地图应用程序或 iPhone 中看到的那样。谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难以启齿的温柔 2024-10-16 15:25:17

如果你的问题是二维的,那很简单

  1. 你需要获取每一帧中经过的时间
  2. 你的onTouch函数将找到你手指的加速度。我忘记了如何获得远距离加速度的公式。它应该是位置对时间变量的二阶导数。但您应该始终将 deltaX、deltaY 转换为加速度。为了方便起见,您实际上不需要在那里放置准确的内容。编辑:我不知道为什么我没有看到它,但功能都在那里......

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

  3. 获得加速度后,您可以使用该代码设置新位置。这是简单的二维物理动力学。通过你的加速度,你可以找到你的速度,通过你的速度,你可以找到你的下一个位置。

    speed.x = (float) (质量 * 加速度.x * 经过 + 速度.x);
    speed.y = (float) (质量 * 加速度.y * 经过 + 速度.y);
    
    
    位置.x += 质量 * 加速度.x / 2 * 已过去 * 已过去 + 速度.x * 已过去;
    位置.y += 质量 * 加速度.y / 2 * 经过 * 经过 + 速度.y * 经过;
    
    
    速度.x *= 摩擦力;
    速度.y *= 摩擦力;
    

质量和摩擦力可以让你定义它的行驶速度以及它自身减速的速度。您可能需要调整代码,因为如果您必须向后滚动才能减慢速度,那么这种动态就不太好。

在每一帧结束时,您必须将加速度重置为 (0,0)。即使在触摸后的每个新帧上,也应将加速度设置为某个值。它应该工作得很好:)

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 :)

愁杀 2024-10-16 15:25:17
  1. 测量视图滚动的速度。
  2. 检测用户何时停止滚动。
  3. 逐渐降低滚动视图的滚动速度。

像这样的东西:

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;
}
  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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文