Merge pull request #1141 from NativeScript/feature/pivot-point

API for setting origin (a.k.a. pivot or anchor) point for view transfroms
This commit is contained in:
Alexander Vakrilov
2015-11-25 11:01:02 +02:00
8 changed files with 146 additions and 19 deletions

View File

@ -2104,7 +2104,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<UserProperties ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" />
<UserProperties ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" />
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@ -6,3 +6,8 @@ export function pageLoaded(args: observable.EventData) {
var page = <pages.Page>args.object;
page.bindingContext = new model.ViewModel();
}
export function onReset(args: observable.EventData) {
var model = <model.ViewModel>(<any>args.object).bindingContext;
model.reset();
}

View File

@ -1,29 +1,56 @@
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" id="mainPage">
<StackLayout orientation="vertical" backgroundColor="LightGray" paddingLeft="5" paddingRight="5">
<Page loaded="pageLoaded" id="mainPage">
<GridLayout columns="*, *" rows="auto, *">
<Label text="translateX" marginTop="5" />
<Slider minValue="-300" maxValue="300" value="{{ translateX }}"/>
<StackLayout orientation="vertical" backgroundColor="LightGray" paddingLeft="5" paddingRight="5">
<Label text="translateY" marginTop="5" />
<Slider minValue="-300" maxValue="300" value="{{ translateY }}"/>
<Label text="{{ 'translateX (' + translateX + ')' }}" marginTop="5" />
<Slider minValue="-300" maxValue="300" value="{{ translateX }}"/>
<Label text="scaleX" marginTop="5" />
<Slider minValue="0" maxValue="5" value="{{ scaleX }}"/>
<Label text="{{ 'scaleX (' + (scaleX / 100) + ')' }}" marginTop="5" />
<Slider minValue="0" maxValue="300" value="{{ scaleX }}"/>
<Label text="scaleY" marginTop="5" />
<Slider minValue="0" maxValue="5" value="{{ scaleY }}"/>
<Label text="{{ 'originX (' + (originX / 100) + ')' }}" marginTop="5" />
<Slider minValue="-100" maxValue="200" value="{{ originX }}"/>
<Label text="rotate" marginTop="5" />
<Slider minValue="-360" maxValue="360" value="{{ rotate }}"/>
<Label text="{{ 'rotate (' + rotate + ')' }}" marginTop="5" />
<Slider minValue="-360" maxValue="360" value="{{ rotate }}"/>
<AbsoluteLayout backgroundColor="Yellow" width="300" height="300" clipToBounds="true" marginTop="5" marginBottom="5">
</StackLayout>
<StackLayout col="1" orientation="vertical" backgroundColor="LightGray" paddingLeft="5" paddingRight="5">
<Label text="{{ 'translateY (' + translateY + ')' }}" marginTop="5" />
<Slider minValue="-300" maxValue="300" value="{{ translateY }}"/>
<Label text="{{ 'scaleY (' + (scaleY / 100) + ')' }}" marginTop="5" />
<Slider minValue="0" maxValue="300" value="{{ scaleY }}"/>
<Label text="{{ 'originY (' + (originY / 100) + ')' }}" marginTop="5" />
<Slider minValue="-100" maxValue="200" value="{{ originY }}"/>
<Button text="Reset" margin="5" tap="onReset" />
</StackLayout>
<AbsoluteLayout row="1" colSpan="2"
backgroundColor="Yellow" width="300" height="300" clipToBounds="true" marginTop="5" marginBottom="5">
<Label text="Transform Me!" backgroundColor="Green" width="100" height="100" left="100" top="100"
translateX="{{ translateX }}"
translateY="{{ translateY }}"
scaleX="{{ scaleX }}"
scaleY="{{ scaleY }}"
scaleX="{{ scaleX / 100 }}"
scaleY="{{ scaleY / 100 }}"
originX="{{ originX / 100 }}"
originY="{{ originY / 100 }}"
rotate="{{ rotate }}"
/>
<StackLayout width="1" height="300" backgroundColor="gray" left="99" />
<StackLayout width="1" height="300" backgroundColor="gray" left="200" />
<StackLayout height="1" width="300" backgroundColor="gray" top="99" />
<StackLayout height="1" width="300" backgroundColor="gray" top="200" />
<StackLayout height="2" width="2" backgroundColor="red" marginLeft="{{ originX + 99 }}" marginTop="{{ originY + 99 }}" />
</AbsoluteLayout>
</StackLayout>
</GridLayout>
</Page>

View File

@ -3,6 +3,7 @@
export class ViewModel extends observable.Observable {
constructor() {
super();
this.reset();
}
private _translateX = 0;;
@ -23,7 +24,7 @@ export class ViewModel extends observable.Observable {
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "translateY", value: value });
}
private _scaleX = 1;
private _scaleX = 100;
get scaleX(): number {
return this._scaleX;
}
@ -32,7 +33,7 @@ export class ViewModel extends observable.Observable {
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "scaleX", value: value });
}
private _scaleY = 1;
private _scaleY = 100;
get scaleY(): number {
return this._scaleY;
}
@ -41,6 +42,24 @@ export class ViewModel extends observable.Observable {
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "scaleY", value: value });
}
private _originX = 50;
get originX(): number {
return this._originX;
}
set originX(value: number) {
this._originX = value;
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "originX", value: value });
}
private _originY = 50;
get originY(): number {
return this._originY;
}
set originY(value: number) {
this._originY = value;
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "originY", value: value });
}
private _rotate = 0;
get rotate(): number {
return this._rotate;
@ -49,4 +68,14 @@ export class ViewModel extends observable.Observable {
this._rotate = value;
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "rotate", value: value });
}
public reset() {
this.originX = 50;
this.originY = 50;
this.scaleX = 100;
this.scaleY = 100;
this.translateX = 0;
this.translateY = 0;
this.rotate = 0;
}
}

View File

@ -149,6 +149,18 @@ var scaleYProperty = new dependencyObservable.Property(
new proxy.PropertyMetadata(1)
);
var originXProperty = new dependencyObservable.Property(
"originX",
"View",
new proxy.PropertyMetadata(0.5)
);
var originYProperty = new dependencyObservable.Property(
"originY",
"View",
new proxy.PropertyMetadata(0.5)
);
var rotateProperty = new dependencyObservable.Property(
"rotate",
"View",
@ -178,6 +190,8 @@ export class View extends proxy.ProxyObject implements definition.View {
public static translateYProperty = translateYProperty;
public static scaleXProperty = scaleXProperty;
public static scaleYProperty = scaleYProperty;
public static originXProperty = originXProperty;
public static originYProperty = originYProperty;
public static rotateProperty = rotateProperty;
public static isEnabledProperty = isEnabledProperty;
public static isUserInteractionEnabledProperty = isUserInteractionEnabledProperty;
@ -470,6 +484,20 @@ export class View extends proxy.ProxyObject implements definition.View {
this._setValue(View.scaleYProperty, value);
}
get originX(): number {
return this._getValue(View.originXProperty);
}
set originX(value: number) {
this._setValue(View.originXProperty, value);
}
get originY(): number {
return this._getValue(View.originYProperty);
}
set originY(value: number) {
this._setValue(View.originYProperty, value);
}
get rotate(): number {
return this._getValue(View.rotateProperty);
}

View File

@ -44,6 +44,20 @@ function onScaleYPropertyChanged(data: dependencyObservable.PropertyChangeData)
}
(<proxy.PropertyMetadata>viewCommon.View.scaleYProperty.metadata).onSetNativeValue = onScaleYPropertyChanged;
function onOriginXPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
var width = view._nativeView.getWidth();
view._nativeView.setPivotX(data.newValue * width);
}
(<proxy.PropertyMetadata>viewCommon.View.originXProperty.metadata).onSetNativeValue = onOriginXPropertyChanged;
function onOriginYPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
var height = view._nativeView.getHeight();
view._nativeView.setPivotY(data.newValue * height);
}
(<proxy.PropertyMetadata>viewCommon.View.originYProperty.metadata).onSetNativeValue = onOriginYPropertyChanged;
function onRotatePropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
view._nativeView.setRotation(data.newValue);

10
ui/core/view.d.ts vendored
View File

@ -259,6 +259,16 @@ declare module "ui/core/view" {
*/
scaleY: number;
/**
* Gets or sets the X component of the origin point around which the view will be transformed. The deafault value is 0.5 representing the center of the view.
*/
originX: number;
/**
* Gets or sets the Y component of the origin point around which the view will be transformed. The deafault value is 0.5 representing the center of the view.
*/
originY: number;
/**
* Gets or sets the rotate affine transform of the view.
*/

View File

@ -66,6 +66,20 @@ function onScaleYPropertyChanged(data: dependencyObservable.PropertyChangeData)
}
(<proxy.PropertyMetadata>viewCommon.View.scaleYProperty.metadata).onSetNativeValue = onScaleYPropertyChanged;
function onOriginXPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
var current = view._nativeView.layer.anchorPoint;
view._nativeView.layer.anchorPoint = CGPointMake(data.newValue, current.y);
}
(<proxy.PropertyMetadata>viewCommon.View.originXProperty.metadata).onSetNativeValue = onOriginXPropertyChanged;
function onOriginYPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
var current = view._nativeView.layer.anchorPoint;
view._nativeView.layer.anchorPoint = CGPointMake(current.x, data.newValue);
}
(<proxy.PropertyMetadata>viewCommon.View.originYProperty.metadata).onSetNativeValue = onOriginYPropertyChanged;
function onRotatePropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
var newTransform = CGAffineTransformIdentity;