summaryrefslogtreecommitdiff
path: root/core/java/android/animation/KeyframeSet.java
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2010-07-20 14:00:01 -0700
committerChet Haase <chet@google.com>2010-07-21 08:00:40 -0700
commit3dd207a6dbd5d9244dc7fe213d5caa3cddaff0db (patch)
tree4e2684e913ee2d081c2a2f894e0a6755da789898 /core/java/android/animation/KeyframeSet.java
parentbcfdb32839d1fa4c1c793913d60574674910c042 (diff)
Add keyframes to animation framework.
Change-Id: I5c8c8037aeeedae1ce7a18200986caf57264772f
Diffstat (limited to 'core/java/android/animation/KeyframeSet.java')
-rw-r--r--core/java/android/animation/KeyframeSet.java99
1 files changed, 99 insertions, 0 deletions
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
new file mode 100644
index 000000000000..59e9708e3deb
--- /dev/null
+++ b/core/java/android/animation/KeyframeSet.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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 android.animation;
+
+import java.util.ArrayList;
+
+import android.view.animation.Interpolator;
+
+/**
+ * This class holds a collection of Keyframe objects and is called by Animator to calculate
+ * values between those keyframes for a given animation. The class internal to the animation
+ * package because it is an implementation detail of how Keyframes are stored and used.
+ */
+class KeyframeSet {
+
+ private int mNumKeyframes;
+
+ private ArrayList<Keyframe> mKeyframes;
+
+ public KeyframeSet(Keyframe... keyframes) {
+ mKeyframes = new ArrayList<Keyframe>();
+ for (Keyframe keyframe : keyframes) {
+ mKeyframes.add(keyframe);
+ }
+ mNumKeyframes = mKeyframes.size();
+ }
+
+ /**
+ * Gets the animated value, given the elapsed fraction of the animation (interpolated by the
+ * animation's interpolator) and the evaluator used to calculate in-between values. This
+ * function maps the input fraction to the appropriate keyframe interval and a fraction
+ * between them and returns the interpolated value. Note that the input fraction may fall
+ * outside the [0-1] bounds, if the animation's interpolator made that happen (e.g., a
+ * spring interpolation that might send the fraction past 1.0). We handle this situation by
+ * just using the two keyframes at the appropriate end when the value is outside those bounds.
+ *
+ * @param fraction The elapsed fraction of the animation
+ * @param evaluator The type evaluator to use when calculating the interpolated values.
+ * @return The animated value.
+ */
+ public Object getValue(float fraction, TypeEvaluator evaluator) {
+ // TODO: special-case 2-keyframe common case
+
+ if (fraction <= 0f) {
+ final Keyframe prevKeyframe = mKeyframes.get(0);
+ final Keyframe nextKeyframe = mKeyframes.get(1);
+ final Interpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevKeyframe.getFraction()) /
+ (nextKeyframe.getFraction() - prevKeyframe.getFraction());
+ return evaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
+ nextKeyframe.getValue());
+ } else if (fraction >= 1f) {
+ final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
+ final Keyframe nextKeyframe = mKeyframes.get(mNumKeyframes - 1);
+ final Interpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevKeyframe.getFraction()) /
+ (nextKeyframe.getFraction() - prevKeyframe.getFraction());
+ return evaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
+ nextKeyframe.getValue());
+ }
+ Keyframe prevKeyframe = mKeyframes.get(0);
+ for (int i = 1; i < mNumKeyframes; ++i) {
+ Keyframe nextKeyframe = mKeyframes.get(i);
+ if (fraction < nextKeyframe.getFraction()) {
+ final Interpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevKeyframe.getFraction()) /
+ (nextKeyframe.getFraction() - prevKeyframe.getFraction());
+ return evaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
+ nextKeyframe.getValue());
+ }
+ prevKeyframe = nextKeyframe;
+ }
+ // shouldn't get here
+ return mKeyframes.get(mNumKeyframes - 1).getValue();
+ }
+}