/* * Copyright (C) 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.apps.santatracker.doodles.shared; /** * Tweens properties of Actors (currently, position & scale). * * <p>If any of the from-values is left unset, the from value will be initialized on the first * update of the tween. This allows us to tween from an unspecified value, and have it do so * smoothly when the tween actually runs, regardless of the actual starting value.</p> */ public class ActorTween extends Tween { private static final String TAG = ActorTween.class.getSimpleName(); private final Actor actor; private Interpolator interpolator; // Use Float objects set to null so that we can detect & support unspecified values. private Float xStart = null; private Float yStart = null; private Float xEnd = null; private Float yEnd = null; private Float scaleStart; private Float scaleEnd; private Callback finishedCallback = null; private Float rotationStart; private Float rotationEnd; private Float alphaStart; private Float alphaEnd; private boolean firstUpdate = true; public ActorTween(Actor actor) { super(0); this.actor = actor; interpolator = Interpolator.LINEAR; } public ActorTween from(float x, float y) { fromX(x); fromY(y); return this; } public ActorTween fromX(float x) { xStart = x; return this; } public ActorTween fromY(float y) { yStart = y; return this; } public ActorTween to(float x, float y) { toX(x); toY(y); return this; } public ActorTween toX(float x) { xEnd = x; return this; } public ActorTween toY(float y) { yEnd = y; return this; } public ActorTween scale(float fromScale, float toScale) { this.scaleStart = fromScale; this.scaleEnd = toScale; return this; } public ActorTween scale(float toScale) { this.scaleEnd = toScale; return this; } public ActorTween withRotation(float fromRadians, float toRadians) { this.rotationStart = fromRadians; this.rotationEnd = toRadians; return this; } public ActorTween withRotation(float toRadians) { this.rotationEnd = toRadians; return this; } public ActorTween withAlpha(float fromAlpha, float toAlpha) { this.alphaStart = fromAlpha; this.alphaEnd = toAlpha; return this; } public ActorTween withAlpha(float toAlpha) { this.alphaEnd = toAlpha; return this; } public ActorTween withDuration(float seconds) { this.durationSeconds = seconds; return this; } public ActorTween withInterpolator(Interpolator interpolator) { this.interpolator = interpolator; return this; } public ActorTween whenFinished(Callback c) { finishedCallback = c; return this; } protected void setInitialValues() { xStart = (xStart != null) ? xStart : actor.position.x; yStart = (yStart != null) ? yStart : actor.position.y; scaleStart = (scaleStart != null) ? scaleStart : actor.scale; rotationStart = (rotationStart != null) ? rotationStart : actor.rotation; alphaStart = (alphaStart != null) ? alphaStart : actor.alpha; } @Override protected void updateValues(float percentDone) { if (firstUpdate) { firstUpdate = false; setInitialValues(); } // Perform null checks here so that we don't interpolate over unspecified fields. if (xEnd != null) { actor.position.x = interpolator.getValue(percentDone, xStart, xEnd); } if (yEnd != null) { actor.position.y = interpolator.getValue(percentDone, yStart, yEnd); } if (scaleEnd != null) { actor.scale = interpolator.getValue(percentDone, scaleStart, scaleEnd); } if (rotationEnd != null) { actor.rotation = interpolator.getValue(percentDone, rotationStart, rotationEnd); } if (alphaEnd != null) { actor.alpha = interpolator.getValue(percentDone, alphaStart, alphaEnd); } } @Override protected void onFinish() { if (finishedCallback != null) { finishedCallback.call(); } } /** * Callback to be called at the end of a tween (can be used to chain tweens together, to hide * an actor when a tween finishes, etc.) */ public interface Callback { void call(); } }