-->

分類

2016年3月24日 星期四

Android OverScroller, SplineScroller

source code
SplinerScroller做了一個類似在算Cubic Bezier Curve的東西, 只是這邊他不是算B(t)的值而是從已知B(x)的值去算t, 這裡利用t是strictly ascending的特性所以x min可以不用reset而x max需每次reset成1.0, 利用x = (x min + x max) / 2代入cubic bezier curve去看B(x)是否夠接近所求之值, 不夠則根據算出的B(x)修改x min, x max, 求出之各x存起來做為Spline interpolation之用(這段就看不太懂了)
(Wiki裡的t就是x)
Wiki Bezier

static {
            float x_min = 0.0f;
            float y_min = 0.0f;
            for (int i = 0; i < NB_SAMPLES; i++) {
                final float alpha = (float) i / NB_SAMPLES;

                float x_max = 1.0f;
                float x, tx, coef;
                while (true) {
                    x = x_min + (x_max - x_min) / 2.0f;
                    coef = 3.0f * x * (1.0f - x);
                    tx = coef * ((1.0f - x) * P1 + x * P2) + x * x * x;
                    if (Math.abs(tx - alpha) < 1E-5) break;
                    if (tx > alpha) x_max = x;
                    else x_min = x;
                }
                SPLINE_POSITION[i] = coef * ((1.0f - x) * START_TENSION + x) + x * x * x;

                float y_max = 1.0f;
                float y, dy;
                while (true) {
                    y = y_min + (y_max - y_min) / 2.0f;
                    coef = 3.0f * y * (1.0f - y);
                    dy = coef * ((1.0f - y) * START_TENSION + y) + y * y * y;
                    if (Math.abs(dy - alpha) < 1E-5) break;
                    if (dy > alpha) y_max = y;
                    else y_min = y;
                }
                SPLINE_TIME[i] = coef * ((1.0f - y) * P1 + y * P2) + y * y * y;
            }
            SPLINE_POSITION[NB_SAMPLES] = SPLINE_TIME[NB_SAMPLES] = 1.0f;
        }

實際使用OverScroller時就是view在computeScroll時不斷invalidate直到scroller認為scroll結束

@Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            // This is called at drawing time by ViewGroup.  We use
            // this method to keep the fling animation going through
            // to completion.
            int x = mScroller.getCurrX();
            int y = mScroller.getCurrY();

            scrollTo(x, y);

            // Keep on drawing until the animation has finished.
            postInvalidate();
        }
    }

沒有留言:

張貼留言