feat:Android support animation

This commit is contained in:
pengfei.zhou 2019-11-30 17:10:28 +08:00
parent 85a8e0fdaf
commit 9c2348a19c
4 changed files with 122 additions and 27 deletions

View File

@ -16,12 +16,13 @@
package pub.doric.shader; package pub.doric.shader;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator; import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@ -29,16 +30,18 @@ import android.widget.LinearLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import pub.doric.Doric;
import pub.doric.DoricContext; import pub.doric.DoricContext;
import pub.doric.DoricRegistry; import pub.doric.DoricRegistry;
import pub.doric.async.AsyncResult; import pub.doric.async.AsyncResult;
import pub.doric.extension.bridge.DoricMethod; import pub.doric.extension.bridge.DoricMethod;
import pub.doric.extension.bridge.DoricPromise;
import pub.doric.utils.DoricContextHolder; import pub.doric.utils.DoricContextHolder;
import pub.doric.utils.DoricConstant; import pub.doric.utils.DoricConstant;
import pub.doric.utils.DoricLog;
import pub.doric.utils.DoricMetaInfo; import pub.doric.utils.DoricMetaInfo;
import pub.doric.utils.DoricUtils; import pub.doric.utils.DoricUtils;
import com.github.pengfeizhou.jscore.JSArray;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue; import com.github.pengfeizhou.jscore.JSValue;
@ -636,4 +639,62 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
public float getPivotY() { public float getPivotY() {
return getNodeView().getPivotY() / getNodeView().getHeight(); return getNodeView().getPivotY() / getNodeView().getHeight();
} }
@DoricMethod
public void doAnimation(JSValue value, final DoricPromise promise) {
Animator animator = parseAnimator(value);
if (animator != null) {
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
promise.resolve();
}
});
animator.start();
}
}
private Animator parseAnimator(JSValue value) {
if (value.isArray()) {
AnimatorSet animatorSet = new AnimatorSet();
for (int i = 0; i < value.asArray().size(); i++) {
animatorSet.play(parseAnimator(value.asArray().get(i)));
}
return animatorSet;
} else if (value.isObject()) {
JSArray changeables = value.asObject().getProperty("changeables").asArray();
AnimatorSet animatorSet = new AnimatorSet();
for (int j = 0; j < changeables.size(); j++) {
animatorSet.play(parseChangeable(changeables.get(j).asObject()));
}
long duration = value.asObject().getProperty("duration").asNumber().toLong();
animatorSet.setDuration(duration);
JSValue delayJS = value.asObject().getProperty("delay");
if (delayJS.isNumber()) {
animatorSet.setStartDelay(delayJS.asNumber().toLong());
}
return animatorSet;
} else {
return null;
}
}
private Animator parseChangeable(JSObject jsObject) {
String key = jsObject.getProperty("key").asString().value();
ObjectAnimator animator = ObjectAnimator.ofFloat(this,
key,
jsObject.getProperty("fromValue").asNumber().toFloat(),
jsObject.getProperty("toValue").asNumber().toFloat()
);
JSValue repeatCount = jsObject.getProperty("repeatCount");
if (repeatCount.isNumber()) {
animator.setRepeatCount(repeatCount.asNumber().toInt() + 1);
}
JSValue repeatMode = jsObject.getProperty("repeatMode");
if (repeatMode.isNumber()) {
animator.setRepeatMode(repeatMode.asNumber().toInt());
}
return animator;
}
} }

View File

@ -1,4 +1,4 @@
import { animate, Group, Panel, gravity, Color, LayoutSpec, vlayout, scroller, layoutConfig, IVLayout, modal, IText, network, View, stack, IHLayout, hlayout, IView, text } from "doric"; import { animate, Group, Panel, gravity, Color, AnimationSet, vlayout, scroller, layoutConfig, IVLayout, modal, IText, network, View, stack, IHLayout, hlayout, IView, text, TranslationAnimation, ScaleAnimation, RotationAnimation } from "doric";
import { title, colors, box } from "./utils"; import { title, colors, box } from "./utils";
function thisLabel(str: string) { function thisLabel(str: string) {
@ -164,6 +164,36 @@ class AnimatorDemo extends Panel {
}); });
} }
}), }),
thisLabel('animationSet').apply({
onClick: () => {
const animationSet = new AnimationSet
const translate = new TranslationAnimation
translate.fromTranslationX = 10
translate.toTranslationX = 200
translate.fromTranslationY = 10
translate.toTranslationY = 200
translate.duration = 1000
const scale = new ScaleAnimation
scale.fromScaleX = 1
scale.toScaleX = 5
scale.fromScaleY = 1
scale.toScaleY = 5
scale.duration = 1000
const rotation = new RotationAnimation
rotation.fromRotation = 0
rotation.toRotation = 6
rotation.duration = 1000
animationSet.addAnimation(translate)
animationSet.addAnimation(scale)
animationSet.addAnimation(rotation)
view.doAnimation(context, animationSet)
}
}),
]).apply({ space: 10 } as IHLayout), ]).apply({ space: 10 } as IHLayout),
] ]
).apply({ space: 10 } as IVLayout), ).apply({ space: 10 } as IVLayout),

View File

@ -19,12 +19,10 @@ import { Modeling, Model } from "../util/types"
export type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY" export type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY"
export enum RepeatMode { export enum RepeatMode {
RESTART, RESTART = 1,
REVERSE, REVERSE = 2,
} }
export interface IAnimation extends Modeling { export interface IAnimation extends Modeling {
repeatCount?: number
repeatMode?: RepeatMode
duration: number duration: number
delay?: number delay?: number
} }
@ -33,6 +31,8 @@ export interface Changeable {
fromValue: number fromValue: number
toValue: number toValue: number
key: AnimatedKey key: AnimatedKey
repeatCount?: number
repeatMode?: RepeatMode
} }
abstract class Animation implements IAnimation { abstract class Animation implements IAnimation {
@ -43,24 +43,27 @@ abstract class Animation implements IAnimation {
delay?: number delay?: number
toModel() { toModel() {
const ret = [] const changeables = []
for (let e of this.changeables.values()) { for (let e of this.changeables.values()) {
ret.push({ changeables.push({
repeatCount: this.repeatCount,
repeatMode: this.repeatMode,
delay: this.delay,
duration: this.duration,
key: e.key, key: e.key,
fromValue: e.fromValue, fromValue: e.fromValue,
toValue: e.toValue, toValue: e.toValue,
repeatCount: this.repeatCount,
repeatMode: this.repeatMode,
}) })
} }
return ret return {
type: this.constructor.name,
delay: this.delay,
duration: this.duration,
changeables,
}
} }
} }
export class ScaleAnimation extends Animation { export class ScaleAnimation extends Animation {
private scaleXChaneable: Changeable = { private scaleXChangeable: Changeable = {
key: "scaleX", key: "scaleX",
fromValue: 1, fromValue: 1,
toValue: 1, toValue: 1,
@ -72,25 +75,25 @@ export class ScaleAnimation extends Animation {
} }
constructor() { constructor() {
super() super()
this.changeables.set("scaleX", this.scaleXChaneable) this.changeables.set("scaleX", this.scaleXChangeable)
this.changeables.set("scaleY", this.scaleXChaneable) this.changeables.set("scaleY", this.scaleYChangeable)
} }
set fromScaleX(v: number) { set fromScaleX(v: number) {
this.scaleXChaneable.fromValue = v this.scaleXChangeable.fromValue = v
} }
get fromScaleX() { get fromScaleX() {
return this.scaleXChaneable.fromValue return this.scaleXChangeable.fromValue
} }
set toScaleX(v: number) { set toScaleX(v: number) {
this.scaleXChaneable.toValue = v this.scaleXChangeable.toValue = v
} }
get toScaleX() { get toScaleX() {
return this.scaleXChaneable.toValue return this.scaleXChangeable.toValue
} }
set fromScaleY(v: number) { set fromScaleY(v: number) {
this.scaleYChangeable.fromValue = v this.scaleYChangeable.fromValue = v
@ -186,14 +189,15 @@ export class RotationAnimation extends Animation {
} }
} }
export class AnimaionSet implements IAnimation { export class AnimationSet implements IAnimation {
animations: IAnimation[] = [] private animations: IAnimation[] = []
_duration = 0 _duration = 0
repeatCount?: number
repeatMode?: RepeatMode
delay?: number delay?: number
addAnimation(anim: IAnimation) {
this.animations.push(anim)
}
get duration() { get duration() {
return this._duration return this._duration
} }

View File

@ -336,7 +336,7 @@ export abstract class View implements Modeling, IView {
/**----------transform----------*/ /**----------transform----------*/
doAnimation(context: BridgeContext, animation: IAnimation) { doAnimation(context: BridgeContext, animation: IAnimation) {
return this.nativeChannel(context, "doAnimation")(animation) return this.nativeChannel(context, "doAnimation")(animation.toModel())
} }
} }