Merge branch 'feature/animation' into 'master'
Feature/animation See merge request !40
This commit is contained in:
commit
f22b4a1cde
@ -25,10 +25,17 @@ import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
||||
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
import pub.doric.DoricRegistry;
|
||||
@ -695,6 +702,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
|
||||
JSValue repeatMode = value.asObject().getProperty("repeatMode");
|
||||
JSValue fillMode = value.asObject().getProperty("fillMode");
|
||||
JSValue timingFunction = value.asObject().getProperty("timingFunction");
|
||||
for (int j = 0; j < changeables.size(); j++) {
|
||||
ObjectAnimator animator = parseChangeable(changeables.get(j).asObject(), fillMode);
|
||||
if (repeatCount.isNumber()) {
|
||||
@ -703,6 +711,9 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
if (repeatMode.isNumber()) {
|
||||
animator.setRepeatMode(repeatMode.asNumber().toInt());
|
||||
}
|
||||
if (timingFunction.isNumber()) {
|
||||
animator.setInterpolator(getTimingInterpolator(timingFunction.asNumber().toInt()));
|
||||
}
|
||||
animatorSet.play(animator);
|
||||
}
|
||||
long duration = value.asObject().getProperty("duration").asNumber().toLong();
|
||||
@ -711,13 +722,27 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
if (delayJS.isNumber()) {
|
||||
animatorSet.setStartDelay(delayJS.asNumber().toLong());
|
||||
}
|
||||
|
||||
return animatorSet;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Interpolator getTimingInterpolator(int timingFunction) {
|
||||
switch (timingFunction) {
|
||||
case 1:
|
||||
return new LinearInterpolator();
|
||||
case 2:
|
||||
return new AccelerateInterpolator();
|
||||
case 3:
|
||||
return new DecelerateInterpolator();
|
||||
case 4:
|
||||
return new FastOutSlowInInterpolator();
|
||||
default:
|
||||
return new AccelerateDecelerateInterpolator();
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectAnimator parseChangeable(JSObject jsObject, JSValue fillMode) {
|
||||
String key = jsObject.getProperty("key").asString().value();
|
||||
float startVal = jsObject.getProperty("fromValue").asNumber().toFloat();
|
||||
|
@ -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, FillMode } 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, TimingFunction } from "doric";
|
||||
import { title, colors, box } from "./utils";
|
||||
|
||||
function thisLabel(str: string) {
|
||||
@ -122,6 +122,58 @@ class AnimationDemo extends Panel {
|
||||
}
|
||||
}),
|
||||
]).apply({ space: 10 } as IHLayout),
|
||||
hlayout([
|
||||
thisLabel('Default').apply({
|
||||
onClick: () => {
|
||||
const translation = new TranslationAnimation
|
||||
translation.duration = 3000
|
||||
translation.fromTranslationX = 0
|
||||
translation.toTranslationX = 300
|
||||
translation.timingFunction = TimingFunction.Default
|
||||
view.doAnimation(context, translation)
|
||||
}
|
||||
}),
|
||||
thisLabel('Linear').apply({
|
||||
onClick: () => {
|
||||
const translation = new TranslationAnimation
|
||||
translation.duration = 3000
|
||||
translation.fromTranslationX = 0
|
||||
translation.toTranslationX = 300
|
||||
translation.timingFunction = TimingFunction.Linear
|
||||
view.doAnimation(context, translation)
|
||||
}
|
||||
}),
|
||||
thisLabel('EaseIn').apply({
|
||||
onClick: () => {
|
||||
const translation = new TranslationAnimation
|
||||
translation.duration = 3000
|
||||
translation.fromTranslationX = 0
|
||||
translation.toTranslationX = 300
|
||||
translation.timingFunction = TimingFunction.EaseIn
|
||||
view.doAnimation(context, translation)
|
||||
}
|
||||
}),
|
||||
thisLabel('EaseOut').apply({
|
||||
onClick: () => {
|
||||
const translation = new TranslationAnimation
|
||||
translation.duration = 3000
|
||||
translation.fromTranslationX = 0
|
||||
translation.toTranslationX = 300
|
||||
translation.timingFunction = TimingFunction.EaseOut
|
||||
view.doAnimation(context, translation)
|
||||
}
|
||||
}),
|
||||
thisLabel('EaseInEaseOut').apply({
|
||||
onClick: () => {
|
||||
const translation = new TranslationAnimation
|
||||
translation.duration = 3000
|
||||
translation.fromTranslationX = 0
|
||||
translation.toTranslationX = 300
|
||||
translation.timingFunction = TimingFunction.EaseInEaseOut
|
||||
view.doAnimation(context, translation)
|
||||
}
|
||||
}),
|
||||
]).apply({ space: 10 } as IHLayout),
|
||||
]
|
||||
).apply({ space: 10 } as IVLayout),
|
||||
stack([
|
||||
|
@ -32,7 +32,7 @@ class RefreshableDemo extends Panel {
|
||||
log('stopAnimation')
|
||||
},
|
||||
setProgressRotation: (rotation: number) => {
|
||||
refreshImage.setRotation(context, rotation)
|
||||
refreshImage.rotation = rotation
|
||||
},
|
||||
}),
|
||||
content: (vlayout([
|
||||
|
@ -66,7 +66,7 @@ export function rotatedArrow(context: BridgeContext) {
|
||||
log('stopAnimation')
|
||||
},
|
||||
setProgressRotation: (rotation: number) => {
|
||||
refreshImage.setRotation(context, rotation)
|
||||
refreshImage.rotation = rotation
|
||||
},
|
||||
})
|
||||
}
|
@ -454,6 +454,9 @@ - (CAAnimation *)parseAnimation:(id)params {
|
||||
}];
|
||||
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 {
|
||||
@ -462,6 +465,9 @@ - (CAAnimation *)parseAnimation:(id)params {
|
||||
|
||||
[changeables forEach:^(NSDictionary *obj) {
|
||||
CABasicAnimation *animation = [self parseChangeable:obj fillMode:params[@"fillMode"]];
|
||||
if (params[@"timingFunction"]) {
|
||||
animation.timingFunction = [self translateToTimingFunction:params[@"timingFunction"]];
|
||||
}
|
||||
[animations addObject:animation];
|
||||
}];
|
||||
animationGroup.animations = animations;
|
||||
@ -603,16 +609,18 @@ - (CABasicAnimation *)parseChangeable:(NSDictionary *)params fillMode:(NSNumber
|
||||
return animation;
|
||||
}
|
||||
|
||||
- (CAMediaTimingFillMode)translateToFillMode:(NSNumber *)fillMode {
|
||||
switch ([fillMode integerValue]) {
|
||||
- (CAMediaTimingFunction *)translateToTimingFunction:(NSNumber *)timingFunction {
|
||||
switch (timingFunction.integerValue) {
|
||||
case 1:
|
||||
return kCAFillModeForwards;
|
||||
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
|
||||
case 2:
|
||||
return kCAFillModeBackwards;
|
||||
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
|
||||
case 3:
|
||||
return kCAFillModeBoth;
|
||||
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
|
||||
case 4:
|
||||
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
|
||||
default:
|
||||
return kCAFillModeRemoved;
|
||||
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,29 @@ export enum FillMode {
|
||||
Both = 0x3,
|
||||
}
|
||||
|
||||
export enum TimingFunction {
|
||||
/**
|
||||
* The system default timing function. Use this function to ensure that the timing of your animations matches that of most system animations.
|
||||
*/
|
||||
Default = 0,
|
||||
/**
|
||||
* Linear pacing, which causes an animation to occur evenly over its duration.
|
||||
*/
|
||||
Linear,
|
||||
/**
|
||||
* Ease-in pacing, which causes an animation to begin slowly and then speed up as it progresses.
|
||||
*/
|
||||
EaseIn,
|
||||
/**
|
||||
* Ease-out pacing, which causes an animation to begin quickly and then slow as it progresses.
|
||||
*/
|
||||
EaseOut,
|
||||
/**
|
||||
* Ease-in-ease-out pacing, which causes an animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing.
|
||||
*/
|
||||
EaseInEaseOut,
|
||||
}
|
||||
|
||||
abstract class Animation implements IAnimation {
|
||||
changeables: Map<AnimatedKey, Changeable> = new Map
|
||||
duration = 0
|
||||
@ -62,6 +85,7 @@ abstract class Animation implements IAnimation {
|
||||
repeatMode?: RepeatMode
|
||||
delay?: number
|
||||
fillMode = FillMode.Forward
|
||||
timingFunction?: TimingFunction
|
||||
toModel() {
|
||||
const changeables = []
|
||||
for (let e of this.changeables.values()) {
|
||||
@ -79,6 +103,7 @@ abstract class Animation implements IAnimation {
|
||||
repeatCount: this.repeatCount,
|
||||
repeatMode: this.repeatMode,
|
||||
fillMode: this.fillMode,
|
||||
timingFunction: this.timingFunction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,21 +297,6 @@ export abstract class View implements Modeling, IView {
|
||||
return this.nativeChannel(context, 'getHeight')() as Promise<number>
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rotation [0..1]
|
||||
*/
|
||||
setRotation(context: BridgeContext, rotation: number) {
|
||||
return this.nativeChannel(context, 'setRotation')(rotation)
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return rotation [0..1]
|
||||
*/
|
||||
getRotation(context: BridgeContext) {
|
||||
return this.nativeChannel(context, 'getRotation')() as Promise<number>
|
||||
}
|
||||
|
||||
/**++++++++++transform++++++++++*/
|
||||
@Property
|
||||
translationX?: number
|
||||
|
Reference in New Issue
Block a user