feat:iOS support fillmode and delay
This commit is contained in:
parent
b12930605e
commit
9b9d8de262
@ -656,10 +656,15 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Animator parseAnimator(JSValue value) {
|
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();
|
AnimatorSet animatorSet = new AnimatorSet();
|
||||||
for (int i = 0; i < value.asArray().size(); i++) {
|
for (int i = 0; i < animations.asArray().size(); i++) {
|
||||||
animatorSet.play(parseAnimator(value.asArray().get(i)));
|
animatorSet.play(parseAnimator(animations.asArray().get(i)));
|
||||||
}
|
}
|
||||||
return animatorSet;
|
return animatorSet;
|
||||||
} else if (value.isObject()) {
|
} 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";
|
import { title, colors, box } from "./utils";
|
||||||
|
|
||||||
function thisLabel(str: string) {
|
function thisLabel(str: string) {
|
||||||
@ -17,10 +17,13 @@ function thisLabel(str: string) {
|
|||||||
class AnimatorDemo extends Panel {
|
class AnimatorDemo extends Panel {
|
||||||
build(rootView: Group): void {
|
build(rootView: Group): void {
|
||||||
const view = box(2)
|
const view = box(2)
|
||||||
|
view.onClick = () => {
|
||||||
|
modal(context).toast('Clicked')
|
||||||
|
}
|
||||||
const view2 = box(3)
|
const view2 = box(3)
|
||||||
let idx = 0
|
let idx = 0
|
||||||
vlayout([
|
vlayout([
|
||||||
title("Animator zDemo"),
|
title("Animator Demo"),
|
||||||
vlayout(
|
vlayout(
|
||||||
[
|
[
|
||||||
hlayout([
|
hlayout([
|
||||||
@ -167,27 +170,26 @@ class AnimatorDemo extends Panel {
|
|||||||
thisLabel('animationSet').apply({
|
thisLabel('animationSet').apply({
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const animationSet = new AnimationSet
|
const animationSet = new AnimationSet
|
||||||
|
animationSet.fillMode = FillMode.Forward
|
||||||
|
animationSet.delay = 2000
|
||||||
const translate = new TranslationAnimation
|
const translate = new TranslationAnimation
|
||||||
translate.fromTranslationX = 10
|
translate.fromTranslationX = 100
|
||||||
translate.toTranslationX = 200
|
translate.toTranslationX = 200
|
||||||
translate.fromTranslationY = 10
|
translate.fromTranslationY = 10
|
||||||
translate.toTranslationY = 200
|
translate.toTranslationY = 200
|
||||||
translate.duration = 3000
|
translate.duration = 2000
|
||||||
translate.delay = 1000
|
translate.delay = 1000
|
||||||
const scale = new ScaleAnimation
|
const scale = new ScaleAnimation
|
||||||
scale.fromScaleX = 1
|
scale.fromScaleX = 1
|
||||||
scale.toScaleX = 5
|
scale.toScaleX = 5
|
||||||
scale.fromScaleY = 1
|
scale.fromScaleY = 1
|
||||||
scale.toScaleY = 5
|
scale.toScaleY = 5
|
||||||
scale.duration = 3000
|
//scale.delay = 1000
|
||||||
|
scale.duration = 2000
|
||||||
const rotation = new RotationAnimation
|
const rotation = new RotationAnimation
|
||||||
rotation.fromRotation = 0
|
rotation.fromRotation = 0
|
||||||
rotation.toRotation = 6
|
rotation.toRotation = 6.2
|
||||||
rotation.delay = 1000
|
|
||||||
rotation.duration = 3000
|
rotation.duration = 3000
|
||||||
|
|
||||||
animationSet.addAnimation(translate)
|
animationSet.addAnimation(translate)
|
||||||
animationSet.addAnimation(scale)
|
animationSet.addAnimation(scale)
|
||||||
animationSet.addAnimation(rotation)
|
animationSet.addAnimation(rotation)
|
||||||
|
@ -323,14 +323,15 @@ - (void)blendLayoutConfig:(NSDictionary *)params {
|
|||||||
|
|
||||||
- (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
- (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||||
CAAnimation *animation = [self parseAnimation:params];
|
CAAnimation *animation = [self parseAnimation:params];
|
||||||
animation.removedOnCompletion = NO;
|
|
||||||
animation.fillMode = kCAFillModeForwards;
|
|
||||||
AnimationCallback *animationCallback = [[AnimationCallback new] also:^(AnimationCallback *it) {
|
AnimationCallback *animationCallback = [[AnimationCallback new] also:^(AnimationCallback *it) {
|
||||||
it.endBlock = ^{
|
it.endBlock = ^{
|
||||||
[promise resolve:nil];
|
[promise resolve:nil];
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
animation.delegate = animationCallback;
|
animation.delegate = animationCallback;
|
||||||
|
if (params[@"delay"]) {
|
||||||
|
animation.beginTime = CACurrentMediaTime() + [params[@"delay"] floatValue] / 1000;
|
||||||
|
}
|
||||||
[self.view.layer addAnimation:animation forKey:nil];
|
[self.view.layer addAnimation:animation forKey:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,15 +344,20 @@ - (CFTimeInterval)computeDurationOfAnimations:(NSArray<CAAnimation *> *)animatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (CAAnimation *)parseAnimation:(id)params {
|
- (CAAnimation *)parseAnimation:(id)params {
|
||||||
if ([params isKindOfClass:[NSArray class]]) {
|
if (params[@"animations"]) {
|
||||||
NSArray *anims = params;
|
NSArray *anims = params[@"animations"];
|
||||||
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
|
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
|
||||||
NSMutableArray *animations = [NSMutableArray new];
|
NSMutableArray *animations = [NSMutableArray new];
|
||||||
[anims forEach:^(id obj) {
|
[anims forEach:^(id obj) {
|
||||||
[animations addObject:[self parseAnimation:obj]];
|
[animations addObject:[self parseAnimation:obj]];
|
||||||
}];
|
}];
|
||||||
animationGroup.duration = [self computeDurationOfAnimations:animations];
|
animationGroup.duration = [self computeDurationOfAnimations:animations];
|
||||||
|
animationGroup.fillMode = [self translateToFillMode:params[@"fillMode"]];
|
||||||
|
animationGroup.removedOnCompletion = [animationGroup.fillMode isEqualToString:kCAFillModeRemoved];
|
||||||
animationGroup.animations = animations;
|
animationGroup.animations = animations;
|
||||||
|
if (params[@"delay"]) {
|
||||||
|
animationGroup.beginTime = [params[@"delay"] floatValue] / 1000;
|
||||||
|
}
|
||||||
return animationGroup;
|
return animationGroup;
|
||||||
} else if ([params isKindOfClass:[NSDictionary class]]) {
|
} else if ([params isKindOfClass:[NSDictionary class]]) {
|
||||||
NSArray<NSDictionary *> *changeables = params[@"changeables"];
|
NSArray<NSDictionary *> *changeables = params[@"changeables"];
|
||||||
@ -405,8 +411,8 @@ - (void)setAnimation:(CAAnimation *)animation params:(NSDictionary *)params {
|
|||||||
animation.beginTime = [params[@"delay"] floatValue] / 1000;
|
animation.beginTime = [params[@"delay"] floatValue] / 1000;
|
||||||
}
|
}
|
||||||
animation.duration = [params[@"duration"] floatValue] / 1000;
|
animation.duration = [params[@"duration"] floatValue] / 1000;
|
||||||
animation.removedOnCompletion = NO;
|
animation.fillMode = [self translateToFillMode:params[@"fillMode"]];
|
||||||
animation.fillMode = kCAFillModeForwards;
|
animation.removedOnCompletion = [animation.fillMode isEqualToString:kCAFillModeRemoved];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CAAnimation *)parseChangeable:(NSDictionary *)params {
|
- (CAAnimation *)parseChangeable:(NSDictionary *)params {
|
||||||
@ -432,4 +438,17 @@ - (CAAnimation *)parseChangeable:(NSDictionary *)params {
|
|||||||
return animation;
|
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
|
@end
|
||||||
|
@ -18,13 +18,16 @@ 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 = 1,
|
RESTART = 1,
|
||||||
REVERSE = 2,
|
REVERSE = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAnimation extends Modeling {
|
export interface IAnimation extends Modeling {
|
||||||
duration: number
|
duration: number
|
||||||
delay?: number
|
delay?: number
|
||||||
|
fillMode: FillMode
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Changeable {
|
export interface Changeable {
|
||||||
@ -34,6 +37,24 @@ export interface Changeable {
|
|||||||
repeatCount?: number
|
repeatCount?: number
|
||||||
repeatMode?: RepeatMode
|
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 {
|
abstract class Animation implements IAnimation {
|
||||||
changeables: Map<AnimatedKey, Changeable> = new Map
|
changeables: Map<AnimatedKey, Changeable> = new Map
|
||||||
@ -41,7 +62,7 @@ abstract class Animation implements IAnimation {
|
|||||||
repeatCount?: number
|
repeatCount?: number
|
||||||
repeatMode?: RepeatMode
|
repeatMode?: RepeatMode
|
||||||
delay?: number
|
delay?: number
|
||||||
|
fillMode = FillMode.Forward
|
||||||
toModel() {
|
toModel() {
|
||||||
const changeables = []
|
const changeables = []
|
||||||
for (let e of this.changeables.values()) {
|
for (let e of this.changeables.values()) {
|
||||||
@ -58,6 +79,7 @@ abstract class Animation implements IAnimation {
|
|||||||
changeables,
|
changeables,
|
||||||
repeatCount: this.repeatCount,
|
repeatCount: this.repeatCount,
|
||||||
repeatMode: this.repeatMode,
|
repeatMode: this.repeatMode,
|
||||||
|
fillMode: this.fillMode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +215,7 @@ export class AnimationSet implements IAnimation {
|
|||||||
private animations: IAnimation[] = []
|
private animations: IAnimation[] = []
|
||||||
_duration = 0
|
_duration = 0
|
||||||
delay?: number
|
delay?: number
|
||||||
|
fillMode = FillMode.Removed
|
||||||
addAnimation(anim: IAnimation) {
|
addAnimation(anim: IAnimation) {
|
||||||
this.animations.push(anim)
|
this.animations.push(anim)
|
||||||
}
|
}
|
||||||
@ -208,8 +230,12 @@ export class AnimationSet implements IAnimation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toModel() {
|
toModel() {
|
||||||
return this.animations.map(e => {
|
return {
|
||||||
|
animations: this.animations.map(e => {
|
||||||
return e.toModel()
|
return e.toModel()
|
||||||
}) as Model
|
}) as Model,
|
||||||
|
fillMode: this.fillMode,
|
||||||
|
delay: this.delay,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user