feat:Add cancelAnimation and clearAnimation
This commit is contained in:
parent
15a62bad8a
commit
e7ced92281
@ -920,20 +920,10 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
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() {
|
||||
@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"));
|
||||
}
|
||||
|
||||
@ -956,10 +946,8 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
Animator animator = animators.get(id);
|
||||
if (animator != null) {
|
||||
animator.cancel();
|
||||
promise.resolve();
|
||||
} else {
|
||||
promise.reject(new JavaValue("Cannot find running animation for " + id));
|
||||
}
|
||||
promise.resolve();
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
@ -967,10 +955,8 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
Animator animator = animators.get(id);
|
||||
if (animator != null) {
|
||||
animator.cancel();
|
||||
promise.resolve();
|
||||
} else {
|
||||
promise.reject(new JavaValue("Cannot find running animation for " + id));
|
||||
}
|
||||
promise.resolve();
|
||||
}
|
||||
|
||||
private Animator parseAnimator(JSValue value) {
|
||||
|
@ -18,21 +18,30 @@ class Animations extends Panel {
|
||||
height: 20,
|
||||
backgroundColor: Color.BLUE,
|
||||
}),
|
||||
|
||||
text({
|
||||
text: "Start",
|
||||
onClick: () => {
|
||||
view.doAnimation(context, animation)
|
||||
}
|
||||
}),
|
||||
|
||||
text({
|
||||
text: "Cancel",
|
||||
onClick: () => {
|
||||
view.cancelAnimation(context, animation)
|
||||
}
|
||||
}),
|
||||
|
||||
text({
|
||||
text: "Clear",
|
||||
onClick: () => {
|
||||
view.clearAnimation(context, animation)
|
||||
}
|
||||
}),
|
||||
],
|
||||
{
|
||||
space: 10,
|
||||
space: 20,
|
||||
layoutConfig: layoutConfig().most(),
|
||||
gravity: Gravity.Center
|
||||
}).in(root)
|
||||
|
@ -35,6 +35,10 @@ @interface AnimationCallback : NSObject <CAAnimationDelegate>
|
||||
@property(nonatomic, strong) void (^startBlock)(AnimationCallback *callback);
|
||||
|
||||
@property(nonatomic, strong) void (^endBlock)(AnimationCallback *callback);
|
||||
|
||||
@property(nonatomic, strong) void (^cancelBlock)(void);
|
||||
@property(nonatomic, strong) void (^clearBlock)(void);
|
||||
|
||||
@end
|
||||
|
||||
@implementation AnimationCallback
|
||||
@ -507,37 +511,75 @@ - (NSDictionary *)transformation {
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
- (void)setTransformation:(NSDictionary *)dictionary {
|
||||
self.translationX = dictionary[@"translationX"];
|
||||
self.translationY = dictionary[@"translationY"];
|
||||
self.scaleX = dictionary[@"scaleX"];
|
||||
self.scaleY = dictionary[@"scaleY"];
|
||||
self.rotation = dictionary[@"rotation"];
|
||||
};
|
||||
|
||||
#pragma animations
|
||||
|
||||
- (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||
CAAnimation *animation = [self parseAnimation:params];
|
||||
AnimationCallback *originDelegate = animation.delegate;
|
||||
AnimationCallback *animationCallback = [[AnimationCallback new] also:^(AnimationCallback *it) {
|
||||
__block BOOL stop = NO;
|
||||
it.startBlock = ^(AnimationCallback *callback) {
|
||||
if (originDelegate) {
|
||||
originDelegate.startBlock(callback);
|
||||
}
|
||||
[self transformProperties];
|
||||
};
|
||||
it.endBlock = ^(AnimationCallback *callback) {
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
if (originDelegate) {
|
||||
originDelegate.endBlock(callback);
|
||||
}
|
||||
[self.view.layer removeAllAnimations];
|
||||
[self transformProperties];
|
||||
[promise resolve:self.transformation];
|
||||
};
|
||||
it.cancelBlock = ^{
|
||||
stop = YES;
|
||||
self.view.layer.transform = self.view.layer.presentationLayer.transform;
|
||||
[promise reject:@"Animation cancelled"];
|
||||
};
|
||||
it.clearBlock = ^{
|
||||
stop = YES;
|
||||
[promise reject:@"Animation cleared"];
|
||||
};
|
||||
}];
|
||||
animation.delegate = animationCallback;
|
||||
if (params[@"delay"]) {
|
||||
animation.beginTime = CACurrentMediaTime() + [params[@"delay"] floatValue] / 1000;
|
||||
}
|
||||
animation.removedOnCompletion = NO;
|
||||
animation.removedOnCompletion = YES;
|
||||
animation.fillMode = kCAFillModeForwards;
|
||||
if (animation.duration == 0) {
|
||||
animation.duration = FLT_MIN;
|
||||
}
|
||||
[self.view.layer addAnimation:animation forKey:nil];
|
||||
[self.view.layer addAnimation:animation forKey:params[@"id"]];
|
||||
}
|
||||
|
||||
- (void)clearAnimation:(NSString *)animationId withPromise:(DoricPromise *)promise {
|
||||
CAAnimation *caAnimation = [self.view.layer animationForKey:animationId];
|
||||
if ([caAnimation.delegate isKindOfClass:AnimationCallback.class]) {
|
||||
((AnimationCallback *) caAnimation.delegate).clearBlock();
|
||||
}
|
||||
[self.view.layer removeAnimationForKey:animationId];
|
||||
[promise resolve:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void)cancelAnimation:(NSString *)animationId withPromise:(DoricPromise *)promise {
|
||||
CAAnimation *caAnimation = [self.view.layer animationForKey:animationId];
|
||||
if ([caAnimation.delegate isKindOfClass:AnimationCallback.class]) {
|
||||
((AnimationCallback *) caAnimation.delegate).cancelBlock();
|
||||
}
|
||||
[self.view.layer removeAnimationForKey:animationId];
|
||||
[promise resolve:nil];
|
||||
}
|
||||
|
||||
- (CFTimeInterval)computeDurationOfAnimations:(NSArray<CAAnimation *> *)animations {
|
||||
@ -584,40 +626,6 @@ - (CAAnimation *)parseAnimation:(id)params {
|
||||
return animationGroup;
|
||||
} else if ([params isKindOfClass:[NSDictionary class]]) {
|
||||
NSArray<NSDictionary *> *changeables = params[@"changeables"];
|
||||
NSString *type = params[@"type"];
|
||||
if ([@"TranslationAnimation" isEqualToString:type]) {
|
||||
__block CGPoint from = self.view.layer.position;
|
||||
__block CGPoint to = self.view.layer.position;
|
||||
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
|
||||
[changeables forEach:^(NSDictionary *obj) {
|
||||
NSString *key = obj[@"key"];
|
||||
if ([@"translationX" isEqualToString:key]) {
|
||||
from.x += [obj[@"fromValue"] floatValue] - self.translationX.floatValue;
|
||||
to.x += [obj[@"toValue"] floatValue] - self.translationX.floatValue;
|
||||
[self setFillMode:animation
|
||||
key:key
|
||||
startValue:obj[@"fromValue"]
|
||||
endValue:obj[@"toValue"]
|
||||
fillMode:params[@"fillMode"]];
|
||||
} else if ([@"translationY" isEqualToString:key]) {
|
||||
from.y += [obj[@"fromValue"] floatValue] - self.translationY.floatValue;
|
||||
to.y += [obj[@"toValue"] floatValue] - self.translationY.floatValue;
|
||||
[self setFillMode:animation
|
||||
key:key
|
||||
startValue:obj[@"fromValue"]
|
||||
endValue:obj[@"toValue"]
|
||||
fillMode:params[@"fillMode"]];
|
||||
}
|
||||
|
||||
}];
|
||||
animation.fromValue = [NSValue valueWithCGPoint:from];
|
||||
animation.toValue = [NSValue valueWithCGPoint:to];
|
||||
if (params[@"timingFunction"]) {
|
||||
animation.timingFunction = [self translateToTimingFunction:params[@"timingFunction"]];
|
||||
}
|
||||
[self setAnimation:animation params:params];
|
||||
return animation;
|
||||
} else {
|
||||
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
|
||||
NSMutableArray <CABasicAnimation *> *animations = [NSMutableArray new];
|
||||
|
||||
@ -652,7 +660,6 @@ - (CAAnimation *)parseAnimation:(id)params {
|
||||
[self setAnimation:animationGroup params:params];
|
||||
return animationGroup;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@ -752,7 +759,15 @@ - (void)setAnimatedValue:(NSString *)key value:(NSNumber *)value {
|
||||
- (CABasicAnimation *)parseChangeable:(NSDictionary *)params fillMode:(NSNumber *)fillMode {
|
||||
NSString *key = params[@"key"];
|
||||
CABasicAnimation *animation = [CABasicAnimation animation];
|
||||
if ([@"scaleX" isEqualToString:key]) {
|
||||
if ([@"translationX" isEqualToString:key]) {
|
||||
animation.keyPath = @"transform.translation.x";
|
||||
animation.fromValue = params[@"fromValue"];
|
||||
animation.toValue = params[@"toValue"];
|
||||
} else if ([@"translationY" isEqualToString:key]) {
|
||||
animation.keyPath = @"transform.translation.y";
|
||||
animation.fromValue = params[@"fromValue"];
|
||||
animation.toValue = params[@"toValue"];
|
||||
} else if ([@"scaleX" isEqualToString:key]) {
|
||||
animation.keyPath = @"transform.scale.x";
|
||||
animation.fromValue = params[@"fromValue"];
|
||||
animation.toValue = params[@"toValue"];
|
||||
|
@ -399,6 +399,19 @@ var View = /** @class */ (function () {
|
||||
}
|
||||
});
|
||||
};
|
||||
View.prototype.clearAnimation = function (context, animation) {
|
||||
var _this = this;
|
||||
return this.nativeChannel(context, "clearAnimation")(animation.id).then(function () {
|
||||
_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;
|
||||
});
|
||||
};
|
||||
View.prototype.cancelAnimation = function (context, animation) {
|
||||
return this.nativeChannel(context, "cancelAnimation")(animation.id);
|
||||
};
|
||||
__decorate$d([
|
||||
Property,
|
||||
__metadata$d("design:type", Number)
|
||||
|
@ -314,8 +314,8 @@ class View {
|
||||
}
|
||||
});
|
||||
}
|
||||
cancelAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "cancelAnimation")(animation.id).then(() => {
|
||||
clearAnimation(context, animation) {
|
||||
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;
|
||||
@ -323,6 +323,9 @@ class View {
|
||||
this.__dirty_props__.rotation = this.rotation || 0;
|
||||
});
|
||||
}
|
||||
cancelAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "cancelAnimation")(animation.id);
|
||||
}
|
||||
}
|
||||
__decorate$d([
|
||||
Property,
|
||||
|
@ -1835,8 +1835,8 @@ class View {
|
||||
}
|
||||
});
|
||||
}
|
||||
cancelAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "cancelAnimation")(animation.id).then(() => {
|
||||
clearAnimation(context, animation) {
|
||||
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;
|
||||
@ -1844,6 +1844,9 @@ class View {
|
||||
this.__dirty_props__.rotation = this.rotation || 0;
|
||||
});
|
||||
}
|
||||
cancelAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "cancelAnimation")(animation.id);
|
||||
}
|
||||
}
|
||||
__decorate$d([
|
||||
Property,
|
||||
|
3
doric-js/index.d.ts
vendored
3
doric-js/index.d.ts
vendored
@ -298,7 +298,8 @@ declare module 'doric/lib/src/ui/view' {
|
||||
*/
|
||||
flexConfig?: FlexConfig;
|
||||
doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
cancelAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
clearAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
cancelAnimation(context: BridgeContext, animation: IAnimation): Promise<any>;
|
||||
}
|
||||
export abstract class Superview extends View {
|
||||
subviewById(id: string): View | undefined;
|
||||
|
3
doric-js/lib/src/ui/view.d.ts
vendored
3
doric-js/lib/src/ui/view.d.ts
vendored
@ -130,7 +130,8 @@ export declare abstract class View implements Modeling {
|
||||
*/
|
||||
flexConfig?: FlexConfig;
|
||||
doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
cancelAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
clearAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
cancelAnimation(context: BridgeContext, animation: IAnimation): Promise<any>;
|
||||
}
|
||||
export declare abstract class Superview extends View {
|
||||
subviewById(id: string): View | undefined;
|
||||
|
@ -199,8 +199,8 @@ export class View {
|
||||
}
|
||||
});
|
||||
}
|
||||
cancelAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "cancelAnimation")(animation.id).then(() => {
|
||||
clearAnimation(context, animation) {
|
||||
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;
|
||||
@ -208,6 +208,9 @@ export class View {
|
||||
this.__dirty_props__.rotation = this.rotation || 0;
|
||||
});
|
||||
}
|
||||
cancelAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "cancelAnimation")(animation.id);
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
|
@ -352,6 +352,10 @@ export abstract class View implements Modeling {
|
||||
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 {
|
||||
|
Reference in New Issue
Block a user