package com.github.mikephil.charting.animation; /** * Easing options. * * @author Daniel Cohen Gindi */ public class Easing { /** * Use EasingOption instead of EasingFunction to avoid crashes below Android * 3.0 */ public enum EasingOption { Linear, EaseInQuad, EaseOutQuad, EaseInOutQuad, EaseInCubic, EaseOutCubic, EaseInOutCubic, EaseInQuart, EaseOutQuart, EaseInOutQuart, EaseInSine, EaseOutSine, EaseInOutSine, EaseInExpo, EaseOutExpo, EaseInOutExpo, EaseInCirc, EaseOutCirc, EaseInOutCirc, EaseInElastic, EaseOutElastic, EaseInOutElastic, EaseInBack, EaseOutBack, EaseInOutBack, EaseInBounce, EaseOutBounce, EaseInOutBounce, } public static EasingFunction getEasingFunctionFromOption(EasingOption easing) { switch (easing) { default: case Linear: return EasingFunctions.Linear; case EaseInQuad: return EasingFunctions.EaseInQuad; case EaseOutQuad: return EasingFunctions.EaseOutQuad; case EaseInOutQuad: return EasingFunctions.EaseInOutQuad; case EaseInCubic: return EasingFunctions.EaseInCubic; case EaseOutCubic: return EasingFunctions.EaseOutCubic; case EaseInOutCubic: return EasingFunctions.EaseInOutCubic; case EaseInQuart: return EasingFunctions.EaseInQuart; case EaseOutQuart: return EasingFunctions.EaseOutQuart; case EaseInOutQuart: return EasingFunctions.EaseInOutQuart; case EaseInSine: return EasingFunctions.EaseInSine; case EaseOutSine: return EasingFunctions.EaseOutSine; case EaseInOutSine: return EasingFunctions.EaseInOutSine; case EaseInExpo: return EasingFunctions.EaseInExpo; case EaseOutExpo: return EasingFunctions.EaseOutExpo; case EaseInOutExpo: return EasingFunctions.EaseInOutExpo; case EaseInCirc: return EasingFunctions.EaseInCirc; case EaseOutCirc: return EasingFunctions.EaseOutCirc; case EaseInOutCirc: return EasingFunctions.EaseInOutCirc; case EaseInElastic: return EasingFunctions.EaseInElastic; case EaseOutElastic: return EasingFunctions.EaseOutElastic; case EaseInOutElastic: return EasingFunctions.EaseInOutElastic; case EaseInBack: return EasingFunctions.EaseInBack; case EaseOutBack: return EasingFunctions.EaseOutBack; case EaseInOutBack: return EasingFunctions.EaseInOutBack; case EaseInBounce: return EasingFunctions.EaseInBounce; case EaseOutBounce: return EasingFunctions.EaseOutBounce; case EaseInOutBounce: return EasingFunctions.EaseInOutBounce; } } private static class EasingFunctions { /** * ########## ########## ########## ########## ########## ########## * PREDEFINED EASING FUNCTIONS BELOW THIS */ public static final EasingFunction Linear = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // return elapsed / (float) duration; // } @Override public float getInterpolation(float input) { return input; } }; public static final EasingFunction EaseInQuad = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // return position * position; // } @Override public float getInterpolation(float input) { return input * input; } }; public static final EasingFunction EaseOutQuad = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // return -position * (position - 2.f); // } @Override public float getInterpolation(float input) { return -input * (input - 2f); } }; public static final EasingFunction EaseInOutQuad = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (duration / 2.f); // if (position < 1.f) // { // return 0.5f * position * position; // } // return -0.5f * ((--position) * (position - 2.f) - 1.f); // } @Override public float getInterpolation(float input) { float position = input / 0.5f; if (position < 1.f) { return 0.5f * position * position; } return -0.5f * ((--position) * (position - 2.f) - 1.f); } }; public static final EasingFunction EaseInCubic = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // return position * position * position; // } @Override public float getInterpolation(float input) { return input * input * input; } }; public static final EasingFunction EaseOutCubic = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // position--; // return (position * position * position + 1.f); // } @Override public float getInterpolation(float input) { input--; return (input * input * input + 1.f); } }; public static final EasingFunction EaseInOutCubic = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (duration / 2.f); // if (position < 1.f) // { // return 0.5f * position * position * position; // } // position -= 2.f; // return 0.5f * (position * position * position + 2.f); // } @Override public float getInterpolation(float input) { float position = input / 0.5f; if (position < 1.f) { return 0.5f * position * position * position; } position -= 2.f; return 0.5f * (position * position * position + 2.f); } }; public static final EasingFunction EaseInQuart = new EasingFunction() { public float getInterpolation(float input) { return input * input * input * input; } }; public static final EasingFunction EaseOutQuart = new EasingFunction() { public float getInterpolation(float input) { input--; return -(input * input * input * input - 1f); } }; public static final EasingFunction EaseInOutQuart = new EasingFunction() { @Override public float getInterpolation(float input) { float position = input / 0.5f; if (position < 1.f) { return 0.5f * position * position * position * position; } position -= 2.f; return -0.5f * (position * position * position * position - 2.f); } }; public static final EasingFunction EaseInSine = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // return -(float) Math.cos(position * (Math.PI / 2.f)) + 1.f; // } @Override public float getInterpolation(float input) { return -(float) Math.cos(input * (Math.PI / 2.f)) + 1.f; } }; public static final EasingFunction EaseOutSine = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // return (float) Math.sin(position * (Math.PI / 2.f)); // } @Override public float getInterpolation(float input) { return (float) Math.sin(input * (Math.PI / 2.f)); } }; public static final EasingFunction EaseInOutSine = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // return -0.5f * ((float) Math.cos(Math.PI * position) - 1.f); // } @Override public float getInterpolation(float input) { return -0.5f * ((float) Math.cos(Math.PI * input) - 1.f); } }; public static final EasingFunction EaseInExpo = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // return (elapsed == 0) ? 0.f : (float) Math.pow(2.f, 10.f * (elapsed // / (float) duration - 1.f)); // } @Override public float getInterpolation(float input) { return (input == 0) ? 0.f : (float) Math.pow(2.f, 10.f * (input - 1.f)); } }; public static final EasingFunction EaseOutExpo = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // return (elapsed == duration) ? 1.f : (-(float) Math.pow(2.f, -10.f * // elapsed // / (float) duration) + 1.f); // } @Override public float getInterpolation(float input) { return (input == 1f) ? 1.f : (-(float) Math.pow(2.f, -10.f * (input + 1.f))); } }; public static final EasingFunction EaseInOutExpo = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // if (elapsed == 0) // { // return 0.f; // } // if (elapsed == duration) // { // return 1.f; // } // // float position = elapsed / (duration / 2.f); // if (position < 1.f) // { // return 0.5f * (float) Math.pow(2.f, 10.f * (position - 1.f)); // } // return 0.5f * (-(float) Math.pow(2.f, -10.f * --position) + // 2.f); // } @Override public float getInterpolation(float input) { if (input == 0) { return 0.f; } if (input == 1f) { return 1.f; } float position = input / 0.5f; if (position < 1.f) { return 0.5f * (float) Math.pow(2.f, 10.f * (position - 1.f)); } return 0.5f * (-(float) Math.pow(2.f, -10.f * --position) + 2.f); } }; public static final EasingFunction EaseInCirc = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // return -((float) Math.sqrt(1.f - position * position) - 1.f); // } @Override public float getInterpolation(float input) { return -((float) Math.sqrt(1.f - input * input) - 1.f); } }; public static final EasingFunction EaseOutCirc = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // position--; // return (float) Math.sqrt(1.f - position * position); // } @Override public float getInterpolation(float input) { input--; return (float) Math.sqrt(1.f - input * input); } }; public static final EasingFunction EaseInOutCirc = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (duration / 2.f); // if (position < 1.f) // { // return -0.5f * ((float) Math.sqrt(1.f - position * position) // - 1.f); // } // return 0.5f * ((float) Math.sqrt(1.f - (position -= 2.f) * // position) // + 1.f); // } @Override public float getInterpolation(float input) { float position = input / 0.5f; if (position < 1.f) { return -0.5f * ((float) Math.sqrt(1.f - position * position) - 1.f); } return 0.5f * ((float) Math.sqrt(1.f - (position -= 2.f) * position) + 1.f); } }; public static final EasingFunction EaseInElastic = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // if (elapsed == 0) // { // return 0.f; // } // // float position = elapsed / (float) duration; // if (position == 1) // { // return 1.f; // } // // float p = duration * .3f; // float s = p / (2.f * (float) Math.PI) * (float) // Math.asin(1.f); // return -((float) Math.pow(2.f, 10.f * (position -= 1.f)) * // (float) // Math // .sin((position * duration - s) * (2.f * Math.PI) / p)); // } @Override public float getInterpolation(float input) { if (input == 0) { return 0.f; } float position = input; if (position == 1) { return 1.f; } float p = .3f; float s = p / (2.f * (float) Math.PI) * (float) Math.asin(1.f); return -((float) Math.pow(2.f, 10.f * (position -= 1.f)) * (float) Math .sin((position - s) * (2.f * Math.PI) / p)); } }; public static final EasingFunction EaseOutElastic = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // if (elapsed == 0) // { // return 0.f; // } // // float position = elapsed / (float) duration; // if (position == 1) // { // return 1.f; // } // // float p = duration * .3f; // float s = p / (2 * (float) Math.PI) * (float) Math.asin(1.f); // return (float) Math.pow(2, -10 * position) // * (float) Math.sin((position * duration - s) * (2.f * // Math.PI) / p) + // 1.f; // } @Override public float getInterpolation(float input) { if (input == 0) { return 0.f; } float position = input; if (position == 1) { return 1.f; } float p = .3f; float s = p / (2 * (float) Math.PI) * (float) Math.asin(1.f); return (float) Math.pow(2, -10 * position) * (float) Math.sin((position - s) * (2.f * Math.PI) / p) + 1.f; } }; public static final EasingFunction EaseInOutElastic = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // if (elapsed == 0) // { // return 0.f; // } // // float position = elapsed / (duration / 2.f); // if (position == 2) // { // return 1.f; // } // // float p = duration * (.3f * 1.5f); // float s = p / (2.f * (float) Math.PI) * (float) // Math.asin(1.f); // if (position < 1.f) // { // return -.5f // * ((float) Math.pow(2.f, 10.f * (position -= 1.f)) * (float) // Math // .sin((position * duration - s) * (2.f * Math.PI) / p)); // } // return (float) Math.pow(2.f, -10.f * (position -= 1.f)) // * (float) Math.sin((position * duration - s) * (2.f * // Math.PI) / p) * // .5f // + 1.f; // } @Override public float getInterpolation(float input) { if (input == 0) { return 0.f; } float position = input / 0.5f; if (position == 2) { return 1.f; } float p = (.3f * 1.5f); float s = p / (2.f * (float) Math.PI) * (float) Math.asin(1.f); if (position < 1.f) { return -.5f * ((float) Math.pow(2.f, 10.f * (position -= 1.f)) * (float) Math .sin((position * 1f - s) * (2.f * Math.PI) / p)); } return (float) Math.pow(2.f, -10.f * (position -= 1.f)) * (float) Math.sin((position * 1f - s) * (2.f * Math.PI) / p) * .5f + 1.f; } }; public static final EasingFunction EaseInBack = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // final float s = 1.70158f; // float position = elapsed / (float) duration; // return position * position * ((s + 1.f) * position - s); // } @Override public float getInterpolation(float input) { final float s = 1.70158f; float position = input; return position * position * ((s + 1.f) * position - s); } }; public static final EasingFunction EaseOutBack = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // final float s = 1.70158f; // float position = elapsed / (float) duration; // position--; // return (position * position * ((s + 1.f) * position + s) + 1.f); // } @Override public float getInterpolation(float input) { final float s = 1.70158f; float position = input; position--; return (position * position * ((s + 1.f) * position + s) + 1.f); } }; public static final EasingFunction EaseInOutBack = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float s = 1.70158f; // float position = elapsed / (duration / 2.f); // if (position < 1.f) // { // return 0.5f * (position * position * (((s *= (1.525f)) + 1.f) // * // position - s)); // } // return 0.5f * ((position -= 2.f) * position // * (((s *= (1.525f)) + 1.f) * position + s) + 2.f); // } @Override public float getInterpolation(float input) { float s = 1.70158f; float position = input / 0.5f; if (position < 1.f) { return 0.5f * (position * position * (((s *= (1.525f)) + 1.f) * position - s)); } return 0.5f * ((position -= 2.f) * position * (((s *= (1.525f)) + 1.f) * position + s) + 2.f); } }; public static final EasingFunction EaseInBounce = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // return 1.f - EaseOutBounce.ease(duration - elapsed, // duration); // } @Override public float getInterpolation(float input) { return 1.f - EaseOutBounce.getInterpolation(1f - input); } }; public static final EasingFunction EaseOutBounce = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // float position = elapsed / (float) duration; // if (position < (1.f / 2.75f)) // { // return (7.5625f * position * position); // } // else if (position < (2.f / 2.75f)) // { // return (7.5625f * (position -= (1.5f / 2.75f)) * position + // .75f); // } // else if (position < (2.5f / 2.75f)) // { // return (7.5625f * (position -= (2.25f / 2.75f)) * position + // .9375f); // } // else // { // return (7.5625f * (position -= (2.625f / 2.75f)) * position + // .984375f); // } // } @Override public float getInterpolation(float input) { float position = input; if (position < (1.f / 2.75f)) { return (7.5625f * position * position); } else if (position < (2.f / 2.75f)) { return (7.5625f * (position -= (1.5f / 2.75f)) * position + .75f); } else if (position < (2.5f / 2.75f)) { return (7.5625f * (position -= (2.25f / 2.75f)) * position + .9375f); } else { return (7.5625f * (position -= (2.625f / 2.75f)) * position + .984375f); } } }; public static final EasingFunction EaseInOutBounce = new EasingFunction() { // @Override // public float ease(long elapsed, long duration) { // if (elapsed < duration / 2.f) // { // return EaseInBounce.ease(elapsed * 2, duration) * .5f; // } // return EaseOutBounce.ease(elapsed * 2 - duration, duration) * // .5f + // .5f; // } @Override public float getInterpolation(float input) { if (input < 0.5f) { return EaseInBounce.getInterpolation(input * 2) * .5f; } return EaseOutBounce.getInterpolation(input * 2 - 1f) * .5f + .5f; } }; } }