PathKeyframes.java revision bc68f5adc222e6438588537fba222ea6a13f46e0
1984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount/* 2984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Copyright (C) 2014 The Android Open Source Project 3984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * 4984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 5984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * you may not use this file except in compliance with the License. 6984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * You may obtain a copy of the License at 7984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * 8984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * http://www.apache.org/licenses/LICENSE-2.0 9984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * 10984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Unless required by applicable law or agreed to in writing, software 11984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * distributed under the License is distributed on an "AS IS" BASIS, 12984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * See the License for the specific language governing permissions and 14984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * limitations under the License. 15984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount */ 16984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mountpackage android.animation; 17984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 18984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mountimport android.graphics.Path; 19984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mountimport android.graphics.PointF; 20984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 21984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mountimport java.util.ArrayList; 22984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 23984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount/** 24984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * PathKeyframes relies on approximating the Path as a series of line segments. 25984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * The line segments are recursively divided until there is less than 1/2 pixel error 26984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * between the lines and the curve. Each point of the line segment is converted 27984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * to a Keyframe and a linear interpolation between Keyframes creates a good approximation 28984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * of the curve. 29984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * <p> 30984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * PathKeyframes is optimized to reduce the number of objects created when there are 31984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * many keyframes for a curve. 32984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * </p> 33984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * <p> 34984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Typically, the returned type is a PointF, but the individual components can be extracted 35984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * as either an IntKeyframes or FloatKeyframes. 36984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * </p> 37984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount */ 38984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mountclass PathKeyframes implements Keyframes { 39984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private static final int FRACTION_OFFSET = 0; 40984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private static final int X_OFFSET = 1; 41984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private static final int Y_OFFSET = 2; 42984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private static final int NUM_COMPONENTS = 3; 43984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private static final ArrayList<Keyframe> EMPTY_KEYFRAMES = new ArrayList<Keyframe>(); 44984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 45984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private PointF mTempPointF = new PointF(); 46984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private float[] mKeyframeData; 47984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 48984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public PathKeyframes(Path path) { 49984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount this(path, 0.5f); 50984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 51984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 52984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public PathKeyframes(Path path, float error) { 53984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount if (path == null || path.isEmpty()) { 54984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount throw new IllegalArgumentException("The path must not be null or empty"); 55984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 56984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount mKeyframeData = path.approximate(error); 57984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 58984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 59984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 60984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public ArrayList<Keyframe> getKeyframes() { 61984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return EMPTY_KEYFRAMES; 62984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 63984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 64984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 65984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Object getValue(float fraction) { 66984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount int numPoints = mKeyframeData.length / 3; 67bc68f5adc222e6438588537fba222ea6a13f46e0George Mount if (fraction < 0) { 68bc68f5adc222e6438588537fba222ea6a13f46e0George Mount return interpolateInRange(fraction, 0, 1); 69bc68f5adc222e6438588537fba222ea6a13f46e0George Mount } else if (fraction > 1) { 70bc68f5adc222e6438588537fba222ea6a13f46e0George Mount return interpolateInRange(fraction, numPoints - 2, numPoints - 1); 71bc68f5adc222e6438588537fba222ea6a13f46e0George Mount } else if (fraction == 0) { 72984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return pointForIndex(0); 73984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } else if (fraction == 1) { 74984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return pointForIndex(numPoints - 1); 75984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } else { 76984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount // Binary search for the correct section 77984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount int low = 0; 78984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount int high = numPoints - 1; 79984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 80984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount while (low <= high) { 81984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount int mid = (low + high) / 2; 82984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount float midFraction = mKeyframeData[(mid * NUM_COMPONENTS) + FRACTION_OFFSET]; 83984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 84984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount if (fraction < midFraction) { 85984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount high = mid - 1; 86984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } else if (fraction > midFraction) { 87984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount low = mid + 1; 88984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } else { 89984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return pointForIndex(mid); 90984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 91984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 92984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 93984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount // now high is below the fraction and low is above the fraction 94bc68f5adc222e6438588537fba222ea6a13f46e0George Mount return interpolateInRange(fraction, high, low); 95bc68f5adc222e6438588537fba222ea6a13f46e0George Mount } 96bc68f5adc222e6438588537fba222ea6a13f46e0George Mount } 97984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 98bc68f5adc222e6438588537fba222ea6a13f46e0George Mount private PointF interpolateInRange(float fraction, int startIndex, int endIndex) { 99bc68f5adc222e6438588537fba222ea6a13f46e0George Mount int startBase = (startIndex * NUM_COMPONENTS); 100bc68f5adc222e6438588537fba222ea6a13f46e0George Mount int endBase = (endIndex * NUM_COMPONENTS); 101984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 102bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float startFraction = mKeyframeData[startBase + FRACTION_OFFSET]; 103bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float endFraction = mKeyframeData[endBase + FRACTION_OFFSET]; 104984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 105bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float intervalFraction = (fraction - startFraction)/(endFraction - startFraction); 106984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 107bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float startX = mKeyframeData[startBase + X_OFFSET]; 108bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float endX = mKeyframeData[endBase + X_OFFSET]; 109bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float startY = mKeyframeData[startBase + Y_OFFSET]; 110bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float endY = mKeyframeData[endBase + Y_OFFSET]; 111984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 112bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float x = interpolate(intervalFraction, startX, endX); 113bc68f5adc222e6438588537fba222ea6a13f46e0George Mount float y = interpolate(intervalFraction, startY, endY); 114bc68f5adc222e6438588537fba222ea6a13f46e0George Mount 115bc68f5adc222e6438588537fba222ea6a13f46e0George Mount mTempPointF.set(x, y); 116bc68f5adc222e6438588537fba222ea6a13f46e0George Mount return mTempPointF; 117984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 118984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 119984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 120984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public void invalidateCache() { 121984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 122984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 123984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 124984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public void setEvaluator(TypeEvaluator evaluator) { 125984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 126984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 127984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 128984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Class getType() { 129984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return PointF.class; 130984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 131984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 132984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 133984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Keyframes clone() { 134984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount Keyframes clone = null; 135984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount try { 136984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount clone = (Keyframes) super.clone(); 137984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } catch (CloneNotSupportedException e) {} 138984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return clone; 139984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 140984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 141984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private PointF pointForIndex(int index) { 142984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount int base = (index * NUM_COMPONENTS); 143984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount int xOffset = base + X_OFFSET; 144984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount int yOffset = base + Y_OFFSET; 145984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount mTempPointF.set(mKeyframeData[xOffset], mKeyframeData[yOffset]); 146984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return mTempPointF; 147984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 148984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 149984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private static float interpolate(float fraction, float startValue, float endValue) { 150984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount float diff = endValue - startValue; 151984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return startValue + (diff * fraction); 152984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 153984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 154984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount /** 155984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Returns a FloatKeyframes for the X component of the Path. 156984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * @return a FloatKeyframes for the X component of the Path. 157984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount */ 158984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public FloatKeyframes createXFloatKeyframes() { 159984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return new FloatKeyframesBase() { 160984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 161984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public float getFloatValue(float fraction) { 162984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount PointF pointF = (PointF) PathKeyframes.this.getValue(fraction); 163984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return pointF.x; 164984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 165984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount }; 166984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 167984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 168984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount /** 169984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Returns a FloatKeyframes for the Y component of the Path. 170984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * @return a FloatKeyframes for the Y component of the Path. 171984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount */ 172984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public FloatKeyframes createYFloatKeyframes() { 173984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return new FloatKeyframesBase() { 174984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 175984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public float getFloatValue(float fraction) { 176984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount PointF pointF = (PointF) PathKeyframes.this.getValue(fraction); 177984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return pointF.y; 178984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 179984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount }; 180984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 181984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 182984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount /** 183984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Returns an IntKeyframes for the X component of the Path. 184984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * @return an IntKeyframes for the X component of the Path. 185984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount */ 186984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public IntKeyframes createXIntKeyframes() { 187984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return new IntKeyframesBase() { 188984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 189984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public int getIntValue(float fraction) { 190984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount PointF pointF = (PointF) PathKeyframes.this.getValue(fraction); 191984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return Math.round(pointF.x); 192984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 193984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount }; 194984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 195984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 196984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount /** 197984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * Returns an IntKeyframeSet for the Y component of the Path. 198984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount * @return an IntKeyframeSet for the Y component of the Path. 199984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount */ 200984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public IntKeyframes createYIntKeyframes() { 201984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return new IntKeyframesBase() { 202984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 203984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public int getIntValue(float fraction) { 204984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount PointF pointF = (PointF) PathKeyframes.this.getValue(fraction); 205984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return Math.round(pointF.y); 206984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 207984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount }; 208984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 209984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 210984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private abstract static class SimpleKeyframes implements Keyframes { 211984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 212984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public void setEvaluator(TypeEvaluator evaluator) { 213984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 214984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 215984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 216984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public void invalidateCache() { 217984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 218984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 219984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 220984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public ArrayList<Keyframe> getKeyframes() { 221984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return EMPTY_KEYFRAMES; 222984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 223984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 224984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 225984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Keyframes clone() { 226984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount Keyframes clone = null; 227984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount try { 228984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount clone = (Keyframes) super.clone(); 229984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } catch (CloneNotSupportedException e) {} 230984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return clone; 231984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 232984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 233984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 234984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private abstract static class IntKeyframesBase extends SimpleKeyframes implements IntKeyframes { 235984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 236984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Class getType() { 237984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return Integer.class; 238984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 239984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 240984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 241984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Object getValue(float fraction) { 242984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return getIntValue(fraction); 243984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 244984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 245984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 246984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount private abstract static class FloatKeyframesBase extends SimpleKeyframes 247984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount implements FloatKeyframes { 248984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 249984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Class getType() { 250984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return Float.class; 251984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 252984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount 253984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 254984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Object getValue(float fraction) { 255984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return getFloatValue(fraction); 256984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 257984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 258984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount} 259