├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── geet │ │ └── interpolator │ │ └── androidanimationinterpolator │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── fonts │ │ │ ├── Roboto-Bold.ttf │ │ │ ├── Roboto-Medium.ttf │ │ │ └── Roboto-Regular.ttf │ ├── java │ │ └── com │ │ │ └── geet │ │ │ └── interpolator │ │ │ └── androidanimationinterpolator │ │ │ └── ui │ │ │ └── home │ │ │ ├── CustomSpringInterpolator.java │ │ │ └── HomeActivity.java │ └── res │ │ ├── drawable │ │ ├── background_button.xml │ │ ├── shape_circle.xml │ │ └── spinner_background.xml │ │ ├── layout │ │ ├── activity_home.xml │ │ ├── layout_interpolator_animation.xml │ │ ├── layout_interpolator_defination.xml │ │ └── layout_interpolator_graph.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── geet │ └── interpolator │ └── androidanimationinterpolator │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Animation Interpolator 2 | Proof of concept 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "26.0.0" 6 | defaultConfig { 7 | applicationId "com.geet.interpolator.androidanimationinterpolator" 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | final SUPPORT_LIBRARY_VERSION = '25.3.1' 24 | 25 | compile fileTree(dir: 'libs', include: ['*.jar']) 26 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 27 | exclude group: 'com.android.support', module: 'support-annotations' 28 | }) 29 | 30 | compile "com.android.support:appcompat-v7:$SUPPORT_LIBRARY_VERSION" 31 | compile "com.android.support:cardview-v7:$SUPPORT_LIBRARY_VERSION" 32 | compile "com.android.support:design:$SUPPORT_LIBRARY_VERSION" 33 | compile "com.android.support:recyclerview-v7:$SUPPORT_LIBRARY_VERSION" 34 | 35 | compile 'com.github.Nishant-Pathak:MathView:v1.1' 36 | compile 'com.github.PhilJay:MPAndroidChart:v3.0.2' 37 | 38 | compile 'com.jakewharton:butterknife:8.8.1' 39 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' 40 | 41 | testCompile 'junit:junit:4.12' 42 | } 43 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/geetgobindsingh/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/geet/interpolator/androidanimationinterpolator/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.geet.interpolator.androidanimationinterpolator; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.geet.interpolator.androidanimationinterpolator", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/assets/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geetgobindsingh/AndroidAnimationInterpolator/2bf840bec1a999ff3c01d2fab5821f2af42db2e8/app/src/main/assets/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /app/src/main/assets/fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geetgobindsingh/AndroidAnimationInterpolator/2bf840bec1a999ff3c01d2fab5821f2af42db2e8/app/src/main/assets/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /app/src/main/assets/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geetgobindsingh/AndroidAnimationInterpolator/2bf840bec1a999ff3c01d2fab5821f2af42db2e8/app/src/main/assets/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/geet/interpolator/androidanimationinterpolator/ui/home/CustomSpringInterpolator.java: -------------------------------------------------------------------------------- 1 | package com.geet.interpolator.androidanimationinterpolator.ui.home; 2 | 3 | import android.view.animation.Interpolator; 4 | 5 | /** 6 | * Created by geetgobindsingh on 16/08/17. 7 | */ 8 | 9 | public class CustomSpringInterpolator implements Interpolator { 10 | 11 | private float factor = 0.3f; // default 12 | 13 | public CustomSpringInterpolator() {} 14 | 15 | public CustomSpringInterpolator(float factor) { 16 | this.factor = factor; 17 | } 18 | 19 | @Override 20 | public float getInterpolation(float input) { 21 | return (float) (Math.pow(2, (-10 * input)) * Math.sin(((2* Math.PI) * (input - (factor/4)))/factor) + 1); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/geet/interpolator/androidanimationinterpolator/ui/home/HomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.geet.interpolator.androidanimationinterpolator.ui.home; 2 | 3 | import android.animation.AnimatorSet; 4 | import android.animation.ObjectAnimator; 5 | import android.animation.ValueAnimator; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.support.v7.widget.AppCompatSpinner; 9 | import android.view.View; 10 | import android.view.animation.AccelerateDecelerateInterpolator; 11 | import android.view.animation.AccelerateInterpolator; 12 | import android.view.animation.AnticipateInterpolator; 13 | import android.view.animation.AnticipateOvershootInterpolator; 14 | import android.view.animation.BounceInterpolator; 15 | import android.view.animation.CycleInterpolator; 16 | import android.view.animation.DecelerateInterpolator; 17 | import android.view.animation.Interpolator; 18 | import android.view.animation.LinearInterpolator; 19 | import android.view.animation.OvershootInterpolator; 20 | import android.widget.AdapterView; 21 | import android.widget.ArrayAdapter; 22 | import android.widget.RelativeLayout; 23 | import android.widget.TextView; 24 | 25 | import com.geet.interpolator.androidanimationinterpolator.R; 26 | import com.github.mikephil.charting.charts.LineChart; 27 | import com.github.mikephil.charting.data.Entry; 28 | import com.github.mikephil.charting.data.LineData; 29 | import com.github.mikephil.charting.data.LineDataSet; 30 | import com.nishant.math.MathView; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | import butterknife.BindView; 36 | import butterknife.ButterKnife; 37 | import butterknife.OnClick; 38 | 39 | public class HomeActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { 40 | 41 | //region Member variables 42 | private static final String TAG = HomeActivity.class.getSimpleName(); 43 | 44 | private static final int CYCLE_INTERPOLATOR = 0; 45 | private static final int ACCELERATE_INTERPOLATOR = 1; 46 | private static final int DECELERATE_INTERPOLATOR = 2; 47 | private static final int ACCELERATE_DECELERATE_INTERPOLATOR = 3; 48 | private static final int ANTICIPATE_INTERPOLATOR = 4; 49 | private static final int OVERSHOOT_INTERPOLATOR = 5; 50 | private static final int ANTICIPATE_OVERSHOOT_INTERPOLATOR = 6; 51 | private static final int LINEAR_INTERPOLATOR = 7; 52 | private static final int BOUNCE_INTERPOLATOR = 8; 53 | private static final int CUSTOM_SPRING_INTERPOLATOR = 9; 54 | 55 | private static final int ANIMATION_DURATION_MILLISECONDS = 2000; 56 | //endregion 57 | 58 | //region View variables 59 | @BindView(R.id.interpolator_spinner) 60 | AppCompatSpinner mInterpolatorSpinner; 61 | 62 | @BindView(R.id.interpolator_line_chart) 63 | LineChart mInterpolatorLineChart; 64 | 65 | @BindView(R.id.interpolator_selected_formulae) 66 | MathView mInterpolatorSelectedFormulae; 67 | 68 | @BindView(R.id.interpolator_alpha) 69 | RelativeLayout mInterpolatorAlpha; 70 | 71 | @BindView(R.id.interpolator_scale) 72 | RelativeLayout mInterpolatorScale; 73 | 74 | @BindView(R.id.interpolator_translate_path) 75 | RelativeLayout mInterpolatorTranslatePath; 76 | 77 | @BindView(R.id.interpolator_translate) 78 | RelativeLayout mInterpolatorTranslate; 79 | 80 | @BindView(R.id.interpolator_rotate) 81 | RelativeLayout mInterpolatorRotate; 82 | 83 | @BindView(R.id.interpolator_selected_name) 84 | TextView mInterpolatorSelectedName; 85 | //endregion 86 | 87 | //region Member variables 88 | private List interpolatorList = new ArrayList<>(); 89 | private List entries = new ArrayList(); 90 | private int mSelectedInterpolatorState = CYCLE_INTERPOLATOR; // default selected cycle interpolator index 91 | private Interpolator mSelectedInterpolator = new CycleInterpolator(1); // taking default cycle Interpolator cycle count as 1 92 | private static boolean toggleFlag = true; //by default true : toggles animation 93 | private AnimatorSet mAnimatorSet; 94 | private ValueAnimator mAlphaAnimator, mScaleDownXAnimator, mScaleDownYAnimator, mScaleUpXAnimator, mScaleUpYAnimator, mTranslateAnimator, mRotateAnimator; 95 | //endregion 96 | 97 | //region Activity Lifecycle methods 98 | @Override 99 | protected void onCreate(Bundle savedInstanceState) { 100 | super.onCreate(savedInstanceState); 101 | setContentView(R.layout.activity_home); 102 | 103 | // Binding View with respective ViewObjects 104 | ButterKnife.bind(this); 105 | 106 | // Setting listener to Spinner item selection 107 | mInterpolatorSpinner.setOnItemSelectedListener(HomeActivity.this); 108 | 109 | // Populating list of Default Android Interpolator 110 | interpolatorList.add(CYCLE_INTERPOLATOR, "Cycle Interpolator"); 111 | interpolatorList.add(ACCELERATE_INTERPOLATOR, "Accelerate Interpolator"); 112 | interpolatorList.add(DECELERATE_INTERPOLATOR, "Decelerate Interpolator"); 113 | interpolatorList.add(ACCELERATE_DECELERATE_INTERPOLATOR, "Accelerate Decelerate Interpolator"); 114 | interpolatorList.add(ANTICIPATE_INTERPOLATOR, "Anticipate Interpolator"); 115 | interpolatorList.add(OVERSHOOT_INTERPOLATOR, "Overshoot Interpolator"); 116 | interpolatorList.add(ANTICIPATE_OVERSHOOT_INTERPOLATOR, "Anticipate Overshoot Interpolator"); 117 | interpolatorList.add(LINEAR_INTERPOLATOR, "Linear Interpolator"); 118 | interpolatorList.add(BOUNCE_INTERPOLATOR, "Bounce Interpolator"); 119 | interpolatorList.add(CUSTOM_SPRING_INTERPOLATOR, "Custom Spring Interpolator"); 120 | 121 | ArrayAdapter dataAdapter = new ArrayAdapter(HomeActivity.this, android.R.layout.simple_spinner_item, interpolatorList); 122 | 123 | // Drop down layout style - list view with radio button 124 | dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 125 | 126 | // Attaching data adapter to spinner 127 | mInterpolatorSpinner.setAdapter(dataAdapter); 128 | 129 | // Initializing AnimatorSet object for group animation 130 | mAnimatorSet = new AnimatorSet(); 131 | 132 | mAnimatorSet.setDuration(ANIMATION_DURATION_MILLISECONDS); 133 | 134 | // Disabling all touvh events on Graph 135 | mInterpolatorLineChart.setTouchEnabled(false); 136 | 137 | // Rest to default Graph 138 | resetGraphData(); 139 | } 140 | //endregion 141 | 142 | //region Private Helper methods 143 | private void resetGraphData() { 144 | 145 | // Set selected Interpolator name 146 | mInterpolatorSelectedName.setText(interpolatorList.get(mSelectedInterpolatorState)); 147 | 148 | // clear and add new points to chart wrt. selected interpolator 149 | entries.clear(); 150 | entries.addAll(getSelectedInterpolatorGraphPoints()); 151 | 152 | // Populating data in LinChart 153 | LineDataSet lineDataSet = new LineDataSet(entries, "X = originalTime | Y = displacedTime"); 154 | LineData lineData = new LineData(lineDataSet); 155 | 156 | mInterpolatorLineChart.setData(lineData); 157 | 158 | // Refresh Chart 159 | mInterpolatorLineChart.invalidate(); 160 | } 161 | 162 | /** 163 | * This method updates member interpolator object and 164 | * computes points for respective interpolator. 165 | * 166 | * @return List of Points to be plot on chart 167 | */ 168 | private List getSelectedInterpolatorGraphPoints() { 169 | List entryList = new ArrayList<>(); 170 | switch (mSelectedInterpolatorState) { 171 | case LINEAR_INTERPOLATOR: { 172 | mSelectedInterpolator = new LinearInterpolator(); 173 | mInterpolatorSelectedFormulae.setText("`displacedTime = time`, \nWhere time is originalTime"); 174 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 175 | float displaced_time = original_time; 176 | entryList.add(new Entry(original_time, displaced_time)); 177 | } 178 | break; 179 | } 180 | case ACCELERATE_INTERPOLATOR: { 181 | mSelectedInterpolator = new AccelerateInterpolator(); 182 | mInterpolatorSelectedFormulae.setText("`displacedTime = time^2`, \nWhere time is originalTime"); 183 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 184 | float displaced_time = (float) Math.pow((original_time), 2); 185 | entryList.add(new Entry(original_time, displaced_time)); 186 | } 187 | break; 188 | } 189 | case DECELERATE_INTERPOLATOR: { 190 | mSelectedInterpolator = new DecelerateInterpolator(); 191 | mInterpolatorSelectedFormulae.setText("`displacedTime = 1 - (1 - time)^2`, \nWhere time is originalTime"); 192 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 193 | float displaced_time = (float) (1 - Math.pow(1 - original_time, 2)); 194 | entryList.add(new Entry(original_time, displaced_time)); 195 | } 196 | break; 197 | } 198 | case ACCELERATE_DECELERATE_INTERPOLATOR: { 199 | mSelectedInterpolator = new AccelerateDecelerateInterpolator(); 200 | mInterpolatorSelectedFormulae.setText("`displacedTime = cos((time + 1)π)/2 + 0.5`, \nWhere time is originalTime"); 201 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 202 | float displaced_time = (float) (Math.cos((Math.PI) * (original_time + 1)) / 2) + 0.5f; 203 | entryList.add(new Entry(original_time, displaced_time)); 204 | } 205 | break; 206 | } 207 | case ANTICIPATE_INTERPOLATOR: { 208 | mSelectedInterpolator = new AnticipateInterpolator(); 209 | mInterpolatorSelectedFormulae.setText("`displacedTime = (T + 1)*(time^3) - T*time^2`, \nWhere T is the amount of tension, the default is 2 and time is originalTime"); 210 | int T = 2; // default Where T is the amount of tension, the default is 2 211 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 212 | float displaced_time = (float) (((T + 1) * Math.pow(original_time, 3)) - (T * Math.pow(original_time, 2))); 213 | entryList.add(new Entry(original_time, displaced_time)); 214 | } 215 | break; 216 | } 217 | case OVERSHOOT_INTERPOLATOR: { 218 | mSelectedInterpolator = new OvershootInterpolator(); 219 | mInterpolatorSelectedFormulae.setText("`displacedTime = (T + 1)*(time - 1)^3 + (T*(time - 1)^2) + 1`, \nWhere T is the amount of tension, the default is 2 and time is originalTime"); 220 | int T = 2; // default Where T is the amount of tension, the default is 2 221 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 222 | float displaced_time = (float) (((T + 1) * Math.pow(original_time - 1, 3)) + (T * Math.pow(original_time - 1, 2)) + 1); 223 | entryList.add(new Entry(original_time, displaced_time)); 224 | } 225 | break; 226 | } 227 | case ANTICIPATE_OVERSHOOT_INTERPOLATOR: { 228 | mSelectedInterpolator = new AnticipateOvershootInterpolator(); 229 | mInterpolatorSelectedFormulae.setText("displacedTime = if (time < 0.5) than {`(0.5)*((T + 1)*(2t)^3) - (T*(2t)^2)`}\n " + 230 | "else if (time >= 0.5) than {`(0.5)*((T + 1)*(2t- 2)^3) - (T*(2t-2)^2)`, \nWhere T is the amount of tension, the default is 2 and time/t is originalTime} "); 231 | int T = 2; // default Where T is the amount of tension, the default is 2" 232 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 233 | float displaced_time = 0.0f; 234 | if (original_time >= 0.5f) { 235 | displaced_time = (float) ((0.5f) * (((T + 1) * Math.pow((2 * original_time) - 2, 3)) + ((T * Math.pow((2 * original_time) - 2, 2))))) + 1; 236 | } else if (original_time < 0.5f) { 237 | displaced_time = (float) ((0.5f) * (((T + 1) * Math.pow((2 * original_time), 3)) - (T * Math.pow(2 * original_time, 2)))); 238 | } 239 | entryList.add(new Entry(original_time, displaced_time)); 240 | } 241 | break; 242 | } 243 | case BOUNCE_INTERPOLATOR: { 244 | mSelectedInterpolator = new BounceInterpolator(); 245 | mInterpolatorSelectedFormulae.setText("displacedTime = if (time < 0.31489) than {`8*(1.1.226time)^2)`}\n " + 246 | "else if (0.31489 <= time < 0.65990) than {`8*(1.1.226time - 0.54719)^2) + 0.7`} " + 247 | "else if (0.65990 <= time < 0.85908) than {`8*(1.1.226time - 0.8526)^2) + 0.9`} " + 248 | "else if (0.85908 <= time) than {`8*(1.1.226time - 1.0435)^2) + 1.0435`, \nwhere time is originalTime} "); 249 | 250 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 251 | float displaced_time = 0.0f; 252 | if (original_time < 0.31489f) { 253 | displaced_time = (float) (8 * Math.pow((1.1226 * original_time), 2)); 254 | } else if (original_time >= 0.31489f && original_time < 0.65990f) { 255 | displaced_time = (float) (8 * Math.pow((1.1226 * original_time) - 0.54719, 2) + 0.7f); 256 | } else if (original_time >= 0.65990f && original_time < 0.85908f) { 257 | displaced_time = (float) (8 * Math.pow((1.1226 * original_time) - 0.8526, 2) + 0.9f); 258 | } else if (original_time >= 0.85908) { 259 | displaced_time = (float) (8 * Math.pow((1.1226 * original_time - 1.0435), 2) + 1.0435f); 260 | } 261 | entryList.add(new Entry(original_time, displaced_time)); 262 | } 263 | break; 264 | } 265 | case CYCLE_INTERPOLATOR: { 266 | mSelectedInterpolator = new CycleInterpolator(1); 267 | mInterpolatorSelectedFormulae.setText("`displacedTime = sin(2π*C*time)`, \nWhere C is the number of cycles, the default is 1 and time is originalTime"); 268 | int C = 1; //default Where C is the number of cycles, the default is 1 269 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 270 | float displaced_time = (float) Math.sin(2 * Math.PI * C * original_time); 271 | entryList.add(new Entry(original_time, displaced_time)); 272 | } 273 | break; 274 | } 275 | case CUSTOM_SPRING_INTERPOLATOR: { 276 | float F = 0.3f; //Where F is the damping factor, the default is 0.3 277 | mSelectedInterpolator = new CustomSpringInterpolator(F); 278 | mInterpolatorSelectedFormulae.setText("`displacedTime = 2^(-10*time) * sin((2π*(time - (F/4)))) + 1` " + 279 | ", \nWhere F is the damping factor, the default is 0.3 and time is originalTime"); 280 | for (float original_time = 0; original_time < 1.1f; original_time += 0.1f) { 281 | float displaced_time = (float) (Math.pow(2, (-10 * original_time)) * Math.sin(((2* Math.PI) * (original_time - (F/4)))/F) + 1); 282 | entryList.add(new Entry(original_time, displaced_time)); 283 | } 284 | break; 285 | } 286 | } 287 | 288 | animate(); 289 | 290 | return entryList; 291 | } 292 | 293 | private void animate() { 294 | mAnimatorSet.setInterpolator(mSelectedInterpolator); 295 | 296 | if (toggleFlag) { 297 | 298 | mAlphaAnimator = ObjectAnimator.ofFloat(mInterpolatorAlpha, "alpha", 1f, 0f); 299 | 300 | mScaleDownXAnimator = ObjectAnimator.ofFloat(mInterpolatorScale, "scaleX", 1.0f, 0.0f); 301 | mScaleDownYAnimator = ObjectAnimator.ofFloat(mInterpolatorScale, "scaleY", 1.0f, 0.0f); 302 | 303 | mTranslateAnimator = ObjectAnimator.ofFloat(mInterpolatorTranslate, "translationX", 0, (mInterpolatorTranslatePath.getWidth() - mInterpolatorTranslate.getWidth())); 304 | 305 | mRotateAnimator = ObjectAnimator.ofFloat(mInterpolatorRotate, "rotation", 0f, 360f); 306 | 307 | mAnimatorSet.play(mAlphaAnimator).with(mScaleDownXAnimator).with(mScaleDownYAnimator).with(mTranslateAnimator).with(mRotateAnimator); 308 | 309 | toggleFlag = false; 310 | 311 | } else { 312 | mAlphaAnimator = ObjectAnimator.ofFloat(mInterpolatorAlpha, "alpha", 0f, 1f); 313 | 314 | mScaleUpXAnimator = ObjectAnimator.ofFloat(mInterpolatorScale, "scaleX", 0.0f, 1.0f); 315 | mScaleUpYAnimator = ObjectAnimator.ofFloat(mInterpolatorScale, "scaleY", 0.0f, 1.0f); 316 | 317 | mTranslateAnimator = ObjectAnimator.ofFloat(mInterpolatorTranslate, "translationX", (mInterpolatorTranslatePath.getWidth() - mInterpolatorTranslate.getWidth()), 0); 318 | 319 | mRotateAnimator = ObjectAnimator.ofFloat(mInterpolatorRotate, "rotation", 360f, 0f); 320 | 321 | mAnimatorSet.play(mAlphaAnimator).with(mScaleUpXAnimator).with(mScaleUpYAnimator).with(mTranslateAnimator).with(mRotateAnimator); 322 | 323 | toggleFlag = true; 324 | } 325 | 326 | mAnimatorSet.start(); 327 | } 328 | //endregion 329 | 330 | //region Overriding AdapterView.OnItemSelectedListener methods 331 | @Override 332 | public void onItemSelected(AdapterView adapterView, View view, int position, long l) { 333 | 334 | // Update selected interpolator index in list 335 | mSelectedInterpolatorState = position; 336 | 337 | //reset Graph to respective selected interpolator 338 | resetGraphData(); 339 | } 340 | 341 | @Override 342 | public void onNothingSelected(AdapterView adapterView) { 343 | //no-op 344 | } 345 | //endregion 346 | 347 | //region ButterKnife Listeners Binding 348 | @OnClick(R.id.animate) 349 | void onCLick(View view) { 350 | animate(); 351 | } 352 | //endregion 353 | } 354 | 355 | 356 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/spinner_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_interpolator_animation.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 18 | 19 | 27 | 28 | 35 | 36 | 44 | 45 | 50 | 51 | 58 | 59 | 69 | 70 | 71 | 76 | 77 | 84 | 85 | 95 | 96 | 97 | 98 | 106 | 107 | 112 | 113 | 120 | 121 | 131 | 132 | 133 | 138 | 139 | 147 | 148 | 156 | 157 | 167 | 168 | 169 | 170 |