Merge branch 'feature/animation' into 'master'
Feature/animation See merge request !37
This commit is contained in:
commit
ca27e8a26e
@ -28,6 +28,7 @@ import android.widget.LinearLayout;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import pub.doric.Doric;
|
||||||
import pub.doric.DoricContext;
|
import pub.doric.DoricContext;
|
||||||
import pub.doric.DoricRegistry;
|
import pub.doric.DoricRegistry;
|
||||||
import pub.doric.async.AsyncResult;
|
import pub.doric.async.AsyncResult;
|
||||||
@ -184,17 +185,6 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
|||||||
setBgColor(prop.asNumber().toInt());
|
setBgColor(prop.asNumber().toInt());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "rotation":
|
|
||||||
if (isAnimating()) {
|
|
||||||
addAnimator(ObjectAnimator.ofFloat(
|
|
||||||
this,
|
|
||||||
name,
|
|
||||||
getRotation(),
|
|
||||||
prop.asNumber().toFloat()));
|
|
||||||
} else {
|
|
||||||
setRotation(prop.asNumber().toFloat());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "onClick":
|
case "onClick":
|
||||||
final String functionId = prop.asString().value();
|
final String functionId = prop.asString().value();
|
||||||
view.setOnClickListener(new View.OnClickListener() {
|
view.setOnClickListener(new View.OnClickListener() {
|
||||||
@ -248,6 +238,103 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "translationX":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getTranslationX(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setTranslationX(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "translationY":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getTranslationY(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setTranslationY(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "scaleX":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getScaleX(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setScaleX(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
case "scaleY":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getScaleY(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setScaleY(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
case "pivotX":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getPivotX(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setPivotX(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "pivotY":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getPivotY(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setPivotY(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "rotation":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getRotation(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setRotation(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "rotationX":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getRotationX(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setRotationX(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "rotationY":
|
||||||
|
if (isAnimating()) {
|
||||||
|
addAnimator(ObjectAnimator.ofFloat(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
getRotationY(),
|
||||||
|
prop.asNumber().toFloat()));
|
||||||
|
} else {
|
||||||
|
setRotationY(prop.asNumber().toFloat());
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -392,16 +479,6 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
|||||||
return DoricUtils.px2dp(getNodeView().getHeight());
|
return DoricUtils.px2dp(getNodeView().getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
@DoricMethod
|
|
||||||
public void setRotation(float rotation) {
|
|
||||||
getNodeView().setRotation(rotation * 180);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DoricMethod
|
|
||||||
public float getRotation() {
|
|
||||||
return getNodeView().getRotation() / 180;
|
|
||||||
}
|
|
||||||
|
|
||||||
@DoricMethod
|
@DoricMethod
|
||||||
protected void setWidth(float width) {
|
protected void setWidth(float width) {
|
||||||
if (mLayoutParams.width >= 0) {
|
if (mLayoutParams.width >= 0) {
|
||||||
@ -473,4 +550,94 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
|||||||
public float getCorners() {
|
public float getCorners() {
|
||||||
return DoricUtils.px2dp((int) requireDoricLayer().getCornerRadius());
|
return DoricUtils.px2dp((int) requireDoricLayer().getCornerRadius());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setTranslationX(float v) {
|
||||||
|
getNodeView().setTranslationX(DoricUtils.dp2px(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getTranslationX() {
|
||||||
|
return DoricUtils.px2dp((int) getNodeView().getTranslationX());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setTranslationY(float v) {
|
||||||
|
getNodeView().setTranslationY(DoricUtils.dp2px(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getTranslationY() {
|
||||||
|
return DoricUtils.px2dp((int) getNodeView().getTranslationY());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setScaleX(float v) {
|
||||||
|
getNodeView().setScaleX(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getScaleX() {
|
||||||
|
return getNodeView().getScaleX();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setScaleY(float v) {
|
||||||
|
getNodeView().setScaleY(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getScaleY() {
|
||||||
|
return getNodeView().getScaleY();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setRotation(float rotation) {
|
||||||
|
getNodeView().setRotation(rotation * 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getRotation() {
|
||||||
|
return getNodeView().getRotation() / 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setRotationX(float rotation) {
|
||||||
|
getNodeView().setRotationX(rotation * 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getRotationX() {
|
||||||
|
return getNodeView().getRotationX() / 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setRotationY(float rotation) {
|
||||||
|
getNodeView().setRotationY(rotation * 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getRotationY() {
|
||||||
|
return getNodeView().getRotationY() / 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setPivotX(float v) {
|
||||||
|
getNodeView().setPivotX(v * getNodeView().getWidth());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getPivotX() {
|
||||||
|
return getNodeView().getPivotX() / getNodeView().getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public void setPivotY(float v) {
|
||||||
|
getNodeView().setPivotY(v * getNodeView().getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoricMethod
|
||||||
|
public float getPivotY() {
|
||||||
|
return getNodeView().getPivotY() / getNodeView().getHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,11 @@ class AnimatorDemo extends Panel {
|
|||||||
view.rotation = 0
|
view.rotation = 0
|
||||||
view.bgColor = colors[2]
|
view.bgColor = colors[2]
|
||||||
view.corners = 0
|
view.corners = 0
|
||||||
|
view.scaleX = 1
|
||||||
|
view.scaleY = 1
|
||||||
|
view.translationX = 0
|
||||||
|
view.translationY = 0
|
||||||
|
view.rotation = 0
|
||||||
},
|
},
|
||||||
duration: 1500,
|
duration: 1500,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
@ -126,6 +131,37 @@ class AnimatorDemo extends Panel {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
]).apply({ space: 10 } as IHLayout),
|
]).apply({ space: 10 } as IHLayout),
|
||||||
|
|
||||||
|
hlayout([
|
||||||
|
thisLabel('scaleX').apply({
|
||||||
|
onClick: () => {
|
||||||
|
animate(this)({
|
||||||
|
animations: () => {
|
||||||
|
if (view.scaleX) {
|
||||||
|
view.scaleX += 0.1
|
||||||
|
} else {
|
||||||
|
view.scaleX = 1.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
duration: 1000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
thisLabel('scaleY').apply({
|
||||||
|
onClick: () => {
|
||||||
|
animate(this)({
|
||||||
|
animations: () => {
|
||||||
|
if (view.scaleY) {
|
||||||
|
view.scaleY += 0.1
|
||||||
|
} else {
|
||||||
|
view.scaleY = 1.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
duration: 1000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
]).apply({ space: 10 } as IHLayout),
|
||||||
]
|
]
|
||||||
).apply({ space: 10 } as IVLayout),
|
).apply({ space: 10 } as IVLayout),
|
||||||
stack([
|
stack([
|
||||||
|
@ -68,6 +68,15 @@ CGPathRef DoricCreateRoundedRectPath(CGRect bounds,
|
|||||||
|
|
||||||
@interface DoricViewNode ()
|
@interface DoricViewNode ()
|
||||||
@property(nonatomic, strong) NSMutableDictionary *callbackIds;
|
@property(nonatomic, strong) NSMutableDictionary *callbackIds;
|
||||||
|
@property(nonatomic, copy) NSNumber *translationX;
|
||||||
|
@property(nonatomic, copy) NSNumber *translationY;
|
||||||
|
@property(nonatomic, copy) NSNumber *scaleX;
|
||||||
|
@property(nonatomic, copy) NSNumber *scaleY;
|
||||||
|
@property(nonatomic, copy) NSNumber *rotation;
|
||||||
|
@property(nonatomic, copy) NSNumber *rotationX;
|
||||||
|
@property(nonatomic, copy) NSNumber *rotationY;
|
||||||
|
@property(nonatomic, copy) NSNumber *pivotX;
|
||||||
|
@property(nonatomic, copy) NSNumber *pivotY;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricViewNode
|
@implementation DoricViewNode
|
||||||
@ -79,7 +88,6 @@ - (instancetype)initWithContext:(DoricContext *)doricContext {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
||||||
if ([self isKindOfClass:[DoricSuperNode class]]) {
|
if ([self isKindOfClass:[DoricSuperNode class]]) {
|
||||||
((DoricSuperNode *) self).reusable = superNode.reusable;
|
((DoricSuperNode *) self).reusable = superNode.reusable;
|
||||||
@ -104,6 +112,27 @@ - (void)blend:(NSDictionary *)props {
|
|||||||
id value = props[key];
|
id value = props[key];
|
||||||
[self blendView:self.view forPropName:key propValue:value];
|
[self blendView:self.view forPropName:key propValue:value];
|
||||||
}
|
}
|
||||||
|
[self transformProperties];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)transformProperties {
|
||||||
|
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||||
|
if (self.translationX || self.translationY) {
|
||||||
|
transform = CGAffineTransformTranslate(transform, [self.translationX floatValue] ?: 0, [self.translationY floatValue] ?: 0);
|
||||||
|
}
|
||||||
|
if (self.scaleX || self.scaleY) {
|
||||||
|
transform = CGAffineTransformScale(transform, [self.scaleX floatValue] ?: 1, [self.scaleY floatValue] ?: 1);
|
||||||
|
}
|
||||||
|
if (self.rotation) {
|
||||||
|
transform = CGAffineTransformRotate(transform, (self.rotation.floatValue ?: 0) * M_PI);
|
||||||
|
}
|
||||||
|
if (!CGAffineTransformEqualToTransform(transform, self.view.transform)) {
|
||||||
|
self.view.transform = transform;
|
||||||
|
}
|
||||||
|
if (self.pivotX || self.pivotY) {
|
||||||
|
self.view.layer.anchorPoint = CGPointMake(self.pivotX.floatValue
|
||||||
|
?: 0.5f, self.pivotY.floatValue ?: 0.5f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop {
|
- (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||||
@ -123,8 +152,6 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
|
|||||||
view.y = [(NSNumber *) prop floatValue];
|
view.y = [(NSNumber *) prop floatValue];
|
||||||
} else if ([name isEqualToString:@"bgColor"]) {
|
} else if ([name isEqualToString:@"bgColor"]) {
|
||||||
view.backgroundColor = DoricColor(prop);
|
view.backgroundColor = DoricColor(prop);
|
||||||
} else if ([name isEqualToString:@"rotation"]) {
|
|
||||||
[self setRotation:prop];
|
|
||||||
} else if ([name isEqualToString:@"layoutConfig"]) {
|
} else if ([name isEqualToString:@"layoutConfig"]) {
|
||||||
if (self.superNode && [prop isKindOfClass:[NSDictionary class]]) {
|
if (self.superNode && [prop isKindOfClass:[NSDictionary class]]) {
|
||||||
[self.superNode blendSubNode:self layoutConfig:prop];
|
[self.superNode blendSubNode:self layoutConfig:prop];
|
||||||
@ -181,6 +208,24 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
|
|||||||
view.clipsToBounds = YES;
|
view.clipsToBounds = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if ([name isEqualToString:@"translationX"]) {
|
||||||
|
self.translationX = prop;
|
||||||
|
} else if ([name isEqualToString:@"translationY"]) {
|
||||||
|
self.translationY = prop;
|
||||||
|
} else if ([name isEqualToString:@"scaleX"]) {
|
||||||
|
self.scaleX = prop;
|
||||||
|
} else if ([name isEqualToString:@"scaleY"]) {
|
||||||
|
self.scaleY = prop;
|
||||||
|
} else if ([name isEqualToString:@"pivotX"]) {
|
||||||
|
self.pivotX = prop;
|
||||||
|
} else if ([name isEqualToString:@"pivotY"]) {
|
||||||
|
self.pivotY = prop;
|
||||||
|
} else if ([name isEqualToString:@"rotation"]) {
|
||||||
|
self.rotation = prop;
|
||||||
|
} else if ([name isEqualToString:@"rotationX"]) {
|
||||||
|
self.rotationX = prop;
|
||||||
|
} else if ([name isEqualToString:@"rotationY"]) {
|
||||||
|
self.rotationY = prop;
|
||||||
} else {
|
} else {
|
||||||
DoricLog(@"Blend View error for View Type :%@, prop is %@", self.class, name);
|
DoricLog(@"Blend View error for View Type :%@, prop is %@", self.class, name);
|
||||||
}
|
}
|
||||||
@ -236,20 +281,6 @@ - (NSNumber *)getHeight {
|
|||||||
return @(self.view.height);
|
return @(self.view.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setRotation:(NSNumber *)rotation {
|
|
||||||
if (rotation.floatValue == 0) {
|
|
||||||
self.view.transform = CGAffineTransformIdentity;
|
|
||||||
} else {
|
|
||||||
self.view.transform = CGAffineTransformMakeRotation(M_PI * rotation.floatValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSNumber *)getRotation {
|
|
||||||
float radius = atan2f((float) self.view.transform.b, (float) self.view.transform.a);
|
|
||||||
float degree = (float) (radius / M_PI);
|
|
||||||
return @(degree);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)blendLayoutConfig:(NSDictionary *)params {
|
- (void)blendLayoutConfig:(NSDictionary *)params {
|
||||||
[params[@"widthSpec"] also:^(NSNumber *it) {
|
[params[@"widthSpec"] also:^(NSNumber *it) {
|
||||||
if (it) {
|
if (it) {
|
||||||
|
@ -42,6 +42,30 @@ export interface IView {
|
|||||||
layoutConfig?: LayoutConfig
|
layoutConfig?: LayoutConfig
|
||||||
onClick?: Function
|
onClick?: Function
|
||||||
identifier?: string
|
identifier?: string
|
||||||
|
|
||||||
|
/**++++++++++transform++++++++++*/
|
||||||
|
translationX?: number
|
||||||
|
|
||||||
|
translationY?: number
|
||||||
|
|
||||||
|
scaleX?: number
|
||||||
|
|
||||||
|
scaleY?: number
|
||||||
|
/**
|
||||||
|
* float [0,..1]
|
||||||
|
*/
|
||||||
|
pivotX?: number
|
||||||
|
/**
|
||||||
|
* float [0,..1]
|
||||||
|
*/
|
||||||
|
pivotY?: number
|
||||||
|
|
||||||
|
rotation?: number
|
||||||
|
|
||||||
|
rotationX?: number
|
||||||
|
|
||||||
|
rotationY?: number
|
||||||
|
/**----------transform----------*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -61,9 +85,6 @@ export abstract class View implements Modeling, IView {
|
|||||||
@Property
|
@Property
|
||||||
bgColor?: Color | GradientColor
|
bgColor?: Color | GradientColor
|
||||||
|
|
||||||
@Property
|
|
||||||
rotation?: number
|
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
corners?: number | { leftTop?: number; rightTop?: number; leftBottom?: number; rightBottom?: number }
|
corners?: number | { leftTop?: number; rightTop?: number; leftBottom?: number; rightBottom?: number }
|
||||||
|
|
||||||
@ -288,6 +309,35 @@ export abstract class View implements Modeling, IView {
|
|||||||
getRotation(context: BridgeContext) {
|
getRotation(context: BridgeContext) {
|
||||||
return this.nativeChannel(context, 'getRotation')() as Promise<number>
|
return this.nativeChannel(context, 'getRotation')() as Promise<number>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**++++++++++transform++++++++++*/
|
||||||
|
@Property
|
||||||
|
translationX?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
translationY?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
scaleX?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
scaleY?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
pivotX?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
pivotY?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
rotation?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
rotationX?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
rotationY?: number
|
||||||
|
/**----------transform----------*/
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class Superview extends View {
|
export abstract class Superview extends View {
|
||||||
|
Reference in New Issue
Block a user