/** * Creates a new animation with original value type <code>T</code> and a new transformed value * type <code>W</code>. * * @param <W> The animation's new transformed value type. * @param transformer The value transformer to use to transform the animation's original type * <code>T</code> to a new transformed value type <code>W</code>. * @return A new animation with the same original value type <code>T</code> and transformed value * type <code>W</code>. */ @NonNull public <W> Animation<T, W> transform(ValueTransformer<T, W> transformer) { return new Animation<>(keyframeSet, transformer) .startDelay(startDelay) .duration(duration) .repeatCount(repeatCount) .repeatMode(repeatMode) .interpolator(interpolator); }
@NonNull static Animation<?, float[]> asAnimation(float[] initialValue) { return Animation.ofFloatArray(initialValue, initialValue).duration(0); }
@NonNull static Animation<?, PathData> asAnimation(PathData initialValue) { return Animation.ofPathMorph(initialValue, initialValue).duration(0); }
switch (valueType) { case VALUE_TYPE_FLOAT: anim = Animation.ofFloat(keyframes); break; case VALUE_TYPE_COLOR: anim = Animation.ofArgb(keyframes); break; case VALUE_TYPE_PATH: anim = Animation.ofPathMorph(keyframes); break; default: anim.startDelay(startTime) .duration(endTime - startTime) .interpolator(interpolator == null ? DEFAULT_INTERPOLATOR : interpolator) .repeatCount(repeatCount) .repeatMode(repeatMode)); map.put(propertyName, anims); return map;
Animation.ofPathMotion(path) .startDelay(startTime) .duration(endTime - startTime) .interpolator(interpolator == null ? DEFAULT_INTERPOLATOR : interpolator) .repeatCount(repeatCount) .repeatMode(repeatMode); if (propertyNameX != null) { final List<Animation<?, ?>> list = new ArrayList<>(1); list.add( anim.transform( new Animation.ValueTransformer<PointF, Float>() { @NonNull final List<Animation<?, ?>> list = new ArrayList<>(1); list.add( anim.transform( new Animation.ValueTransformer<PointF, Float>() { @NonNull
private KyrieDrawable createVortexDrawable() { final KyrieDrawable.Builder builder = KyrieDrawable.builder().viewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); for (Polygon polygon : polygons) { final float length = polygon.length; final float totalLength = length * polygon.laps; builder.child( PathNode.builder() .pathData(PathData.parse(polygon.pathData)) .strokeWidth(4f) .strokeColor(polygon.color) .strokeDashArray( Animation.ofFloatArray(new float[] {0, length}, new float[] {length, 0}) .repeatCount(Animation.INFINITE) .duration(DURATION)) .strokeDashOffset( Animation.ofFloat(0f, 2 * totalLength) .repeatCount(Animation.INFINITE) .duration(DURATION))); } return builder.build(); }
.strokeWidth(1f) .fillColor( Animation.ofArgb(hippoFillColor, elephantFillColor).duration(300), Animation.ofArgb(buffaloFillColor).startDelay(600).duration(300), Animation.ofArgb(hippoFillColor).startDelay(1200).duration(300)) .pathData( Animation.ofPathMorph( Keyframe.of(0, hippoPathData), Keyframe.of(0.2f, elephantPathData), Keyframe.of(0.8f, buffaloPathData), Keyframe.of(1, hippoPathData)) .duration(1500))) .build(); kyrieDrawable.addListener(new SampleListenerAdapter(seekBar));
private KyrieDrawable createLapsDrawable() { final KyrieDrawable.Builder builder = KyrieDrawable.builder().viewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); for (Polygon polygon : polygons) { builder.child( PathNode.builder() .pathData(PathData.parse(polygon.pathData)) .strokeWidth(4f) .strokeColor(polygon.color)); } for (Polygon polygon : polygons) { final PathData pathData = PathData.parse(TextUtils.join(" ", Collections.nCopies(polygon.laps, polygon.pathData))); final Animation<PointF, PointF> pathMotion = Animation.ofPathMotion(PathData.toPath(pathData)) .repeatCount(Animation.INFINITE) .duration(DURATION); builder.child( CircleNode.builder() .fillColor(Color.BLACK) .radius(8) .centerX(pathMotion.transform(p -> p.x)) .centerY(pathMotion.transform(p -> p.y))); } return builder.build(); }
@NonNull private static <V> Animation<V, V> ofObject(ValueEvaluator<V> evaluator, V[] values) { if (values.length < 1) { throw new IllegalArgumentException("Must specify at least one value"); } return new Animation<>( KeyframeSet.ofObject(evaluator, values), new IdentityValueTransformer<V>()); }
case VALUE_TYPE_FLOAT: if (fromValue == null) { anim = Animation.ofFloat((Float) toValue); } else { anim = Animation.ofFloat((Float) fromValue, (Float) toValue); anim = Animation.ofArgb((Integer) toValue); } else { anim = Animation.ofArgb((Integer) fromValue, (Integer) toValue); if (fromValue == null) { anim = Animation.ofPathMorph((PathData) toValue) .startDelay(startTime) .duration(endTime - startTime); } else { anim = Animation.ofPathMorph((PathData) fromValue, (PathData) toValue); anim.startDelay(startTime) .duration(endTime - startTime) .interpolator(interpolator == null ? DEFAULT_INTERPOLATOR : interpolator) .repeatCount(repeatCount) .repeatMode(repeatMode)); final Map<String, List<Animation<?, ?>>> map = new ArrayMap<>(1); map.put(propertyName, anims);
@NonNull private static <V> Animation<V, V> ofObject(ValueEvaluator<V> evaluator, Keyframe<V>[] values) { if (values.length < 1) { throw new IllegalArgumentException("Must specify at least one keyframe"); } return new Animation<>( KeyframeSet.ofObject(evaluator, values), new IdentityValueTransformer<V>()); }
/** * Constructs and returns an {@link Animation} that animates through {@link PointF} values in * order to simulate motion along the given path. Clients can use {@link * #transform(ValueTransformer)} to transform the returned animation into one that outputs floats * corresponding to the path's x/y coordinates. * * @param path The path to animate values along. * @return A new {@link Animation}. */ @NonNull public static Animation<PointF, PointF> ofPathMotion(Path path) { if (path.isEmpty()) { throw new IllegalArgumentException("The path must not be empty"); } return new Animation<>(KeyframeSet.ofPath(path), new IdentityValueTransformer<PointF>()); }