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