package com.tencent.util;
/**
* 粘性流体算法. 从scroller里扣出来的. 使用这个算法处理滚动
* 视觉效果会比AccelerateDecelerateInterpolator视觉效果要好
*
*
*/
public final class AnimateUtils
{
private static float START_TENSION = 0.4f; // Tension at start: (0.4 * total T, 1.0 * Distance)
private static float END_TENSION = 1.0f - START_TENSION;
private static final int NB_SAMPLES = 100;
private static final float[] SPLINE = new float[NB_SAMPLES + 1];
private static float sViscousFluidScale;
private static float sViscousFluidNormalize;
static
{
float x_min = 0.0f;
for (int i = 0; i <= NB_SAMPLES; i++)
{
final float t = (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) * START_TENSION + x * END_TENSION) + x * x * x;
if (Math.abs(tx - t) < 1E-5)
break;
if (tx > t)
x_max = x;
else
x_min = x;
}
final float d = coef + x * x * x;
SPLINE[i] = d;
}
SPLINE[NB_SAMPLES] = 1.0f;
// This controls the viscous fluid effect (how much of it)
sViscousFluidScale = 8.0f;
// must be set to 1.0 (used in viscousFluid())
sViscousFluidNormalize = 1.0f;
sViscousFluidNormalize = 1.0f / viscousFluid(1.0f);
}
private AnimateUtils()
{
}
/**
* for滚动动画, 这个算法会比较平滑
*
* @param x
* @return
*/
public static float viscousFluid(float x)
{
x *= sViscousFluidScale;
if (x < 1.0f)
{
x -= (1.0f - (float) Math.exp(-x));
}
else
{
float start = 0.36787944117f; // 1/e == exp(-1)
x = 1.0f - (float) Math.exp(1.0f - x);
x = start + x * (1.0f - start);
}
x *= sViscousFluidNormalize;
return x;
}
}