Merge branch 'feature/animation' into 'master'

Feature/animation



See merge request !37
This commit is contained in:
pengfeizhou 2019-11-29 19:37:29 +08:00
commit ca27e8a26e
4 changed files with 325 additions and 41 deletions

View File

@ -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();
}
} }

View File

@ -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([

View File

@ -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) {

View File

@ -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 {