mirror of https://github.com/NekoX-Dev/NekoX.git
75 lines
2.6 KiB
Java
75 lines
2.6 KiB
Java
package org.telegram.ui.Components;
|
|
|
|
import android.graphics.PointF;
|
|
import android.view.animation.Interpolator;
|
|
|
|
public class CubicBezierInterpolator implements Interpolator {
|
|
|
|
public static final CubicBezierInterpolator DEFAULT = new CubicBezierInterpolator(0.25, 0.1, 0.25, 1);
|
|
public static final CubicBezierInterpolator EASE_OUT = new CubicBezierInterpolator(0, 0, .58, 1);
|
|
public static final CubicBezierInterpolator EASE_OUT_QUINT = new CubicBezierInterpolator(.23, 1, .32, 1);
|
|
public static final CubicBezierInterpolator EASE_IN = new CubicBezierInterpolator(.42, 0, 1, 1);
|
|
public static final CubicBezierInterpolator EASE_BOTH = new CubicBezierInterpolator(.42, 0, .58, 1);
|
|
|
|
protected PointF start;
|
|
protected PointF end;
|
|
protected PointF a = new PointF();
|
|
protected PointF b = new PointF();
|
|
protected PointF c = new PointF();
|
|
|
|
public CubicBezierInterpolator(PointF start, PointF end) throws IllegalArgumentException {
|
|
if (start.x < 0 || start.x > 1) {
|
|
throw new IllegalArgumentException("startX value must be in the range [0, 1]");
|
|
}
|
|
if (end.x < 0 || end.x > 1) {
|
|
throw new IllegalArgumentException("endX value must be in the range [0, 1]");
|
|
}
|
|
this.start = start;
|
|
this.end = end;
|
|
}
|
|
|
|
public CubicBezierInterpolator(float startX, float startY, float endX, float endY) {
|
|
this(new PointF(startX, startY), new PointF(endX, endY));
|
|
}
|
|
|
|
public CubicBezierInterpolator(double startX, double startY, double endX, double endY) {
|
|
this((float) startX, (float) startY, (float) endX, (float) endY);
|
|
}
|
|
|
|
@Override
|
|
public float getInterpolation(float time) {
|
|
return getBezierCoordinateY(getXForTime(time));
|
|
}
|
|
|
|
protected float getBezierCoordinateY(float time) {
|
|
c.y = 3 * start.y;
|
|
b.y = 3 * (end.y - start.y) - c.y;
|
|
a.y = 1 - c.y - b.y;
|
|
return time * (c.y + time * (b.y + time * a.y));
|
|
}
|
|
|
|
protected float getXForTime(float time) {
|
|
float x = time;
|
|
float z;
|
|
for (int i = 1; i < 14; i++) {
|
|
z = getBezierCoordinateX(x) - time;
|
|
if (Math.abs(z) < 1e-3) {
|
|
break;
|
|
}
|
|
x -= z / getXDerivate(x);
|
|
}
|
|
return x;
|
|
}
|
|
|
|
private float getXDerivate(float t) {
|
|
return c.x + t * (2 * b.x + 3 * a.x * t);
|
|
}
|
|
|
|
private float getBezierCoordinateX(float time) {
|
|
c.x = 3 * start.x;
|
|
b.x = 3 * (end.x - start.x) - c.x;
|
|
a.x = 1 - c.x - b.x;
|
|
return time * (c.x + time * (b.x + time * a.x));
|
|
}
|
|
}
|