mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat: Add 3D rotation to view - takeover of PR# 5950 (#8136)
* feat: add 3d rotation * chore: fix build errors * chore: fix tslint errors * chore: add @types/chai dev dep * chore: unused import cleanup * chore: update tests for x,y rotation * chore: rebase upstream/master * fix: iOS Affine Transform test verification * feat(css): Added optional css-tree parser (#8076) * feat(css): Added optional css-tree parser * test: css-tree parser compat tests * test: more css-tree compat tests * feat(dialogs): Setting the size of popup dialog thru dialog options (#8041) * Added iOS specific height and width attributes to ShowModalOptions * Set the height and width of the popup dialog to the presenting controller * dialog options ios attributes presentationStyle, height & width are made optional * Updated NativeScript.api.md for public API changes * Update with git properties * Public API * CLA update * fix: use iOS native-helper for 3d-rotate * test: Fix tests using _getTransformMismatchError * fix: view.__hasTransfrom not set updating properly * test: fix css-animations test page Co-authored-by: Alexander Vakrilov <alexander.vakrilov@gmail.com> Co-authored-by: Darin Dimitrov <darin.dimitrov@gmail.com> Co-authored-by: Shailesh Lolam <slolam@live.com> Co-authored-by: Dimitar Topuzov <dtopuzov@gmail.com>
This commit is contained in:
committed by
Alexander Vakrilov
parent
8550c3293d
commit
e8f5ac8522
@@ -697,6 +697,27 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
this.style.rotate = value;
|
||||
}
|
||||
|
||||
get rotateX(): number {
|
||||
return this.style.rotateX;
|
||||
}
|
||||
set rotateX(value: number) {
|
||||
this.style.rotateX = value;
|
||||
}
|
||||
|
||||
get rotateY(): number {
|
||||
return this.style.rotateY;
|
||||
}
|
||||
set rotateY(value: number) {
|
||||
this.style.rotateY = value;
|
||||
}
|
||||
|
||||
get perspective(): number {
|
||||
return this.style.perspective;
|
||||
}
|
||||
set perspective(value: number) {
|
||||
this.style.perspective = value;
|
||||
}
|
||||
|
||||
get translateX(): dip {
|
||||
return this.style.translateX;
|
||||
}
|
||||
|
||||
@@ -10,17 +10,18 @@ import {
|
||||
} from "./view-common";
|
||||
|
||||
import {
|
||||
Length, PercentLength, Visibility, HorizontalAlignment, VerticalAlignment,
|
||||
perspectiveProperty, Length, PercentLength, Visibility, HorizontalAlignment, VerticalAlignment,
|
||||
visibilityProperty, opacityProperty, horizontalAlignmentProperty, verticalAlignmentProperty,
|
||||
minWidthProperty, minHeightProperty, widthProperty, heightProperty,
|
||||
marginLeftProperty, marginTopProperty, marginRightProperty, marginBottomProperty,
|
||||
rotateProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty,
|
||||
rotateProperty, rotateXProperty, rotateYProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty,
|
||||
zIndexProperty, backgroundInternalProperty, androidElevationProperty, androidDynamicElevationOffsetProperty
|
||||
} from "../../styling/style-properties";
|
||||
|
||||
import { Background, ad as androidBackground } from "../../styling/background";
|
||||
import { profile } from "../../../profiling";
|
||||
import { topmost } from "../../frame/frame-stack";
|
||||
import { screen } from "../../../platform";
|
||||
import { AndroidActivityBackPressedEventData, android as androidApp } from "../../../application";
|
||||
import { device } from "../../../platform";
|
||||
import lazy from "../../../utils/lazy";
|
||||
@@ -911,6 +912,20 @@ export class View extends ViewCommon {
|
||||
org.nativescript.widgets.ViewHelper.setRotate(this.nativeViewProtected, float(value));
|
||||
}
|
||||
|
||||
[rotateXProperty.setNative](value: number) {
|
||||
org.nativescript.widgets.ViewHelper.setRotateX(this.nativeViewProtected, float(value));
|
||||
}
|
||||
|
||||
[rotateYProperty.setNative](value: number) {
|
||||
org.nativescript.widgets.ViewHelper.setRotateY(this.nativeViewProtected, float(value));
|
||||
}
|
||||
|
||||
[perspectiveProperty.setNative](value: number) {
|
||||
const scale = screen.mainScreen.scale;
|
||||
const distance = value * scale;
|
||||
org.nativescript.widgets.ViewHelper.setPerspective(this.nativeViewProtected, float(distance));
|
||||
}
|
||||
|
||||
[scaleXProperty.setNative](value: number) {
|
||||
org.nativescript.widgets.ViewHelper.setScaleX(this.nativeViewProtected, float(value));
|
||||
}
|
||||
|
||||
23
nativescript-core/ui/core/view/view.d.ts
vendored
23
nativescript-core/ui/core/view/view.d.ts
vendored
@@ -75,6 +75,11 @@ export interface Point {
|
||||
* Represents the y coordinate of the location.
|
||||
*/
|
||||
y: number;
|
||||
|
||||
/**
|
||||
* Represents the z coordinate of the location.
|
||||
*/
|
||||
z?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,10 +320,26 @@ export abstract class View extends ViewBase {
|
||||
opacity: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the rotate affine transform of the view.
|
||||
* Gets or sets the rotate affine transform of the view along the Z axis.
|
||||
*/
|
||||
rotate: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the rotate affine transform of the view along the X axis.
|
||||
*/
|
||||
rotateX: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the rotate affine transform of the view along the Y axis.
|
||||
*/
|
||||
rotateY: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the distance of the camera form the view perspective.
|
||||
* Usually needed when rotating the view over the X or Y axis.
|
||||
*/
|
||||
perspective: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the translateX affine transform of the view in device independent pixels.
|
||||
*/
|
||||
|
||||
@@ -9,10 +9,12 @@ import {
|
||||
import { ios } from "./view-helper";
|
||||
import { ios as iosBackground, Background } from "../../styling/background";
|
||||
import { ios as iosUtils } from "../../../utils/utils";
|
||||
import { ios as iosNativeHelper } from "../../../utils/native-helper";
|
||||
import {
|
||||
Visibility,
|
||||
perspectiveProperty, Visibility,
|
||||
visibilityProperty, opacityProperty,
|
||||
rotateProperty, scaleXProperty, scaleYProperty,
|
||||
rotateProperty, rotateXProperty, rotateYProperty,
|
||||
scaleXProperty, scaleYProperty,
|
||||
translateXProperty, translateYProperty, zIndexProperty,
|
||||
backgroundInternalProperty, clipPathProperty
|
||||
} from "../../styling/style-properties";
|
||||
@@ -156,6 +158,7 @@ export class View extends ViewCommon implements ViewDefinition {
|
||||
}
|
||||
|
||||
public _setNativeViewFrame(nativeView: UIView, frame: CGRect): void {
|
||||
|
||||
let oldFrame = this._cachedFrame || nativeView.frame;
|
||||
if (!CGRectEqualToRect(oldFrame, frame)) {
|
||||
if (traceEnabled()) {
|
||||
@@ -166,8 +169,8 @@ export class View extends ViewCommon implements ViewDefinition {
|
||||
let transform = null;
|
||||
if (this._hasTransfrom) {
|
||||
// Always set identity transform before setting frame;
|
||||
transform = nativeView.transform;
|
||||
nativeView.transform = CGAffineTransformIdentity;
|
||||
transform = nativeView.layer.transform;
|
||||
nativeView.layer.transform = CATransform3DIdentity;
|
||||
nativeView.frame = frame;
|
||||
} else {
|
||||
nativeView.frame = frame;
|
||||
@@ -177,10 +180,10 @@ export class View extends ViewCommon implements ViewDefinition {
|
||||
if (adjustedFrame) {
|
||||
nativeView.frame = adjustedFrame;
|
||||
}
|
||||
|
||||
|
||||
if (this._hasTransfrom) {
|
||||
// re-apply the transform after the frame is adjusted
|
||||
nativeView.transform = transform;
|
||||
nativeView.layer.transform = transform;
|
||||
}
|
||||
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
@@ -348,18 +351,25 @@ export class View extends ViewCommon implements ViewDefinition {
|
||||
public updateNativeTransform() {
|
||||
const scaleX = this.scaleX || 1e-6;
|
||||
const scaleY = this.scaleY || 1e-6;
|
||||
const rotate = this.rotate || 0;
|
||||
let newTransform = CGAffineTransformIdentity;
|
||||
newTransform = CGAffineTransformTranslate(newTransform, this.translateX, this.translateY);
|
||||
newTransform = CGAffineTransformRotate(newTransform, rotate * Math.PI / 180);
|
||||
newTransform = CGAffineTransformScale(newTransform, scaleX, scaleY);
|
||||
if (!CGAffineTransformEqualToTransform(this.nativeViewProtected.transform, newTransform)) {
|
||||
const perspective = this.perspective || 300;
|
||||
|
||||
let transform = new CATransform3D(CATransform3DIdentity);
|
||||
|
||||
// Only set perspective if there is 3D rotation
|
||||
if (this.rotateX || this.rotateY) {
|
||||
transform.m34 = -1 / perspective;
|
||||
}
|
||||
|
||||
transform = CATransform3DTranslate(transform, this.translateX, this.translateY, 0);
|
||||
transform = iosNativeHelper.applyRotateTransform(transform, this.rotateX, this.rotateY, this.rotate);
|
||||
transform = CATransform3DScale(transform, scaleX, scaleY, 1);
|
||||
if (!CATransform3DEqualToTransform(this.nativeViewProtected.layer.transform, transform)) {
|
||||
const updateSuspended = this._isPresentationLayerUpdateSuspeneded();
|
||||
if (!updateSuspended) {
|
||||
CATransaction.begin();
|
||||
}
|
||||
this.nativeViewProtected.transform = newTransform;
|
||||
this._hasTransfrom = this.nativeViewProtected && !CGAffineTransformEqualToTransform(this.nativeViewProtected.transform, CGAffineTransformIdentity);
|
||||
this.nativeViewProtected.layer.transform = transform;
|
||||
this._hasTransfrom = this.nativeViewProtected && !CATransform3DEqualToTransform(this.nativeViewProtected.transform3D, CATransform3DIdentity);
|
||||
if (!updateSuspended) {
|
||||
CATransaction.commit();
|
||||
}
|
||||
@@ -579,6 +589,27 @@ export class View extends ViewCommon implements ViewDefinition {
|
||||
this.updateNativeTransform();
|
||||
}
|
||||
|
||||
[rotateXProperty.getDefault](): number {
|
||||
return 0;
|
||||
}
|
||||
[rotateXProperty.setNative](value: number) {
|
||||
this.updateNativeTransform();
|
||||
}
|
||||
|
||||
[rotateYProperty.getDefault](): number {
|
||||
return 0;
|
||||
}
|
||||
[rotateYProperty.setNative](value: number) {
|
||||
this.updateNativeTransform();
|
||||
}
|
||||
|
||||
[perspectiveProperty.getDefault](): number {
|
||||
return 300;
|
||||
}
|
||||
[perspectiveProperty.setNative](value: number) {
|
||||
this.updateNativeTransform();
|
||||
}
|
||||
|
||||
[scaleXProperty.getDefault](): number {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user