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.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.ShapeDrawable;
@ -32,9 +33,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@ -468,6 +471,34 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
setRotation(prop.asNumber().toFloat());
}
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":
if (prop.isObject()) {
setPadding(prop.asObject());
@ -797,6 +828,26 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
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());
@ -1004,4 +1055,18 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
.put("y", DoricUtils.px2dp(position[1]))
.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";
function thisLabel(str: string) {
@ -16,7 +16,9 @@ function thisLabel(str: string) {
@Entry
class AnimatorDemo extends Panel {
build(rootView: Group): void {
const view = box(2)
const view = image({
imageUrl: "https://pic3.zhimg.com/v2-5847d0813bd0deba333fcbe52435e83e_b.jpg"
})
view.onClick = () => {
modal(context).toast('Clicked')
}
@ -42,6 +44,8 @@ class AnimatorDemo extends Panel {
view.translationX = 0
view.translationY = 0
view.rotation = 0
view.rotationX = 0
view.rotationY = 0
},
duration: 1500,
}).then(() => {
@ -119,9 +123,37 @@ class AnimatorDemo extends Panel {
animate(context)({
animations: () => {
if (view.rotation) {
view.rotation += 0.5
view.rotation += 0.25
} 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,

View File

@ -102,6 +102,8 @@ @interface DoricViewNode ()
@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;
@property(nonatomic, strong) NSDictionary *gradientProps;
@ -158,8 +160,24 @@ - (void)transformProperties {
}
self.view.layer.anchorPoint = CGPointMake(self.pivotX.floatValue
?: 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;
} 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 if ([name isEqualToString:@"padding"]) {
view.doricLayout.paddingLeft = 0;
view.doricLayout.paddingRight = 0;
@ -342,28 +364,28 @@ - (void)requestLayout {
return;
}
self.gradientSize = self.view.frame.size;
NSMutableArray *colors = [[NSMutableArray alloc] init];
NSMutableArray *arrayLocations = nil;
if ([dict objectForKey:@"colors"] != nil) {
if (dict[@"colors"] != nil) {
NSMutableArray *arrayColors = [dict mutableArrayValueForKey:@"colors"];
[arrayColors forEach:^(id obj) {
[colors addObject:(__bridge id) DoricColor(obj).CGColor];
}];
if ([dict objectForKey:@"locations"] != nil) {
if (dict[@"locations"] != nil) {
arrayLocations = [dict mutableArrayValueForKey:@"locations"];
}
} else {
if ([dict objectForKey:@"start"] != nil && [dict objectForKey:@"end"] != nil) {
if (dict[@"start"] != nil && dict[@"end"] != nil) {
UIColor *start = DoricColor(dict[@"start"]);
UIColor *end = DoricColor(dict[@"end"]);
[colors addObject:(__bridge id) start.CGColor];
[colors addObject:(__bridge id) end.CGColor];
}
}
int orientation = [dict[@"orientation"] intValue];
CGPoint startPoint;
CGPoint endPoint;
@ -392,7 +414,7 @@ - (void)requestLayout {
startPoint = CGPointMake(0, 0);
endPoint = CGPointMake(0, 1);
}
UIImage *gradientImage;
if (arrayLocations != nil) {
CGFloat locations[arrayLocations.count];
@ -400,16 +422,16 @@ - (void)requestLayout {
locations[i] = [arrayLocations[i] floatValue];
}
gradientImage = [self gradientImageFromColors:colors
locations:locations
startPoint:startPoint
endPoint:endPoint
imgSize:self.gradientSize];
locations:locations
startPoint:startPoint
endPoint:endPoint
imgSize:self.gradientSize];
} else {
gradientImage = [self gradientImageFromColors:colors
locations:NULL
startPoint:startPoint
endPoint:endPoint
imgSize:self.gradientSize];
locations:NULL
startPoint:startPoint
endPoint:endPoint
imgSize:self.gradientSize];
}
self.view.backgroundColor = [UIColor colorWithPatternImage:gradientImage];
}];

View File

@ -465,6 +465,14 @@ var View = /** @class */ (function () {
Property,
__metadata("design:type", Number)
], 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([
Property,
__metadata("design:type", Object)

View File

@ -382,6 +382,14 @@ let View = /** @class */ (() => {
Property,
__metadata("design:type", Number)
], 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([
Property,
__metadata("design:type", Object)

View File

@ -1841,6 +1841,14 @@ let View = /** @class */ (() => {
Property,
__metadata("design:type", Number)
], 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([
Property,
__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;
/**
* rotation*PI
* In Z
*/
rotation?: number;
/**
* rotation*PI
* In X
*/
rotationX?: number;
/**
* rotation*PI
* In Y
*/
rotationY?: number;
/**
* Only affected when its superview or itself is FlexLayout.
*/

View File

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

View File

@ -267,6 +267,14 @@ let View = /** @class */ (() => {
Property,
__metadata("design:type", Number)
], 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([
Property,
__metadata("design:type", Object)

View File

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

View File

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

View File

@ -1899,6 +1899,14 @@ let View = /** @class */ (() => {
Property,
__metadata("design:type", Number)
], 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([
Property,
__metadata("design:type", Object)

File diff suppressed because one or more lines are too long