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.util.MathUtils; 20 import android.view.animation.AccelerateDecelerateInterpolator; 21 import android.view.animation.AccelerateInterpolator; 22 import android.view.animation.BounceInterpolator; 23 import android.view.animation.DecelerateInterpolator; 24 import android.view.animation.Interpolator; 25 import android.view.animation.LinearInterpolator; 26 import android.view.animation.PathInterpolator; 27 28 /** 29 * Utility class to receive interpolators from 30 */ 31 public class Interpolators { 32 public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f); 33 34 /** 35 * Like {@link #FAST_OUT_SLOW_IN}, but used in case the animation is played in reverse (i.e. t 36 * goes from 1 to 0 instead of 0 to 1). 37 */ 38 public static final Interpolator FAST_OUT_SLOW_IN_REVERSE = 39 new PathInterpolator(0.8f, 0f, 0.6f, 1f); 40 public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); 41 public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f); 42 public static final Interpolator SLOW_OUT_LINEAR_IN = new PathInterpolator(0.8f, 0f, 1f, 1f); 43 public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); 44 public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f); 45 public static final Interpolator LINEAR = new LinearInterpolator(); 46 public static final Interpolator ACCELERATE = new AccelerateInterpolator(); 47 public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator(); 48 public static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f); 49 public static final Interpolator CUSTOM_40_40 = new PathInterpolator(0.4f, 0f, 0.6f, 1f); 50 public static final Interpolator ICON_OVERSHOT = new PathInterpolator(0.4f, 0f, 0.2f, 1.4f); 51 public static final Interpolator ICON_OVERSHOT_LESS = new PathInterpolator(0.4f, 0f, 0.2f, 52 1.1f); 53 public static final Interpolator PANEL_CLOSE_ACCELERATED = new PathInterpolator(0.3f, 0, 0.5f, 54 1); 55 public static final Interpolator BOUNCE = new BounceInterpolator(); 56 /** 57 * For state transitions on the control panel that lives in GlobalActions. 58 */ 59 public static final Interpolator CONTROL_STATE = new PathInterpolator(0.4f, 0f, 0.2f, 60 1.0f); 61 62 /** 63 * Interpolator to be used when animating a move based on a click. Pair with enough duration. 64 */ 65 public static final Interpolator TOUCH_RESPONSE = 66 new PathInterpolator(0.3f, 0f, 0.1f, 1f); 67 68 /** 69 * Like {@link #TOUCH_RESPONSE}, but used in case the animation is played in reverse (i.e. t 70 * goes from 1 to 0 instead of 0 to 1). 71 */ 72 public static final Interpolator TOUCH_RESPONSE_REVERSE = 73 new PathInterpolator(0.9f, 0f, 0.7f, 1f); 74 75 /** 76 * Calculate the amount of overshoot using an exponential falloff function with desired 77 * properties, where the overshoot smoothly transitions at the 1.0f boundary into the 78 * overshoot, retaining its acceleration. 79 * 80 * @param progress a progress value going from 0 to 1 81 * @param overshootAmount the amount > 0 of overshoot desired. A value of 0.1 means the max 82 * value of the overall progress will be at 1.1. 83 * @param overshootStart the point in (0,1] where the result should reach 1 84 * @return the interpolated overshoot 85 */ getOvershootInterpolation(float progress, float overshootAmount, float overshootStart)86 public static float getOvershootInterpolation(float progress, float overshootAmount, 87 float overshootStart) { 88 if (overshootAmount == 0.0f || overshootStart == 0.0f) { 89 throw new IllegalArgumentException("Invalid values for overshoot"); 90 } 91 float b = MathUtils.log((overshootAmount + 1) / (overshootAmount)) / overshootStart; 92 return MathUtils.max(0.0f, 93 (float) (1.0f - Math.exp(-b * progress)) * (overshootAmount + 1.0f)); 94 } 95 96 /** 97 * Similar to {@link #getOvershootInterpolation(float, float, float)} but the overshoot 98 * starts immediately here, instead of first having a section of non-overshooting 99 * 100 * @param progress a progress value going from 0 to 1 101 */ getOvershootInterpolation(float progress)102 public static float getOvershootInterpolation(float progress) { 103 return MathUtils.max(0.0f, (float) (1.0f - Math.exp(-4 * progress))); 104 } 105 106 /** 107 * Interpolate alpha for notifications background scrim during shade expansion. 108 * @param fraction Shade expansion fraction 109 * @param forNotification If we want the alpha of the notification shade or the scrim. 110 */ getNotificationScrimAlpha(float fraction, boolean forNotification)111 public static float getNotificationScrimAlpha(float fraction, boolean forNotification) { 112 if (forNotification) { 113 fraction = MathUtils.constrainedMap(0f, 1f, 0.3f, 1f, fraction); 114 } else { 115 fraction = MathUtils.constrainedMap(0f, 1f, 0f, 0.5f, fraction); 116 } 117 fraction = fraction * 1.2f - 0.2f; 118 if (fraction <= 0) { 119 return 0; 120 } else { 121 final float oneMinusFrac = 1f - fraction; 122 return (float) (1f - 0.5f * (1f - Math.cos(3.14159f * oneMinusFrac * oneMinusFrac))); 123 } 124 } 125 } 126