feat: add API clearAnimation

This commit is contained in:
pengfei.zhou 2021-04-21 18:59:29 +08:00 committed by osborn
parent 93293b099f
commit 5c20680c4c
12 changed files with 155 additions and 26 deletions

View File

@ -51,6 +51,7 @@ import com.github.pengfeizhou.jscore.JavaValue;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.WeakHashMap;
import pub.doric.DoricContext; import pub.doric.DoricContext;
import pub.doric.DoricRegistry; import pub.doric.DoricRegistry;
@ -77,6 +78,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
protected ViewGroup.LayoutParams mLayoutParams; protected ViewGroup.LayoutParams mLayoutParams;
private String mType; private String mType;
protected JSObject mFlexConfig; protected JSObject mFlexConfig;
private final WeakHashMap<String, Animator> animators = new WeakHashMap<>();
public JSObject getFlexConfig() { public JSObject getFlexConfig() {
return mFlexConfig; return mFlexConfig;
@ -904,7 +906,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
return getNodeView().getPivotY() / getNodeView().getHeight(); return getNodeView().getPivotY() / getNodeView().getHeight();
} }
private String[] animatedKeys = { private final String[] animatedKeys = {
"translationX", "translationX",
"translationY", "translationY",
"scaleX", "scaleX",
@ -916,7 +918,25 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
public void doAnimation(JSValue value, final DoricPromise promise) { public void doAnimation(JSValue value, final DoricPromise promise) {
Animator animator = parseAnimator(value); Animator animator = parseAnimator(value);
if (animator != null) { if (animator != null) {
String animatorId = value.asObject().getProperty("id").asString().value();
animators.put(animatorId, animator);
// final float tx = getTranslationX();
// final float ty = getTranslationY();
// final float sx = getScaleX();
// final float sy = getScaleY();
// final float r = getRotation();
animator.addListener(new AnimatorListenerAdapter() { animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
// setTranslationX(tx);
// setTranslationY(ty);
// setScaleX(sx);
// setScaleY(sy);
// setRotation(r);
promise.reject(new JavaValue("Animation cancelled"));
}
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation); super.onAnimationEnd(animation);
@ -931,6 +951,28 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
} }
} }
@DoricMethod
public void clearAnimation(String id, final DoricPromise promise) {
Animator animator = animators.get(id);
if (animator != null) {
animator.cancel();
promise.resolve();
} else {
promise.reject(new JavaValue("Cannot find running animation for " + id));
}
}
@DoricMethod
public void cancelAnimation(String id, final DoricPromise promise) {
Animator animator = animators.get(id);
if (animator != null) {
animator.cancel();
promise.resolve();
} else {
promise.reject(new JavaValue("Cannot find running animation for " + id));
}
}
private Animator parseAnimator(JSValue value) { private Animator parseAnimator(JSValue value) {
if (!value.isObject()) { if (!value.isObject()) {
DoricLog.e("parseAnimator error"); DoricLog.e("parseAnimator error");

View File

@ -1380,6 +1380,7 @@ var Animation = /** @class */ (function () {
this.changeables = new Map; this.changeables = new Map;
this.duration = 0; this.duration = 0;
this.fillMode = exports.FillMode.Forward; this.fillMode = exports.FillMode.Forward;
this.id = uniqueId("Animation");
} }
Animation.prototype.toModel = function () { Animation.prototype.toModel = function () {
var e_1, _a; var e_1, _a;
@ -1409,7 +1410,8 @@ var Animation = /** @class */ (function () {
repeatCount: this.repeatCount, repeatCount: this.repeatCount,
repeatMode: this.repeatMode, repeatMode: this.repeatMode,
fillMode: this.fillMode, fillMode: this.fillMode,
timingFunction: this.timingFunction timingFunction: this.timingFunction,
id: this.id,
}; };
}; };
return Animation; return Animation;
@ -1480,13 +1482,13 @@ var TranslationAnimation = /** @class */ (function (_super) {
var _this = _super.call(this) || this; var _this = _super.call(this) || this;
_this.translationXChangeable = { _this.translationXChangeable = {
key: "translationX", key: "translationX",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
_this.translationYChangeable = { _this.translationYChangeable = {
key: "translationY", key: "translationY",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
_this.changeables.set("translationX", _this.translationXChangeable); _this.changeables.set("translationX", _this.translationXChangeable);
_this.changeables.set("translationY", _this.translationYChangeable); _this.changeables.set("translationY", _this.translationYChangeable);
@ -1640,6 +1642,7 @@ var AnimationSet = /** @class */ (function () {
function AnimationSet() { function AnimationSet() {
this.animations = []; this.animations = [];
this._duration = 0; this._duration = 0;
this.id = uniqueId("AnimationSet");
} }
AnimationSet.prototype.addAnimation = function (anim) { AnimationSet.prototype.addAnimation = function (anim) {
this.animations.push(anim); this.animations.push(anim);
@ -1661,6 +1664,7 @@ var AnimationSet = /** @class */ (function () {
return e.toModel(); return e.toModel();
}), }),
delay: this.delay, delay: this.delay,
id: this.id,
}; };
}; };
return AnimationSet; return AnimationSet;

View File

@ -314,6 +314,15 @@ class View {
} }
}); });
} }
cancelAnimation(context, animation) {
return this.nativeChannel(context, "cancelAnimation")(animation.id).then(() => {
this.__dirty_props__.translationX = this.translationX || 0;
this.__dirty_props__.translationY = this.translationY || 0;
this.__dirty_props__.scaleX = this.scaleX || 1;
this.__dirty_props__.scaleY = this.scaleY || 1;
this.__dirty_props__.rotation = this.rotation || 0;
});
}
} }
__decorate$d([ __decorate$d([
Property, Property,
@ -1051,6 +1060,7 @@ class Animation {
this.changeables = new Map; this.changeables = new Map;
this.duration = 0; this.duration = 0;
this.fillMode = exports.FillMode.Forward; this.fillMode = exports.FillMode.Forward;
this.id = uniqueId("Animation");
} }
toModel() { toModel() {
const changeables = []; const changeables = [];
@ -1069,7 +1079,8 @@ class Animation {
repeatCount: this.repeatCount, repeatCount: this.repeatCount,
repeatMode: this.repeatMode, repeatMode: this.repeatMode,
fillMode: this.fillMode, fillMode: this.fillMode,
timingFunction: this.timingFunction timingFunction: this.timingFunction,
id: this.id,
}; };
} }
} }
@ -1119,13 +1130,13 @@ class TranslationAnimation extends Animation {
super(); super();
this.translationXChangeable = { this.translationXChangeable = {
key: "translationX", key: "translationX",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
this.translationYChangeable = { this.translationYChangeable = {
key: "translationY", key: "translationY",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
this.changeables.set("translationX", this.translationXChangeable); this.changeables.set("translationX", this.translationXChangeable);
this.changeables.set("translationY", this.translationYChangeable); this.changeables.set("translationY", this.translationYChangeable);
@ -1228,6 +1239,7 @@ class AnimationSet {
constructor() { constructor() {
this.animations = []; this.animations = [];
this._duration = 0; this._duration = 0;
this.id = uniqueId("AnimationSet");
} }
addAnimation(anim) { addAnimation(anim) {
this.animations.push(anim); this.animations.push(anim);
@ -1245,6 +1257,7 @@ class AnimationSet {
return e.toModel(); return e.toModel();
}), }),
delay: this.delay, delay: this.delay,
id: this.id,
}; };
} }
} }

View File

@ -1835,6 +1835,15 @@ class View {
} }
}); });
} }
cancelAnimation(context, animation) {
return this.nativeChannel(context, "cancelAnimation")(animation.id).then(() => {
this.__dirty_props__.translationX = this.translationX || 0;
this.__dirty_props__.translationY = this.translationY || 0;
this.__dirty_props__.scaleX = this.scaleX || 1;
this.__dirty_props__.scaleY = this.scaleY || 1;
this.__dirty_props__.rotation = this.rotation || 0;
});
}
} }
__decorate$d([ __decorate$d([
Property, Property,
@ -2572,6 +2581,7 @@ class Animation {
this.changeables = new Map; this.changeables = new Map;
this.duration = 0; this.duration = 0;
this.fillMode = exports.FillMode.Forward; this.fillMode = exports.FillMode.Forward;
this.id = uniqueId("Animation");
} }
toModel() { toModel() {
const changeables = []; const changeables = [];
@ -2590,7 +2600,8 @@ class Animation {
repeatCount: this.repeatCount, repeatCount: this.repeatCount,
repeatMode: this.repeatMode, repeatMode: this.repeatMode,
fillMode: this.fillMode, fillMode: this.fillMode,
timingFunction: this.timingFunction timingFunction: this.timingFunction,
id: this.id,
}; };
} }
} }
@ -2640,13 +2651,13 @@ class TranslationAnimation extends Animation {
super(); super();
this.translationXChangeable = { this.translationXChangeable = {
key: "translationX", key: "translationX",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
this.translationYChangeable = { this.translationYChangeable = {
key: "translationY", key: "translationY",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
this.changeables.set("translationX", this.translationXChangeable); this.changeables.set("translationX", this.translationXChangeable);
this.changeables.set("translationY", this.translationYChangeable); this.changeables.set("translationY", this.translationYChangeable);
@ -2749,6 +2760,7 @@ class AnimationSet {
constructor() { constructor() {
this.animations = []; this.animations = [];
this._duration = 0; this._duration = 0;
this.id = uniqueId("AnimationSet");
} }
addAnimation(anim) { addAnimation(anim) {
this.animations.push(anim); this.animations.push(anim);
@ -2766,6 +2778,7 @@ class AnimationSet {
return e.toModel(); return e.toModel();
}), }),
delay: this.delay, delay: this.delay,
id: this.id,
}; };
} }
} }

6
doric-js/index.d.ts vendored
View File

@ -298,6 +298,7 @@ declare module 'doric/lib/src/ui/view' {
*/ */
flexConfig?: FlexConfig; flexConfig?: FlexConfig;
doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>; doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
cancelAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
} }
export abstract class Superview extends View { export abstract class Superview extends View {
subviewById(id: string): View | undefined; subviewById(id: string): View | undefined;
@ -326,6 +327,7 @@ declare module 'doric/lib/src/ui/animation' {
export interface IAnimation extends Modeling { export interface IAnimation extends Modeling {
duration: number; duration: number;
delay?: number; delay?: number;
id: string;
} }
export interface Changeable { export interface Changeable {
fromValue: number; fromValue: number;
@ -382,6 +384,7 @@ declare module 'doric/lib/src/ui/animation' {
delay?: number; delay?: number;
fillMode: FillMode; fillMode: FillMode;
timingFunction?: TimingFunction; timingFunction?: TimingFunction;
id: string;
toModel(): { toModel(): {
type: string; type: string;
delay: number | undefined; delay: number | undefined;
@ -395,6 +398,7 @@ declare module 'doric/lib/src/ui/animation' {
repeatMode: RepeatMode | undefined; repeatMode: RepeatMode | undefined;
fillMode: FillMode; fillMode: FillMode;
timingFunction: TimingFunction | undefined; timingFunction: TimingFunction | undefined;
id: string;
}; };
} }
export class ScaleAnimation extends Animation { export class ScaleAnimation extends Animation {
@ -442,12 +446,14 @@ declare module 'doric/lib/src/ui/animation' {
} }
export class AnimationSet implements IAnimation { export class AnimationSet implements IAnimation {
delay?: number; delay?: number;
id: string;
addAnimation(anim: IAnimation): void; addAnimation(anim: IAnimation): void;
get duration(): number; get duration(): number;
set duration(v: number); set duration(v: number);
toModel(): { toModel(): {
animations: Model; animations: Model;
delay: number | undefined; delay: number | undefined;
id: string;
}; };
} }
export {}; export {};

View File

@ -7,6 +7,7 @@ export declare enum RepeatMode {
export interface IAnimation extends Modeling { export interface IAnimation extends Modeling {
duration: number; duration: number;
delay?: number; delay?: number;
id: string;
} }
export interface Changeable { export interface Changeable {
fromValue: number; fromValue: number;
@ -63,6 +64,7 @@ declare abstract class Animation implements IAnimation {
delay?: number; delay?: number;
fillMode: FillMode; fillMode: FillMode;
timingFunction?: TimingFunction; timingFunction?: TimingFunction;
id: string;
toModel(): { toModel(): {
type: string; type: string;
delay: number | undefined; delay: number | undefined;
@ -76,6 +78,7 @@ declare abstract class Animation implements IAnimation {
repeatMode: RepeatMode | undefined; repeatMode: RepeatMode | undefined;
fillMode: FillMode; fillMode: FillMode;
timingFunction: TimingFunction | undefined; timingFunction: TimingFunction | undefined;
id: string;
}; };
} }
export declare class ScaleAnimation extends Animation { export declare class ScaleAnimation extends Animation {
@ -132,12 +135,14 @@ export declare class AnimationSet implements IAnimation {
private animations; private animations;
private _duration; private _duration;
delay?: number; delay?: number;
id: string;
addAnimation(anim: IAnimation): void; addAnimation(anim: IAnimation): void;
get duration(): number; get duration(): number;
set duration(v: number); set duration(v: number);
toModel(): { toModel(): {
animations: Model; animations: Model;
delay: number | undefined; delay: number | undefined;
id: string;
}; };
} }
export {}; export {};

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { uniqueId } from "../util/uniqueId";
export var RepeatMode; export var RepeatMode;
(function (RepeatMode) { (function (RepeatMode) {
RepeatMode[RepeatMode["RESTART"] = 1] = "RESTART"; RepeatMode[RepeatMode["RESTART"] = 1] = "RESTART";
@ -65,6 +66,7 @@ class Animation {
this.changeables = new Map; this.changeables = new Map;
this.duration = 0; this.duration = 0;
this.fillMode = FillMode.Forward; this.fillMode = FillMode.Forward;
this.id = uniqueId("Animation");
} }
toModel() { toModel() {
const changeables = []; const changeables = [];
@ -83,7 +85,8 @@ class Animation {
repeatCount: this.repeatCount, repeatCount: this.repeatCount,
repeatMode: this.repeatMode, repeatMode: this.repeatMode,
fillMode: this.fillMode, fillMode: this.fillMode,
timingFunction: this.timingFunction timingFunction: this.timingFunction,
id: this.id,
}; };
} }
} }
@ -133,13 +136,13 @@ export class TranslationAnimation extends Animation {
super(); super();
this.translationXChangeable = { this.translationXChangeable = {
key: "translationX", key: "translationX",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
this.translationYChangeable = { this.translationYChangeable = {
key: "translationY", key: "translationY",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
}; };
this.changeables.set("translationX", this.translationXChangeable); this.changeables.set("translationX", this.translationXChangeable);
this.changeables.set("translationY", this.translationYChangeable); this.changeables.set("translationY", this.translationYChangeable);
@ -242,6 +245,7 @@ export class AnimationSet {
constructor() { constructor() {
this.animations = []; this.animations = [];
this._duration = 0; this._duration = 0;
this.id = uniqueId("AnimationSet");
} }
addAnimation(anim) { addAnimation(anim) {
this.animations.push(anim); this.animations.push(anim);
@ -259,6 +263,7 @@ export class AnimationSet {
return e.toModel(); return e.toModel();
}), }),
delay: this.delay, delay: this.delay,
id: this.id,
}; };
} }
} }

View File

@ -130,6 +130,7 @@ export declare abstract class View implements Modeling {
*/ */
flexConfig?: FlexConfig; flexConfig?: FlexConfig;
doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>; doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
cancelAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
} }
export declare abstract class Superview extends View { export declare abstract class Superview extends View {
subviewById(id: string): View | undefined; subviewById(id: string): View | undefined;

View File

@ -199,6 +199,15 @@ export class View {
} }
}); });
} }
cancelAnimation(context, animation) {
return this.nativeChannel(context, "cancelAnimation")(animation.id).then(() => {
this.__dirty_props__.translationX = this.translationX || 0;
this.__dirty_props__.translationY = this.translationY || 0;
this.__dirty_props__.scaleX = this.scaleX || 1;
this.__dirty_props__.scaleY = this.scaleY || 1;
this.__dirty_props__.rotation = this.rotation || 0;
});
}
} }
__decorate([ __decorate([
Property, Property,

View File

@ -15,6 +15,7 @@
*/ */
import { Modeling, Model } from "../util/types" import { Modeling, Model } from "../util/types"
import { uniqueId } from "../util/uniqueId"
export type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY" | "rotationX" | "rotationY" export type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY" | "rotationX" | "rotationY"
@ -26,6 +27,7 @@ export enum RepeatMode {
export interface IAnimation extends Modeling { export interface IAnimation extends Modeling {
duration: number duration: number
delay?: number delay?: number
id: string
} }
export interface Changeable { export interface Changeable {
@ -85,6 +87,7 @@ abstract class Animation implements IAnimation {
delay?: number delay?: number
fillMode = FillMode.Forward fillMode = FillMode.Forward
timingFunction?: TimingFunction timingFunction?: TimingFunction
id = uniqueId("Animation")
toModel() { toModel() {
const changeables = [] const changeables = []
for (let e of this.changeables.values()) { for (let e of this.changeables.values()) {
@ -102,7 +105,8 @@ abstract class Animation implements IAnimation {
repeatCount: this.repeatCount, repeatCount: this.repeatCount,
repeatMode: this.repeatMode, repeatMode: this.repeatMode,
fillMode: this.fillMode, fillMode: this.fillMode,
timingFunction: this.timingFunction timingFunction: this.timingFunction,
id: this.id,
} }
} }
} }
@ -160,13 +164,13 @@ export class ScaleAnimation extends Animation {
export class TranslationAnimation extends Animation { export class TranslationAnimation extends Animation {
private translationXChangeable: Changeable = { private translationXChangeable: Changeable = {
key: "translationX", key: "translationX",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
} }
private translationYChangeable: Changeable = { private translationYChangeable: Changeable = {
key: "translationY", key: "translationY",
fromValue: 1, fromValue: 0,
toValue: 1, toValue: 0,
} }
constructor() { constructor() {
super() super()
@ -292,6 +296,8 @@ export class AnimationSet implements IAnimation {
private animations: IAnimation[] = [] private animations: IAnimation[] = []
private _duration = 0 private _duration = 0
delay?: number delay?: number
id = uniqueId("AnimationSet")
addAnimation(anim: IAnimation) { addAnimation(anim: IAnimation) {
this.animations.push(anim) this.animations.push(anim)
} }
@ -311,6 +317,7 @@ export class AnimationSet implements IAnimation {
return e.toModel() return e.toModel()
}) as Model, }) as Model,
delay: this.delay, delay: this.delay,
id: this.id,
} }
} }
} }

View File

@ -342,6 +342,16 @@ export abstract class View implements Modeling {
} }
}) })
} }
clearAnimation(context: BridgeContext, animation: IAnimation) {
return this.nativeChannel(context, "clearAnimation")(animation.id).then(() => {
this.__dirty_props__.translationX = this.translationX || 0
this.__dirty_props__.translationY = this.translationY || 0
this.__dirty_props__.scaleX = this.scaleX || 1
this.__dirty_props__.scaleY = this.scaleY || 1
this.__dirty_props__.rotation = this.rotation || 0
})
}
} }
export abstract class Superview extends View { export abstract class Superview extends View {

View File

@ -351,6 +351,20 @@ export abstract class View implements Modeling {
} }
}) })
} }
clearAnimation(context: BridgeContext, animation: IAnimation) {
return this.nativeChannel(context, "clearAnimation")(animation.id).then(() => {
this.__dirty_props__.translationX = this.translationX || 0
this.__dirty_props__.translationY = this.translationY || 0
this.__dirty_props__.scaleX = this.scaleX || 1
this.__dirty_props__.scaleY = this.scaleY || 1
this.__dirty_props__.rotation = this.rotation || 0
})
}
cancelAnimation(context: BridgeContext, animation: IAnimation) {
return this.nativeChannel(context, "cancelAnimation")(animation.id)
}
} }
export abstract class Superview extends View { export abstract class Superview extends View {