1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.animation; 18 19 import android.graphics.Path; 20 import android.util.MathUtils; 21 import android.view.animation.AccelerateDecelerateInterpolator; 22 import android.view.animation.AccelerateInterpolator; 23 import android.view.animation.BounceInterpolator; 24 import android.view.animation.DecelerateInterpolator; 25 import android.view.animation.Interpolator; 26 import android.view.animation.LinearInterpolator; 27 import android.view.animation.PathInterpolator; 28 29 /** 30 * Utility class to receive interpolators from 31 */ 32 public class Interpolators { 33 34 /* 35 * ============================================================================================ 36 * Emphasized interpolators. 37 * ============================================================================================ 38 */ 39 40 /** 41 * The default emphasized interpolator. Used for hero / emphasized movement of content. 42 */ 43 public static final Interpolator EMPHASIZED = createEmphasizedInterpolator(); 44 45 /** 46 * The accelerated emphasized interpolator. Used for hero / emphasized movement of content that 47 * is disappearing e.g. when moving off screen. 48 */ 49 public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator( 50 0.3f, 0f, 0.8f, 0.15f); 51 52 /** 53 * The decelerating emphasized interpolator. Used for hero / emphasized movement of content that 54 * is appearing e.g. when coming from off screen 55 */ 56 public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator( 57 0.05f, 0.7f, 0.1f, 1f); 58 59 60 /* 61 * ============================================================================================ 62 * Standard interpolators. 63 * ============================================================================================ 64 */ 65 66 /** 67 * The standard interpolator that should be used on every normal animation 68 */ 69 public static final Interpolator STANDARD = new PathInterpolator( 70 0.2f, 0f, 0f, 1f); 71 72 /** 73 * The standard accelerating interpolator that should be used on every regular movement of 74 * content that is disappearing e.g. when moving off screen. 75 */ 76 public static final Interpolator STANDARD_ACCELERATE = new PathInterpolator( 77 0.3f, 0f, 1f, 1f); 78 79 /** 80 * The standard decelerating interpolator that should be used on every regular movement of 81 * content that is appearing e.g. when coming from off screen. 82 */ 83 public static final Interpolator STANDARD_DECELERATE = new PathInterpolator( 84 0f, 0f, 0f, 1f); 85 86 /* 87 * ============================================================================================ 88 * Legacy 89 * ============================================================================================ 90 */ 91 92 /** 93 * The default legacy interpolator as defined in Material 1. Also known as FAST_OUT_SLOW_IN. 94 */ 95 public static final Interpolator LEGACY = new PathInterpolator(0.4f, 0f, 0.2f, 1f); 96 97 /** 98 * The default legacy accelerating interpolator as defined in Material 1. 99 * Also known as FAST_OUT_LINEAR_IN. 100 */ 101 public static final Interpolator LEGACY_ACCELERATE = new PathInterpolator(0.4f, 0f, 1f, 1f); 102 103 /** 104 * The default legacy decelerating interpolator as defined in Material 1. 105 * Also known as LINEAR_OUT_SLOW_IN. 106 */ 107 public static final Interpolator LEGACY_DECELERATE = new PathInterpolator(0f, 0f, 0.2f, 1f); 108 109 /** 110 * Linear interpolator. Often used if the interpolator is for different properties who need 111 * different interpolations. 112 */ 113 public static final Interpolator LINEAR = new LinearInterpolator(); 114 115 /* 116 * ============================================================================================ 117 * Custom interpolators 118 * ============================================================================================ 119 */ 120 121 public static final Interpolator FAST_OUT_SLOW_IN = LEGACY; 122 public static final Interpolator FAST_OUT_LINEAR_IN = LEGACY_ACCELERATE; 123 public static final Interpolator LINEAR_OUT_SLOW_IN = LEGACY_DECELERATE; 124 125 /** 126 * Like {@link #FAST_OUT_SLOW_IN}, but used in case the animation is played in reverse (i.e. t 127 * goes from 1 to 0 instead of 0 to 1). 128 */ 129 public static final Interpolator FAST_OUT_SLOW_IN_REVERSE = 130 new PathInterpolator(0.8f, 0f, 0.6f, 1f); 131 public static final Interpolator SLOW_OUT_LINEAR_IN = new PathInterpolator(0.8f, 0f, 1f, 1f); 132 public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); 133 public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f); 134 public static final Interpolator ACCELERATE = new AccelerateInterpolator(); 135 public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator(); 136 public static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f); 137 public static final Interpolator CUSTOM_40_40 = new PathInterpolator(0.4f, 0f, 0.6f, 1f); 138 public static final Interpolator ICON_OVERSHOT = new PathInterpolator(0.4f, 0f, 0.2f, 1.4f); 139 public static final Interpolator ICON_OVERSHOT_LESS = new PathInterpolator(0.4f, 0f, 0.2f, 140 1.1f); 141 public static final Interpolator PANEL_CLOSE_ACCELERATED = new PathInterpolator(0.3f, 0, 0.5f, 142 1); 143 public static final Interpolator BOUNCE = new BounceInterpolator(); 144 /** 145 * For state transitions on the control panel that lives in GlobalActions. 146 */ 147 public static final Interpolator CONTROL_STATE = new PathInterpolator(0.4f, 0f, 0.2f, 148 1.0f); 149 150 /** 151 * Interpolator to be used when animating a move based on a click. Pair with enough duration. 152 */ 153 public static final Interpolator TOUCH_RESPONSE = 154 new PathInterpolator(0.3f, 0f, 0.1f, 1f); 155 156 /** 157 * Like {@link #TOUCH_RESPONSE}, but used in case the animation is played in reverse (i.e. t 158 * goes from 1 to 0 instead of 0 to 1). 159 */ 160 public static final Interpolator TOUCH_RESPONSE_REVERSE = 161 new PathInterpolator(0.9f, 0f, 0.7f, 1f); 162 163 /* 164 * ============================================================================================ 165 * Functions / Utilities 166 * ============================================================================================ 167 */ 168 169 /** 170 * Calculate the amount of overshoot using an exponential falloff function with desired 171 * properties, where the overshoot smoothly transitions at the 1.0f boundary into the 172 * overshoot, retaining its acceleration. 173 * 174 * @param progress a progress value going from 0 to 1 175 * @param overshootAmount the amount > 0 of overshoot desired. A value of 0.1 means the max 176 * value of the overall progress will be at 1.1. 177 * @param overshootStart the point in (0,1] where the result should reach 1 178 * @return the interpolated overshoot 179 */ getOvershootInterpolation(float progress, float overshootAmount, float overshootStart)180 public static float getOvershootInterpolation(float progress, float overshootAmount, 181 float overshootStart) { 182 if (overshootAmount == 0.0f || overshootStart == 0.0f) { 183 throw new IllegalArgumentException("Invalid values for overshoot"); 184 } 185 float b = MathUtils.log((overshootAmount + 1) / (overshootAmount)) / overshootStart; 186 return MathUtils.max(0.0f, 187 (float) (1.0f - Math.exp(-b * progress)) * (overshootAmount + 1.0f)); 188 } 189 190 /** 191 * Similar to {@link #getOvershootInterpolation(float, float, float)} but the overshoot 192 * starts immediately here, instead of first having a section of non-overshooting 193 * 194 * @param progress a progress value going from 0 to 1 195 */ getOvershootInterpolation(float progress)196 public static float getOvershootInterpolation(float progress) { 197 return MathUtils.max(0.0f, (float) (1.0f - Math.exp(-4 * progress))); 198 } 199 200 // Create the default emphasized interpolator createEmphasizedInterpolator()201 private static PathInterpolator createEmphasizedInterpolator() { 202 Path path = new Path(); 203 // Doing the same as fast_out_extra_slow_in 204 path.moveTo(0f, 0f); 205 path.cubicTo(0.05f, 0f, 0.133333f, 0.06f, 0.166666f, 0.4f); 206 path.cubicTo(0.208333f, 0.82f, 0.25f, 1f, 1f, 1f); 207 return new PathInterpolator(path); 208 } 209 } 210