feat:Android support animation
This commit is contained in:
parent
85a8e0fdaf
commit
9c2348a19c
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user