Add rotationX and rotationY

This commit is contained in:
pengfei.zhou 2020-06-02 20:43:27 +08:00 committed by osborn
parent b81c1d824b
commit c14ec1954e
13 changed files with 230 additions and 23 deletions

View File

@ -23,6 +23,7 @@ import android.animation.ObjectAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.LinearGradient; import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Shader; import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.ShapeDrawable;
@ -32,9 +33,11 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator; import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator; import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -468,6 +471,34 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
setRotation(prop.asNumber().toFloat()); setRotation(prop.asNumber().toFloat());
} }
break; break;
case "rotationX":
if (!prop.isNumber()) {
return;
}
if (isAnimating()) {
addAnimator(ObjectAnimator.ofFloat(
this,
name,
getRotationX(),
prop.asNumber().toFloat()));
} else {
setRotationX(prop.asNumber().toFloat());
}
break;
case "rotationY":
if (!prop.isNumber()) {
return;
}
if (isAnimating()) {
addAnimator(ObjectAnimator.ofFloat(
this,
name,
getRotationY(),
prop.asNumber().toFloat()));
} else {
setRotationY(prop.asNumber().toFloat());
}
break;
case "padding": case "padding":
if (prop.isObject()) { if (prop.isObject()) {
setPadding(prop.asObject()); setPadding(prop.asObject());
@ -797,6 +828,26 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
return getNodeView().getRotation() / 180; 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 @DoricMethod
public void setPivotX(float v) { public void setPivotX(float v) {
getNodeView().setPivotX(v * getNodeView().getWidth()); getNodeView().setPivotX(v * getNodeView().getWidth());
@ -1004,4 +1055,18 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
.put("y", DoricUtils.px2dp(position[1])) .put("y", DoricUtils.px2dp(position[1]))
.toJSONObject(); .toJSONObject();
} }
private static class MyAnimation extends Animation {
private Matrix matrix;
public MyAnimation(Matrix matrix) {
this.matrix = matrix;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
t.getMatrix().set(matrix);
}
}
} }

View File

@ -1,4 +1,4 @@
import { animate, Group, Panel, gravity, Color, vlayout, layoutConfig, modal, stack, hlayout, text, } from "doric"; import { animate, Group, Panel, gravity, Color, vlayout, layoutConfig, modal, stack, hlayout, text, image, } from "doric";
import { title, colors, box } from "./utils"; import { title, colors, box } from "./utils";
function thisLabel(str: string) { function thisLabel(str: string) {
@ -16,7 +16,9 @@ function thisLabel(str: string) {
@Entry @Entry
class AnimatorDemo extends Panel { class AnimatorDemo extends Panel {
build(rootView: Group): void { build(rootView: Group): void {
const view = box(2) const view = image({
imageUrl: "https://pic3.zhimg.com/v2-5847d0813bd0deba333fcbe52435e83e_b.jpg"
})
view.onClick = () => { view.onClick = () => {
modal(context).toast('Clicked') modal(context).toast('Clicked')
} }
@ -42,6 +44,8 @@ class AnimatorDemo extends Panel {
view.translationX = 0 view.translationX = 0
view.translationY = 0 view.translationY = 0
view.rotation = 0 view.rotation = 0
view.rotationX = 0
view.rotationY = 0
}, },
duration: 1500, duration: 1500,
}).then(() => { }).then(() => {
@ -119,9 +123,37 @@ class AnimatorDemo extends Panel {
animate(context)({ animate(context)({
animations: () => { animations: () => {
if (view.rotation) { if (view.rotation) {
view.rotation += 0.5 view.rotation += 0.25
} else { } else {
view.rotation = 0.5 view.rotation = 0.25
}
},
duration: 1000,
});
}
}),
thisLabel('RotationX').apply({
onClick: () => {
animate(context)({
animations: () => {
if (view.rotationX) {
view.rotationX += 0.25
} else {
view.rotationX = 0.25
}
},
duration: 1000,
});
}
}),
thisLabel('RotationY').apply({
onClick: () => {
animate(context)({
animations: () => {
if (view.rotationY) {
view.rotationY += 0.25
} else {
view.rotationY = 0.25
} }
}, },
duration: 1000, duration: 1000,

View File

@ -102,6 +102,8 @@ @interface DoricViewNode ()
@property(nonatomic, copy) NSNumber *scaleX; @property(nonatomic, copy) NSNumber *scaleX;
@property(nonatomic, copy) NSNumber *scaleY; @property(nonatomic, copy) NSNumber *scaleY;
@property(nonatomic, copy) NSNumber *rotation; @property(nonatomic, copy) NSNumber *rotation;
@property(nonatomic, copy) NSNumber *rotationX;
@property(nonatomic, copy) NSNumber *rotationY;
@property(nonatomic, copy) NSNumber *pivotX; @property(nonatomic, copy) NSNumber *pivotX;
@property(nonatomic, copy) NSNumber *pivotY; @property(nonatomic, copy) NSNumber *pivotY;
@property(nonatomic, strong) NSDictionary *gradientProps; @property(nonatomic, strong) NSDictionary *gradientProps;
@ -158,8 +160,24 @@ - (void)transformProperties {
} }
self.view.layer.anchorPoint = CGPointMake(self.pivotX.floatValue self.view.layer.anchorPoint = CGPointMake(self.pivotX.floatValue
?: 0.5f, self.pivotY.floatValue ?: 0.5f); ?: 0.5f, self.pivotY.floatValue ?: 0.5f);
if (!CGAffineTransformEqualToTransform(transform, self.view.transform)) {
self.view.transform = transform; if (self.rotationX || self.rotationY) {
CATransform3D transform3D = CATransform3DMakeAffineTransform(transform);
transform3D.m34 = -1.0 / 500;
if (self.rotationX) {
transform3D = CATransform3DRotate(transform3D, (self.rotationX.floatValue ?: 0) * M_PI, 1, 0, 0);
}
if (self.rotationY) {
transform3D = CATransform3DRotate(transform3D, (self.rotationY.floatValue ?: 0) * M_PI, 0, 1, 0);
}
if (!CATransform3DEqualToTransform(transform3D, self.view.layer.transform)) {
self.view.layer.transform = transform3D;
}
} else {
if (!CGAffineTransformEqualToTransform(transform, self.view.transform)) {
self.view.transform = transform;
}
} }
} }
@ -252,6 +270,10 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
self.pivotY = prop; self.pivotY = prop;
} else if ([name isEqualToString:@"rotation"]) { } else if ([name isEqualToString:@"rotation"]) {
self.rotation = prop; self.rotation = prop;
} else if ([name isEqualToString:@"rotationX"]) {
self.rotationX = prop;
} else if ([name isEqualToString:@"rotationY"]) {
self.rotationY = prop;
} else if ([name isEqualToString:@"padding"]) { } else if ([name isEqualToString:@"padding"]) {
view.doricLayout.paddingLeft = 0; view.doricLayout.paddingLeft = 0;
view.doricLayout.paddingRight = 0; view.doricLayout.paddingRight = 0;
@ -342,28 +364,28 @@ - (void)requestLayout {
return; return;
} }
self.gradientSize = self.view.frame.size; self.gradientSize = self.view.frame.size;
NSMutableArray *colors = [[NSMutableArray alloc] init]; NSMutableArray *colors = [[NSMutableArray alloc] init];
NSMutableArray *arrayLocations = nil; NSMutableArray *arrayLocations = nil;
if ([dict objectForKey:@"colors"] != nil) { if (dict[@"colors"] != nil) {
NSMutableArray *arrayColors = [dict mutableArrayValueForKey:@"colors"]; NSMutableArray *arrayColors = [dict mutableArrayValueForKey:@"colors"];
[arrayColors forEach:^(id obj) { [arrayColors forEach:^(id obj) {
[colors addObject:(__bridge id) DoricColor(obj).CGColor]; [colors addObject:(__bridge id) DoricColor(obj).CGColor];
}]; }];
if ([dict objectForKey:@"locations"] != nil) { if (dict[@"locations"] != nil) {
arrayLocations = [dict mutableArrayValueForKey:@"locations"]; arrayLocations = [dict mutableArrayValueForKey:@"locations"];
} }
} else { } else {
if ([dict objectForKey:@"start"] != nil && [dict objectForKey:@"end"] != nil) { if (dict[@"start"] != nil && dict[@"end"] != nil) {
UIColor *start = DoricColor(dict[@"start"]); UIColor *start = DoricColor(dict[@"start"]);
UIColor *end = DoricColor(dict[@"end"]); UIColor *end = DoricColor(dict[@"end"]);
[colors addObject:(__bridge id) start.CGColor]; [colors addObject:(__bridge id) start.CGColor];
[colors addObject:(__bridge id) end.CGColor]; [colors addObject:(__bridge id) end.CGColor];
} }
} }
int orientation = [dict[@"orientation"] intValue]; int orientation = [dict[@"orientation"] intValue];
CGPoint startPoint; CGPoint startPoint;
CGPoint endPoint; CGPoint endPoint;
@ -392,7 +414,7 @@ - (void)requestLayout {
startPoint = CGPointMake(0, 0); startPoint = CGPointMake(0, 0);
endPoint = CGPointMake(0, 1); endPoint = CGPointMake(0, 1);
} }
UIImage *gradientImage; UIImage *gradientImage;
if (arrayLocations != nil) { if (arrayLocations != nil) {
CGFloat locations[arrayLocations.count]; CGFloat locations[arrayLocations.count];
@ -400,16 +422,16 @@ - (void)requestLayout {
locations[i] = [arrayLocations[i] floatValue]; locations[i] = [arrayLocations[i] floatValue];
} }
gradientImage = [self gradientImageFromColors:colors gradientImage = [self gradientImageFromColors:colors
locations:locations locations:locations
startPoint:startPoint startPoint:startPoint
endPoint:endPoint endPoint:endPoint
imgSize:self.gradientSize]; imgSize:self.gradientSize];
} else { } else {
gradientImage = [self gradientImageFromColors:colors gradientImage = [self gradientImageFromColors:colors
locations:NULL locations:NULL
startPoint:startPoint startPoint:startPoint
endPoint:endPoint endPoint:endPoint
imgSize:self.gradientSize]; imgSize:self.gradientSize];
} }
self.view.backgroundColor = [UIColor colorWithPatternImage:gradientImage]; self.view.backgroundColor = [UIColor colorWithPatternImage:gradientImage];
}]; }];

View File

@ -465,6 +465,14 @@ var View = /** @class */ (function () {
Property, Property,
__metadata("design:type", Number) __metadata("design:type", Number)
], View.prototype, "rotation", void 0); ], View.prototype, "rotation", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationX", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationY", void 0);
__decorate([ __decorate([
Property, Property,
__metadata("design:type", Object) __metadata("design:type", Object)

View File

@ -382,6 +382,14 @@ let View = /** @class */ (() => {
Property, Property,
__metadata("design:type", Number) __metadata("design:type", Number)
], View.prototype, "rotation", void 0); ], View.prototype, "rotation", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationX", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationY", void 0);
__decorate([ __decorate([
Property, Property,
__metadata("design:type", Object) __metadata("design:type", Object)

View File

@ -1841,6 +1841,14 @@ let View = /** @class */ (() => {
Property, Property,
__metadata("design:type", Number) __metadata("design:type", Number)
], View.prototype, "rotation", void 0); ], View.prototype, "rotation", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationX", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationY", void 0);
__decorate([ __decorate([
Property, Property,
__metadata("design:type", Object) __metadata("design:type", Object)

11
doric-js/index.d.ts vendored
View File

@ -220,8 +220,19 @@ declare module 'doric/lib/src/ui/view' {
pivotY?: number; pivotY?: number;
/** /**
* rotation*PI * rotation*PI
* In Z
*/ */
rotation?: number; rotation?: number;
/**
* rotation*PI
* In X
*/
rotationX?: number;
/**
* rotation*PI
* In Y
*/
rotationY?: number;
/** /**
* Only affected when its superview or itself is FlexLayout. * Only affected when its superview or itself is FlexLayout.
*/ */

View File

@ -103,8 +103,19 @@ export declare abstract class View implements Modeling {
pivotY?: number; pivotY?: number;
/** /**
* rotation*PI * rotation*PI
* In Z
*/ */
rotation?: number; rotation?: number;
/**
* rotation*PI
* In X
*/
rotationX?: number;
/**
* rotation*PI
* In Y
*/
rotationY?: number;
/**----------transform----------*/ /**----------transform----------*/
/** /**
* Only affected when its superview or itself is FlexLayout. * Only affected when its superview or itself is FlexLayout.

View File

@ -267,6 +267,14 @@ let View = /** @class */ (() => {
Property, Property,
__metadata("design:type", Number) __metadata("design:type", Number)
], View.prototype, "rotation", void 0); ], View.prototype, "rotation", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationX", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationY", void 0);
__decorate([ __decorate([
Property, Property,
__metadata("design:type", Object) __metadata("design:type", Object)

View File

@ -297,6 +297,19 @@ export abstract class View implements Modeling {
@Property @Property
rotation?: number rotation?: number
/**
* rotation*PI
* In X
*/
@Property
rotationX?: number
/**
* rotation*PI
* In Y
*/
@Property
rotationY?: number
/**----------transform----------*/ /**----------transform----------*/
@Property @Property

View File

@ -295,9 +295,22 @@ export abstract class View implements Modeling {
pivotY?: number pivotY?: number
/** /**
* rotation*PI * rotation*PI
* In Z
*/ */
@Property @Property
rotation?: number rotation?: number
/**
* rotation*PI
* In X
*/
@Property
rotationX?: number
/**
* rotation*PI
* In Y
*/
@Property
rotationY?: number
/**----------transform----------*/ /**----------transform----------*/
/** /**
* Only affected when its superview or itself is FlexLayout. * Only affected when its superview or itself is FlexLayout.

View File

@ -1899,6 +1899,14 @@ let View = /** @class */ (() => {
Property, Property,
__metadata("design:type", Number) __metadata("design:type", Number)
], View.prototype, "rotation", void 0); ], View.prototype, "rotation", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationX", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], View.prototype, "rotationY", void 0);
__decorate([ __decorate([
Property, Property,
__metadata("design:type", Object) __metadata("design:type", Object)

File diff suppressed because one or more lines are too long