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(); } }
沒有留言:
張貼留言