feat:iOS support fillmode and delay
This commit is contained in:
		| @@ -656,10 +656,15 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder { | ||||
|     } | ||||
|  | ||||
|     private Animator parseAnimator(JSValue value) { | ||||
|         if (value.isArray()) { | ||||
|         if (!value.isObject()) { | ||||
|             DoricLog.e("parseAnimator error"); | ||||
|             return null; | ||||
|         } | ||||
|         JSValue animations = value.asObject().getProperty("animations"); | ||||
|         if (animations.isArray()) { | ||||
|             AnimatorSet animatorSet = new AnimatorSet(); | ||||
|             for (int i = 0; i < value.asArray().size(); i++) { | ||||
|                 animatorSet.play(parseAnimator(value.asArray().get(i))); | ||||
|             for (int i = 0; i < animations.asArray().size(); i++) { | ||||
|                 animatorSet.play(parseAnimator(animations.asArray().get(i))); | ||||
|             } | ||||
|             return animatorSet; | ||||
|         } else if (value.isObject()) { | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| 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 { animate, Group, Panel, gravity, Color, AnimationSet, vlayout, scroller, layoutConfig, IVLayout, modal, IText, network, View, stack, IHLayout, hlayout, IView, text, TranslationAnimation, ScaleAnimation, RotationAnimation, FillMode } from "doric"; | ||||
| import { title, colors, box } from "./utils"; | ||||
|  | ||||
| function thisLabel(str: string) { | ||||
| @@ -17,10 +17,13 @@ function thisLabel(str: string) { | ||||
| class AnimatorDemo extends Panel { | ||||
|     build(rootView: Group): void { | ||||
|         const view = box(2) | ||||
|         view.onClick = () => { | ||||
|             modal(context).toast('Clicked') | ||||
|         } | ||||
|         const view2 = box(3) | ||||
|         let idx = 0 | ||||
|         vlayout([ | ||||
|             title("Animator zDemo"), | ||||
|             title("Animator Demo"), | ||||
|             vlayout( | ||||
|                 [ | ||||
|                     hlayout([ | ||||
| @@ -167,27 +170,26 @@ class AnimatorDemo extends Panel { | ||||
|                         thisLabel('animationSet').apply({ | ||||
|                             onClick: () => { | ||||
|                                 const animationSet = new AnimationSet | ||||
|  | ||||
|                                 animationSet.fillMode = FillMode.Forward | ||||
|                                 animationSet.delay = 2000 | ||||
|                                 const translate = new TranslationAnimation | ||||
|                                 translate.fromTranslationX = 10 | ||||
|                                 translate.fromTranslationX = 100 | ||||
|                                 translate.toTranslationX = 200 | ||||
|                                 translate.fromTranslationY = 10 | ||||
|                                 translate.toTranslationY = 200 | ||||
|                                 translate.duration = 3000 | ||||
|                                 translate.duration = 2000 | ||||
|                                 translate.delay = 1000 | ||||
|                                 const scale = new ScaleAnimation | ||||
|                                 scale.fromScaleX = 1 | ||||
|                                 scale.toScaleX = 5 | ||||
|                                 scale.fromScaleY = 1 | ||||
|                                 scale.toScaleY = 5 | ||||
|                                 scale.duration = 3000 | ||||
|  | ||||
|                                 //scale.delay = 1000 | ||||
|                                 scale.duration = 2000 | ||||
|                                 const rotation = new RotationAnimation | ||||
|                                 rotation.fromRotation = 0 | ||||
|                                 rotation.toRotation = 6 | ||||
|                                 rotation.delay = 1000 | ||||
|                                 rotation.toRotation = 6.2 | ||||
|                                 rotation.duration = 3000 | ||||
|  | ||||
|                                 animationSet.addAnimation(translate) | ||||
|                                 animationSet.addAnimation(scale) | ||||
|                                 animationSet.addAnimation(rotation) | ||||
|   | ||||
| @@ -323,14 +323,15 @@ - (void)blendLayoutConfig:(NSDictionary *)params { | ||||
| 
 | ||||
| - (void)doAnimation:(id)params withPromise:(DoricPromise *)promise { | ||||
|     CAAnimation *animation = [self parseAnimation:params]; | ||||
|     animation.removedOnCompletion = NO; | ||||
|     animation.fillMode = kCAFillModeForwards; | ||||
|     AnimationCallback *animationCallback = [[AnimationCallback new] also:^(AnimationCallback *it) { | ||||
|         it.endBlock = ^{ | ||||
|             [promise resolve:nil]; | ||||
|         }; | ||||
|     }]; | ||||
|     animation.delegate = animationCallback; | ||||
|     if (params[@"delay"]) { | ||||
|         animation.beginTime = CACurrentMediaTime() + [params[@"delay"] floatValue] / 1000; | ||||
|     } | ||||
|     [self.view.layer addAnimation:animation forKey:nil]; | ||||
| } | ||||
| 
 | ||||
| @@ -343,15 +344,20 @@ - (CFTimeInterval)computeDurationOfAnimations:(NSArray<CAAnimation *> *)animatio | ||||
| } | ||||
| 
 | ||||
| - (CAAnimation *)parseAnimation:(id)params { | ||||
|     if ([params isKindOfClass:[NSArray class]]) { | ||||
|         NSArray *anims = params; | ||||
|     if (params[@"animations"]) { | ||||
|         NSArray *anims = params[@"animations"]; | ||||
|         CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; | ||||
|         NSMutableArray *animations = [NSMutableArray new]; | ||||
|         [anims forEach:^(id obj) { | ||||
|             [animations addObject:[self parseAnimation:obj]]; | ||||
|         }]; | ||||
|         animationGroup.duration = [self computeDurationOfAnimations:animations]; | ||||
|         animationGroup.fillMode = [self translateToFillMode:params[@"fillMode"]]; | ||||
|         animationGroup.removedOnCompletion = [animationGroup.fillMode isEqualToString:kCAFillModeRemoved]; | ||||
|         animationGroup.animations = animations; | ||||
|         if (params[@"delay"]) { | ||||
|             animationGroup.beginTime = [params[@"delay"] floatValue] / 1000; | ||||
|         } | ||||
|         return animationGroup; | ||||
|     } else if ([params isKindOfClass:[NSDictionary class]]) { | ||||
|         NSArray<NSDictionary *> *changeables = params[@"changeables"]; | ||||
| @@ -405,8 +411,8 @@ - (void)setAnimation:(CAAnimation *)animation params:(NSDictionary *)params { | ||||
|         animation.beginTime = [params[@"delay"] floatValue] / 1000; | ||||
|     } | ||||
|     animation.duration = [params[@"duration"] floatValue] / 1000; | ||||
|     animation.removedOnCompletion = NO; | ||||
|     animation.fillMode = kCAFillModeForwards; | ||||
|     animation.fillMode = [self translateToFillMode:params[@"fillMode"]]; | ||||
|     animation.removedOnCompletion = [animation.fillMode isEqualToString:kCAFillModeRemoved]; | ||||
| } | ||||
| 
 | ||||
| - (CAAnimation *)parseChangeable:(NSDictionary *)params { | ||||
| @@ -432,4 +438,17 @@ - (CAAnimation *)parseChangeable:(NSDictionary *)params { | ||||
|     return animation; | ||||
| } | ||||
| 
 | ||||
| - (CAMediaTimingFillMode)translateToFillMode:(NSNumber *)fillMode { | ||||
|     switch ([fillMode integerValue]) { | ||||
|         case 1: | ||||
|             return kCAFillModeForwards; | ||||
|         case 2: | ||||
|             return kCAFillModeBackwards; | ||||
|         case 3: | ||||
|             return kCAFillModeBoth; | ||||
|         default: | ||||
|             return kCAFillModeRemoved; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @end | ||||
|   | ||||
| @@ -18,13 +18,16 @@ import { Modeling, Model } from "../util/types" | ||||
|  | ||||
|  | ||||
| export type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY" | ||||
|  | ||||
| export enum RepeatMode { | ||||
|     RESTART = 1, | ||||
|     REVERSE = 2, | ||||
| } | ||||
|  | ||||
| export interface IAnimation extends Modeling { | ||||
|     duration: number | ||||
|     delay?: number | ||||
|     fillMode: FillMode | ||||
| } | ||||
|  | ||||
| export interface Changeable { | ||||
| @@ -34,6 +37,24 @@ export interface Changeable { | ||||
|     repeatCount?: number | ||||
|     repeatMode?: RepeatMode | ||||
| } | ||||
| export enum FillMode { | ||||
|     /** | ||||
|      * The receiver is removed from the presentation when the animation is completed. | ||||
|      */ | ||||
|     Removed = 0, | ||||
|     /** | ||||
|      * The receiver remains visible in its final state when the animation is completed. | ||||
|      */ | ||||
|     Forward = 1, | ||||
|     /** | ||||
|      * The receiver clamps values before zero to zero when the animation is completed. | ||||
|      */ | ||||
|     Backward = 2, | ||||
|     /** | ||||
|      * The receiver clamps values at both ends of the object’s time space | ||||
|      */ | ||||
|     Both = 3, | ||||
| } | ||||
|  | ||||
| abstract class Animation implements IAnimation { | ||||
|     changeables: Map<AnimatedKey, Changeable> = new Map | ||||
| @@ -41,7 +62,7 @@ abstract class Animation implements IAnimation { | ||||
|     repeatCount?: number | ||||
|     repeatMode?: RepeatMode | ||||
|     delay?: number | ||||
|  | ||||
|     fillMode = FillMode.Forward | ||||
|     toModel() { | ||||
|         const changeables = [] | ||||
|         for (let e of this.changeables.values()) { | ||||
| @@ -58,6 +79,7 @@ abstract class Animation implements IAnimation { | ||||
|             changeables, | ||||
|             repeatCount: this.repeatCount, | ||||
|             repeatMode: this.repeatMode, | ||||
|             fillMode: this.fillMode, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -193,7 +215,7 @@ export class AnimationSet implements IAnimation { | ||||
|     private animations: IAnimation[] = [] | ||||
|     _duration = 0 | ||||
|     delay?: number | ||||
|  | ||||
|     fillMode = FillMode.Removed | ||||
|     addAnimation(anim: IAnimation) { | ||||
|         this.animations.push(anim) | ||||
|     } | ||||
| @@ -208,8 +230,12 @@ export class AnimationSet implements IAnimation { | ||||
|     } | ||||
|  | ||||
|     toModel() { | ||||
|         return this.animations.map(e => { | ||||
|         return { | ||||
|             animations: this.animations.map(e => { | ||||
|                 return e.toModel() | ||||
|         }) as Model | ||||
|             }) as Model, | ||||
|             fillMode: this.fillMode, | ||||
|             delay: this.delay, | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user