package com.nightonke.boommenu.Animation; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.TypeEvaluator; import android.graphics.Point; import android.view.View; import com.nightonke.boommenu.BoomButtons.BoomButton; import java.util.ArrayList; import java.util.Random; import static com.nightonke.boommenu.Animation.BoomEnum.LINE; /** * Created by Weiping Huang at 03:27 on 16/7/26 * For Personal Open Source * Contact me at 2584541288@qq.com or nightonke@outlook.com * For more projects: https://github.com/Nightonke * */ public class AnimationManager { public static ObjectAnimator animate(Object target, String property, long delay, long duration, TimeInterpolator interpolator, AnimatorListenerAdapter listenerAdapter, float... values) { ObjectAnimator animator = ObjectAnimator.ofFloat(target, property, values); animator.setStartDelay(delay); animator.setDuration(duration); if (interpolator != null) animator.setInterpolator(interpolator); if (listenerAdapter != null) animator.addListener(listenerAdapter); animator.start(); return animator; } public static ObjectAnimator animate(Object target, String property, long delay, long duration, TimeInterpolator interpolator, float... values) { return animate( target, property, delay, duration, interpolator, null, values); } public static void animate(String property, long delay, long duration, float[] values, TimeInterpolator interpolator, ArrayList<View> targets) { for (Object target : targets) { animate( target, property, delay, duration, interpolator, null, values); } } public static void rotate(BoomButton boomButton, long delay, long duration, TimeInterpolator interpolator, float... degrees) { boomButton.setRotateAnchorPoints(); for (int i = 0; i < boomButton.rotateViews().size(); i++) { View view = boomButton.rotateViews().get(i); animate( view, "rotation", delay, duration, interpolator, null, degrees); } } public static ObjectAnimator animate( Object target, String property, long delay, long duration, TypeEvaluator evaluator, int... values) { return animate(target, property, delay, duration, evaluator, null, values); } public static ObjectAnimator animate( Object target, String property, long delay, long duration, TypeEvaluator evaluator, AnimatorListenerAdapter listenerAdapter, int... values) { ObjectAnimator animator = ObjectAnimator.ofInt(target, property, values); animator.setStartDelay(delay); animator.setDuration(duration); animator.setEvaluator(evaluator); if (listenerAdapter != null) animator.addListener(listenerAdapter); animator.start(); return animator; } public static ArrayList<Integer> getOrderIndex(OrderEnum orderEnum, int size) { ArrayList<Integer> indexes = new ArrayList<>(); switch (orderEnum) { case DEFAULT: for (int i = 0; i < size; i++) indexes.add(i); break; case REVERSE: for (int i = 0; i < size; i++) indexes.add(size - i - 1); break; case RANDOM: boolean[] used = new boolean[size]; for (int i = 0; i < used.length; i++) used[i] = false; int count = 0; Random random = new Random(); while (count < size) { int r = random.nextInt(size); if (!used[r]) { used[r] = true; indexes.add(r); count++; } } break; } return indexes; } public static void calculateShowXY(BoomEnum boomEnum, Point parentSize, int frames, Point startPosition, Point endPosition, float[] xs, float[] ys) { if (startPosition.x == endPosition.x) boomEnum = LINE; float x1 = startPosition.x; float y1 = startPosition.y; float x2 = endPosition.x; float y2 = endPosition.y; float p = 1.0f / frames; float xOffset = x2 - x1; float yOffset = y2 - y1; float x3, y3, a, b, c; switch (boomEnum) { case LINE: for (int i = 0; i < xs.length; i++) { float offset = i * p; xs[i] = x1 + offset * xOffset; ys[i] = y1 + offset * yOffset; } break; case PARABOLA_1: x3 = (x1 + x2) / 2.0f; y3 = Math.min(y1, y2) * 3.0f / 4; a = (y1 * (x2 - x3) + y2 * (x3 - x1) + y3 * (x1 - x2)) / (x1 * x1 * (x2 - x3) + x2 * x2 * (x3 - x1) + x3 * x3 * (x1 - x2)); b = (y1 - y2) / (x1 - x2) - a * (x1 + x2); c = y1 - (x1 * x1) * a - x1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; xs[i] = x1 + offset * xOffset; ys[i] = a * xs[i] * xs[i] + b * xs[i] + c; } break; case PARABOLA_2: x3 = (x1 + x2) / 2.0f; y3 = (parentSize.y + Math.max(y1, y2)) / 2.0f; a = (y1 * (x2 - x3) + y2 * (x3 - x1) + y3 * (x1 - x2)) / (x1 * x1 * (x2 - x3) + x2 * x2 * (x3 - x1) + x3 * x3 * (x1 - x2)); b = (y1 - y2) / (x1 - x2) - a * (x1 + x2); c = y1 - (x1 * x1) * a - x1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; xs[i] = x1 + offset * xOffset; ys[i] = a * xs[i] * xs[i] + b * xs[i] + c; } break; case PARABOLA_3: y3 = (y1 + y2) / 2.0f; x3 = Math.min(x1, x2) / 2.0f; a = (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / (y1 * y1 * (y2 - y3) + y2 * y2 * (y3 - y1) + y3 * y3 * (y1 - y2)); b = (x1 - x2) / (y1 - y2) - a * (y1 + y2); c = x1 - (y1 * y1) * a - y1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; ys[i] = y1 + offset * yOffset; xs[i] = a * ys[i] * ys[i] + b * ys[i] + c; } break; case PARABOLA_4: y3 = (y1 + y2) / 2.0f; x3 = (parentSize.x + Math.max(x1, x2)) / 2.0f; a = (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / (y1 * y1 * (y2 - y3) + y2 * y2 * (y3 - y1) + y3 * y3 * (y1 - y2)); b = (x1 - x2) / (y1 - y2) - a * (y1 + y2); c = x1 - (y1 * y1) * a - y1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; ys[i] = y1 + offset * yOffset; xs[i] = a * ys[i] * ys[i] + b * ys[i] + c; } break; case HORIZONTAL_THROW_1: x3 = x2 * 2 - x1; y3 = y1; a = (y1 * (x3 - x2) + y3 * (x2 - x1) + y2 * (x1 - x3)) / (x1 * x1 * (x3 - x2) + x3 * x3 * (x2 - x1) + x2 * x2 * (x1 - x3)); b = (y1 - y3) / (x1 - x3) - a * (x1 + x3); c = y1 - (x1 * x1) * a - x1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; xs[i] = x1 + offset * xOffset; ys[i] = a * xs[i] * xs[i] + b * xs[i] + c; } break; case HORIZONTAL_THROW_2: x2 = startPosition.x; y2 = startPosition.y; x1 = endPosition.x; y1 = endPosition.y; x3 = x2 * 2 - x1; y3 = y1; a = (y1 * (x3 - x2) + y3 * (x2 - x1) + y2 * (x1 - x3)) / (x1 * x1 * (x3 - x2) + x3 * x3 * (x2 - x1) + x2 * x2 * (x1 - x3)); b = (y1 - y3) / (x1 - x3) - a * (x1 + x3); c = y1 - (x1 * x1) * a - x1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; xs[i] = x2 + offset * xOffset; ys[i] = a * xs[i] * xs[i] + b * xs[i] + c; } break; case RANDOM: calculateShowXY( BoomEnum.values()[new Random().nextInt(BoomEnum.RANDOM.getValue())], parentSize, frames, startPosition, endPosition, xs, ys); break; case Unknown: throw new RuntimeException("Unknown boom-enum!"); } } public static void calculateHideXY(BoomEnum boomEnum, Point parentSize, int frames, Point startPosition, Point endPosition, float[] xs, float[] ys) { if (startPosition.x == endPosition.x) boomEnum = LINE; float x1 = startPosition.x; float y1 = startPosition.y; float x2 = endPosition.x; float y2 = endPosition.y; float p = 1.0f / frames; float xOffset = x2 - x1; float yOffset = y2 - y1; float x3, y3, a, b, c; switch (boomEnum) { case LINE: case PARABOLA_1: case PARABOLA_2: case PARABOLA_3: case PARABOLA_4: case RANDOM: case Unknown: calculateShowXY( boomEnum, parentSize, frames, startPosition, endPosition, xs, ys); break; case HORIZONTAL_THROW_1: x2 = startPosition.x; y2 = startPosition.y; x1 = endPosition.x; y1 = endPosition.y; x3 = x2 * 2 - x1; y3 = y1; a = (y1 * (x3 - x2) + y3 * (x2 - x1) + y2 * (x1 - x3)) / (x1 * x1 * (x3 - x2) + x3 * x3 * (x2 - x1) + x2 * x2 * (x1 - x3)); b = (y1 - y3) / (x1 - x3) - a * (x1 + x3); c = y1 - (x1 * x1) * a - x1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; xs[i] = x2 + offset * xOffset; ys[i] = a * xs[i] * xs[i] + b * xs[i] + c; } break; case HORIZONTAL_THROW_2: x3 = x2 * 2 - x1; y3 = y1; a = (y1 * (x3 - x2) + y3 * (x2 - x1) + y2 * (x1 - x3)) / (x1 * x1 * (x3 - x2) + x3 * x3 * (x2 - x1) + x2 * x2 * (x1 - x3)); b = (y1 - y3) / (x1 - x3) - a * (x1 + x3); c = y1 - (x1 * x1) * a - x1 * b; for (int i = 0; i < xs.length; i++) { float offset = i * p; xs[i] = x1 + offset * xOffset; ys[i] = a * xs[i] * xs[i] + b * xs[i] + c; } break; } } private static AnimationManager ourInstance = new AnimationManager(); public static AnimationManager getInstance() { return ourInstance; } private AnimationManager() { } }