mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 22:01:42 +08:00
Merge pull request #3596 from NativeScript/cankov/modules30-qsf
Animation properties and some backward compatability with the QSF
This commit is contained in:
58
apps/app/gallery-app/animations/css-keyframes.css
Normal file
58
apps/app/gallery-app/animations/css-keyframes.css
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
@keyframes intro {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-100, 0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes outro {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-100, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro {
|
||||||
|
animation-name: intro;
|
||||||
|
animation-duration: 3.0;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||||
|
}
|
||||||
|
.outro {
|
||||||
|
animation-name: outro;
|
||||||
|
animation-duration: 3.0;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gone {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-100, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes play {
|
||||||
|
0% { transform: translate(0, 0); }
|
||||||
|
33% { transform: translate(100, 0); }
|
||||||
|
66% { transform: translate(100, 100); }
|
||||||
|
100% { transform: translate(0, 100); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.idle {
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
.play {
|
||||||
|
animation-name: play;
|
||||||
|
animation-duration: 3.0;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||||
|
}
|
13
apps/app/gallery-app/animations/css-keyframes.ts
Normal file
13
apps/app/gallery-app/animations/css-keyframes.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { View, EventData } from "ui/core/view";
|
||||||
|
|
||||||
|
export function setClass(args: EventData) {
|
||||||
|
const btn = (<View & { tag: any }>args.object);
|
||||||
|
const img = btn.page.getViewById<View>("img");
|
||||||
|
img.className = btn.tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setImg2Class(args: EventData) {
|
||||||
|
const btn = (<View & { tag: any }>args.object);
|
||||||
|
const img2 = btn.page.getViewById<View>("img2");
|
||||||
|
img2.className = btn.tag;
|
||||||
|
}
|
18
apps/app/gallery-app/animations/css-keyframes.xml
Normal file
18
apps/app/gallery-app/animations/css-keyframes.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" id="mainPage">
|
||||||
|
<StackLayout orientation="vertical">
|
||||||
|
<Button text="class: gone" tag="gone" tap="setClass" />
|
||||||
|
<Button text="class: intro" tag="intro" tap="setClass" />
|
||||||
|
<Button text="class: outro" tag="outro" tap="setClass" />
|
||||||
|
<Button text="clear class" tag="none" tap="setClass" />
|
||||||
|
|
||||||
|
<GridLayout horizontalAlignment="center" verticalAlignment="middle" backgroundColor="blue" width="150" height="50">
|
||||||
|
<GridLayout id="img" class="gone" backgroundColor="green" width="50" height="50" horizontalAlignment="right" />
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
|
<Button text="class: idle" tag="idle" tap="setImg2Class" />
|
||||||
|
<Button text="class: play" tag="play" tap="setImg2Class" />
|
||||||
|
<GridLayout horizontalAlignment="center" verticalAlignment="middle" backgroundColor="gray" width="150" height="150">
|
||||||
|
<GridLayout id="img2" class="idle" backgroundColor="green" width="50" height="50" horizontalAlignment="left" verticalAlignment="top" />
|
||||||
|
</GridLayout>
|
||||||
|
</StackLayout>
|
||||||
|
</Page>
|
@ -4,12 +4,47 @@ import * as buttonModule from "ui/button";
|
|||||||
import * as abs from "ui/layouts/absolute-layout";
|
import * as abs from "ui/layouts/absolute-layout";
|
||||||
import * as animationModule from "ui/animation";
|
import * as animationModule from "ui/animation";
|
||||||
import * as colorModule from "color";
|
import * as colorModule from "color";
|
||||||
import * as model from "./model";
|
|
||||||
import * as enums from "ui/enums";
|
import * as enums from "ui/enums";
|
||||||
import * as frame from "ui/frame";
|
import * as frame from "ui/frame";
|
||||||
import * as trace from "trace";
|
import * as trace from "trace";
|
||||||
|
|
||||||
var vm = new model.ViewModel();
|
export class ViewModel extends observable.Observable {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this._duration = 3000;
|
||||||
|
this._iterations = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _playSequentially: boolean;
|
||||||
|
get playSequentially(): boolean {
|
||||||
|
return this._playSequentially;
|
||||||
|
}
|
||||||
|
set playSequentially(value: boolean) {
|
||||||
|
this._playSequentially = value;
|
||||||
|
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "playSequentially", value: value });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _duration: number;
|
||||||
|
get duration(): number {
|
||||||
|
return this._duration;
|
||||||
|
}
|
||||||
|
set duration(value: number) {
|
||||||
|
this._duration = value;
|
||||||
|
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "duration", value: value });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _iterations: number;
|
||||||
|
get iterations(): number {
|
||||||
|
return this._iterations;
|
||||||
|
}
|
||||||
|
set iterations(value: number) {
|
||||||
|
this._iterations = value;
|
||||||
|
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "iterations", value: value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var vm = new ViewModel();
|
||||||
|
|
||||||
var page: pages.Page;
|
var page: pages.Page;
|
||||||
var panel: abs.AbsoluteLayout;
|
var panel: abs.AbsoluteLayout;
|
||||||
@ -27,8 +62,8 @@ export function pageLoaded(args: observable.EventData) {
|
|||||||
button2 = page.getViewById<buttonModule.Button>("button2");
|
button2 = page.getViewById<buttonModule.Button>("button2");
|
||||||
button3 = page.getViewById<buttonModule.Button>("button3");
|
button3 = page.getViewById<buttonModule.Button>("button3");
|
||||||
|
|
||||||
trace.enable();
|
// trace.enable();
|
||||||
trace.addCategories(trace.categories.concat(trace.categories.Animation));
|
// trace.addCategories(trace.categories.concat(trace.categories.Animation));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onSlideOut(args: observable.EventData) {
|
export function onSlideOut(args: observable.EventData) {
|
@ -18,7 +18,6 @@
|
|||||||
<Button text="In" tap="onSlideIn" width="40" marginLeft="5" marginRight="5" />
|
<Button text="In" tap="onSlideIn" width="40" marginLeft="5" marginRight="5" />
|
||||||
<Button text="Single" tap="onSingle" width="70" marginLeft="5" marginRight="5" />
|
<Button text="Single" tap="onSingle" width="70" marginLeft="5" marginRight="5" />
|
||||||
<Button text="Cancel" tap="onCancel" width="70" marginLeft="5" marginRight="5" />
|
<Button text="Cancel" tap="onCancel" width="70" marginLeft="5" marginRight="5" />
|
||||||
<Button text="Opacity" tap="onOpacity" width="70" marginLeft="5" marginRight="5" />
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
||||||
<StackLayout orientation="horizontal" marginTop="5" marginBottom="5" horizontalAlignment="center" paddingLeft="5" paddingRight="5">>
|
<StackLayout orientation="horizontal" marginTop="5" marginBottom="5" horizontalAlignment="center" paddingLeft="5" paddingRight="5">>
|
@ -1,37 +0,0 @@
|
|||||||
import observable = require("data/observable");
|
|
||||||
|
|
||||||
export class ViewModel extends observable.Observable {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this._duration = 3000;
|
|
||||||
this._iterations = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _playSequentially: boolean;
|
|
||||||
get playSequentially(): boolean {
|
|
||||||
return this._playSequentially;
|
|
||||||
}
|
|
||||||
set playSequentially(value: boolean) {
|
|
||||||
this._playSequentially = value;
|
|
||||||
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "playSequentially", value: value });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _duration: number;
|
|
||||||
get duration(): number {
|
|
||||||
return this._duration;
|
|
||||||
}
|
|
||||||
set duration(value: number) {
|
|
||||||
this._duration = value;
|
|
||||||
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "duration", value: value });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _iterations: number;
|
|
||||||
get iterations(): number {
|
|
||||||
return this._iterations;
|
|
||||||
}
|
|
||||||
set iterations(value: number) {
|
|
||||||
this._iterations = value;
|
|
||||||
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "iterations", value: value });
|
|
||||||
}
|
|
||||||
}
|
|
@ -43,8 +43,9 @@
|
|||||||
|
|
||||||
<Label class="title" text="Animations" />
|
<Label class="title" text="Animations" />
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<Button tag="animations/configurable" text="configurable" tap="itemTap" />
|
<Button tag="animations/js-configurable" text="js-configurable" tap="itemTap" />
|
||||||
<Button tag="animations/opacity" text="opacity" tap="itemTap" />
|
<Button tag="animations/js-opacity" text="js-opacity" tap="itemTap" />
|
||||||
|
<Button tag="animations/css-keyframes" text="css-keyframes" tap="itemTap" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
AnimationBase, Properties, PropertyAnimation, CubicBezierAnimationCurve, AnimationPromise,
|
AnimationBase, Properties, PropertyAnimation, CubicBezierAnimationCurve, AnimationPromise,
|
||||||
opacityProperty, backgroundColorProperty, rotateProperty,
|
opacityProperty, backgroundColorProperty, rotateProperty,
|
||||||
translateXProperty, translateYProperty,
|
translateXProperty, translateYProperty,
|
||||||
scaleXProperty, scaleYProperty, Color, traceWrite, traceEnabled, traceCategories
|
scaleXProperty, scaleYProperty, Color, traceWrite, traceEnabled, traceCategories, unsetValue
|
||||||
} from "./animation-common";
|
} from "./animation-common";
|
||||||
|
|
||||||
import { CacheLayerType, layout } from "utils/utils";
|
import { CacheLayerType, layout } from "utils/utils";
|
||||||
@ -12,7 +12,7 @@ import lazy from "utils/lazy";
|
|||||||
export * from "./animation-common";
|
export * from "./animation-common";
|
||||||
|
|
||||||
interface AnimationDefinitionInternal extends AnimationDefinition {
|
interface AnimationDefinitionInternal extends AnimationDefinition {
|
||||||
valueSource?: number;
|
valueSource?: "animation" | "keyframe";
|
||||||
}
|
}
|
||||||
|
|
||||||
let argbEvaluator: android.animation.ArgbEvaluator;
|
let argbEvaluator: android.animation.ArgbEvaluator;
|
||||||
@ -88,7 +88,7 @@ export class Animation extends AnimationBase {
|
|||||||
private _animators: Array<android.animation.Animator>;
|
private _animators: Array<android.animation.Animator>;
|
||||||
private _propertyUpdateCallbacks: Array<Function>;
|
private _propertyUpdateCallbacks: Array<Function>;
|
||||||
private _propertyResetCallbacks: Array<Function>;
|
private _propertyResetCallbacks: Array<Function>;
|
||||||
private _valueSource: number;
|
private _valueSource: "animation" | "keyframe";
|
||||||
|
|
||||||
constructor(animationDefinitions: Array<AnimationDefinitionInternal>, playSequentially?: boolean) {
|
constructor(animationDefinitions: Array<AnimationDefinitionInternal>, playSequentially?: boolean) {
|
||||||
super(animationDefinitions, playSequentially);
|
super(animationDefinitions, playSequentially);
|
||||||
@ -243,7 +243,7 @@ export class Animation extends AnimationBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let valueSource = this._valueSource !== undefined ? this._valueSource : dependencyObservable.ValueSource.Local;
|
let setLocal = this._valueSource === "animation";
|
||||||
|
|
||||||
switch (propertyAnimation.property) {
|
switch (propertyAnimation.property) {
|
||||||
case Properties.opacity:
|
case Properties.opacity:
|
||||||
@ -251,10 +251,17 @@ export class Animation extends AnimationBase {
|
|||||||
nativeArray = Array.create("float", 1);
|
nativeArray = Array.create("float", 1);
|
||||||
nativeArray[0] = propertyAnimation.value;
|
nativeArray[0] = propertyAnimation.value;
|
||||||
propertyUpdateCallbacks.push(checkAnimation(() => {
|
propertyUpdateCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[opacityProperty.cssName] = propertyAnimation.value;
|
propertyAnimation.target.style[setLocal ? opacityProperty.name : opacityProperty.keyframe] = propertyAnimation.value;
|
||||||
}));
|
}));
|
||||||
propertyResetCallbacks.push(checkAnimation(() => {
|
propertyResetCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[opacityProperty.cssName] = originalValue1;
|
if (setLocal) {
|
||||||
|
propertyAnimation.target.style[opacityProperty.name] = originalValue1;
|
||||||
|
} else {
|
||||||
|
propertyAnimation.target.style[opacityProperty.keyframe] = originalValue1;
|
||||||
|
}
|
||||||
|
if (propertyAnimation.target.nativeView) {
|
||||||
|
propertyAnimation.target[opacityProperty.native] = propertyAnimation.target.style.opacity;
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
animators.push(android.animation.ObjectAnimator.ofFloat(nativeView, "alpha", nativeArray));
|
animators.push(android.animation.ObjectAnimator.ofFloat(nativeView, "alpha", nativeArray));
|
||||||
break;
|
break;
|
||||||
@ -274,10 +281,17 @@ export class Animation extends AnimationBase {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
propertyUpdateCallbacks.push(checkAnimation(() => {
|
propertyUpdateCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[backgroundColorProperty.cssName] = propertyAnimation.value;
|
propertyAnimation.target.style[setLocal ? backgroundColorProperty.name : backgroundColorProperty.keyframe] = propertyAnimation.value;
|
||||||
}));
|
}));
|
||||||
propertyResetCallbacks.push(checkAnimation(() => {
|
propertyResetCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[backgroundColorProperty.cssName] = originalValue1;
|
if (setLocal) {
|
||||||
|
propertyAnimation.target.style[backgroundColorProperty.name] = originalValue1;
|
||||||
|
} else {
|
||||||
|
propertyAnimation.target.style[backgroundColorProperty.keyframe] = originalValue1;
|
||||||
|
if (propertyAnimation.target.nativeView) {
|
||||||
|
propertyAnimation.target[backgroundColorProperty.native] = propertyAnimation.target.style.backgroundColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
animators.push(animator);
|
animators.push(animator);
|
||||||
break;
|
break;
|
||||||
@ -295,17 +309,26 @@ export class Animation extends AnimationBase {
|
|||||||
xyObjectAnimators[1] = android.animation.ObjectAnimator.ofFloat(nativeView, "translationY", nativeArray);
|
xyObjectAnimators[1] = android.animation.ObjectAnimator.ofFloat(nativeView, "translationY", nativeArray);
|
||||||
xyObjectAnimators[1].setRepeatCount(Animation._getAndroidRepeatCount(propertyAnimation.iterations));
|
xyObjectAnimators[1].setRepeatCount(Animation._getAndroidRepeatCount(propertyAnimation.iterations));
|
||||||
|
|
||||||
originalValue1 = nativeView.getTranslationX();
|
originalValue1 = nativeView.getTranslationX() / density;
|
||||||
originalValue2 = nativeView.getTranslationY();
|
originalValue2 = nativeView.getTranslationY() / density;
|
||||||
|
|
||||||
propertyUpdateCallbacks.push(checkAnimation(() => {
|
propertyUpdateCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[translateXProperty.cssName] = propertyAnimation.value.x;
|
propertyAnimation.target.style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = propertyAnimation.value.x;
|
||||||
propertyAnimation.target.style[translateYProperty.cssName] = propertyAnimation.value.y;
|
propertyAnimation.target.style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = propertyAnimation.value.y;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
propertyResetCallbacks.push(checkAnimation(() => {
|
propertyResetCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[translateXProperty.cssName] = originalValue1;
|
if (setLocal) {
|
||||||
propertyAnimation.target.style[translateYProperty.cssName] = originalValue2;
|
propertyAnimation.target.style[translateXProperty.name] = originalValue1;
|
||||||
|
propertyAnimation.target.style[translateYProperty.name] = originalValue2;
|
||||||
|
} else {
|
||||||
|
propertyAnimation.target.style[translateXProperty.keyframe] = originalValue1;
|
||||||
|
propertyAnimation.target.style[translateYProperty.keyframe] = originalValue2;
|
||||||
|
if (propertyAnimation.target.nativeView) {
|
||||||
|
propertyAnimation.target[translateXProperty.native] = propertyAnimation.target.style.translateX;
|
||||||
|
propertyAnimation.target[translateYProperty.native] = propertyAnimation.target.style.translateY;
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
animatorSet = new android.animation.AnimatorSet();
|
animatorSet = new android.animation.AnimatorSet();
|
||||||
@ -331,13 +354,22 @@ export class Animation extends AnimationBase {
|
|||||||
originalValue2 = nativeView.getScaleY();
|
originalValue2 = nativeView.getScaleY();
|
||||||
|
|
||||||
propertyUpdateCallbacks.push(checkAnimation(() => {
|
propertyUpdateCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[scaleXProperty.cssName] = propertyAnimation.value.x;
|
propertyAnimation.target.style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = propertyAnimation.value.x;
|
||||||
propertyAnimation.target.style[scaleYProperty.cssName] = propertyAnimation.value.y;
|
propertyAnimation.target.style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = propertyAnimation.value.y;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
propertyResetCallbacks.push(checkAnimation(() => {
|
propertyResetCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[scaleXProperty.cssName] = originalValue1;
|
if (setLocal) {
|
||||||
propertyAnimation.target.style[scaleYProperty.cssName] = originalValue2;
|
propertyAnimation.target.style[scaleXProperty.name] = originalValue1;
|
||||||
|
propertyAnimation.target.style[scaleYProperty.name] = originalValue2;
|
||||||
|
} else {
|
||||||
|
propertyAnimation.target.style[scaleXProperty.keyframe] = originalValue1;
|
||||||
|
propertyAnimation.target.style[scaleYProperty.keyframe] = originalValue2;
|
||||||
|
if (propertyAnimation.target.nativeView) {
|
||||||
|
propertyAnimation.target[scaleXProperty.native] = propertyAnimation.target.style.scaleX;
|
||||||
|
propertyAnimation.target[scaleYProperty.native] = propertyAnimation.target.style.scaleY;
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
animatorSet = new android.animation.AnimatorSet();
|
animatorSet = new android.animation.AnimatorSet();
|
||||||
@ -351,10 +383,17 @@ export class Animation extends AnimationBase {
|
|||||||
nativeArray = Array.create("float", 1);
|
nativeArray = Array.create("float", 1);
|
||||||
nativeArray[0] = propertyAnimation.value;
|
nativeArray[0] = propertyAnimation.value;
|
||||||
propertyUpdateCallbacks.push(checkAnimation(() => {
|
propertyUpdateCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[rotateProperty.cssName] = propertyAnimation.value;
|
propertyAnimation.target.style[setLocal ? rotateProperty.name : rotateProperty.keyframe] = propertyAnimation.value;
|
||||||
}));
|
}));
|
||||||
propertyResetCallbacks.push(checkAnimation(() => {
|
propertyResetCallbacks.push(checkAnimation(() => {
|
||||||
propertyAnimation.target.style[rotateProperty.cssName] = originalValue1;
|
if (setLocal) {
|
||||||
|
propertyAnimation.target.style[rotateProperty.name] = originalValue1;
|
||||||
|
} else {
|
||||||
|
propertyAnimation.target.style[rotateProperty.keyframe] = originalValue1;
|
||||||
|
if (propertyAnimation.target.nativeView) {
|
||||||
|
propertyAnimation.target[rotateProperty.native] = propertyAnimation.target.style.rotate;
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
animators.push(android.animation.ObjectAnimator.ofFloat(nativeView, "rotation", nativeArray));
|
animators.push(android.animation.ObjectAnimator.ofFloat(nativeView, "rotation", nativeArray));
|
||||||
break;
|
break;
|
||||||
|
@ -2,7 +2,7 @@ import { AnimationDefinition } from "ui/animation";
|
|||||||
import {
|
import {
|
||||||
AnimationBase, Properties, PropertyAnimation, CubicBezierAnimationCurve, AnimationPromise, View, opacityProperty, backgroundColorProperty, rotateProperty,
|
AnimationBase, Properties, PropertyAnimation, CubicBezierAnimationCurve, AnimationPromise, View, opacityProperty, backgroundColorProperty, rotateProperty,
|
||||||
translateXProperty, translateYProperty,
|
translateXProperty, translateYProperty,
|
||||||
scaleXProperty, scaleYProperty, traceEnabled, traceWrite, traceCategories
|
scaleXProperty, scaleYProperty, traceEnabled, traceWrite, traceCategories, Length
|
||||||
} from "./animation-common";
|
} from "./animation-common";
|
||||||
|
|
||||||
import { ios } from "utils/utils";
|
import { ios } from "utils/utils";
|
||||||
@ -33,7 +33,7 @@ interface PropertyAnimationInfo extends PropertyAnimation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface AnimationDefinitionInternal extends AnimationDefinition {
|
interface AnimationDefinitionInternal extends AnimationDefinition {
|
||||||
valueSource?: number;
|
valueSource?: "animation" | "keyframe";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IOSView extends View {
|
interface IOSView extends View {
|
||||||
@ -51,9 +51,9 @@ class AnimationDelegateImpl extends NSObject implements CAAnimationDelegate {
|
|||||||
|
|
||||||
private _finishedCallback: Function;
|
private _finishedCallback: Function;
|
||||||
private _propertyAnimation: PropertyAnimationInfo;
|
private _propertyAnimation: PropertyAnimationInfo;
|
||||||
private _valueSource: number;
|
private _valueSource: "animation" | "keyframe";
|
||||||
|
|
||||||
public static initWithFinishedCallback(finishedCallback: Function, propertyAnimation: PropertyAnimationInfo, valueSource: number): AnimationDelegateImpl {
|
public static initWithFinishedCallback(finishedCallback: Function, propertyAnimation: PropertyAnimationInfo, valueSource: "animation" | "keyframe"): AnimationDelegateImpl {
|
||||||
let delegate = <AnimationDelegateImpl>AnimationDelegateImpl.new();
|
let delegate = <AnimationDelegateImpl>AnimationDelegateImpl.new();
|
||||||
delegate._finishedCallback = finishedCallback;
|
delegate._finishedCallback = finishedCallback;
|
||||||
delegate._propertyAnimation = propertyAnimation;
|
delegate._propertyAnimation = propertyAnimation;
|
||||||
@ -63,40 +63,39 @@ class AnimationDelegateImpl extends NSObject implements CAAnimationDelegate {
|
|||||||
|
|
||||||
animationDidStart(anim: CAAnimation): void {
|
animationDidStart(anim: CAAnimation): void {
|
||||||
let value = this._propertyAnimation.value;
|
let value = this._propertyAnimation.value;
|
||||||
// let valueSource = this._valueSource || dependencyObservable.ValueSource.Local;
|
let setLocal = this._valueSource === "animation";
|
||||||
let setLocal = true;
|
|
||||||
let targetStyle = this._propertyAnimation.target.style;
|
let targetStyle = this._propertyAnimation.target.style;
|
||||||
|
|
||||||
(<IOSView>this._propertyAnimation.target)._suspendPresentationLayerUpdates();
|
(<IOSView>this._propertyAnimation.target)._suspendPresentationLayerUpdates();
|
||||||
|
|
||||||
switch (this._propertyAnimation.property) {
|
switch (this._propertyAnimation.property) {
|
||||||
case Properties.backgroundColor:
|
case Properties.backgroundColor:
|
||||||
targetStyle[setLocal ? backgroundColorProperty.name : backgroundColorProperty.cssName] = value;
|
targetStyle[setLocal ? backgroundColorProperty.name : backgroundColorProperty.keyframe] = value;
|
||||||
break;
|
break;
|
||||||
case Properties.opacity:
|
case Properties.opacity:
|
||||||
targetStyle[setLocal ? opacityProperty.name : opacityProperty.cssName] = value;
|
targetStyle[setLocal ? opacityProperty.name : opacityProperty.keyframe] = value;
|
||||||
break;
|
break;
|
||||||
case Properties.rotate:
|
case Properties.rotate:
|
||||||
targetStyle[setLocal ? rotateProperty.name : rotateProperty.cssName] = value;
|
targetStyle[setLocal ? rotateProperty.name : rotateProperty.keyframe] = value;
|
||||||
break;
|
break;
|
||||||
case Properties.translate:
|
case Properties.translate:
|
||||||
targetStyle[setLocal ? translateXProperty.name : translateXProperty.cssName] = value;
|
targetStyle[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value;
|
||||||
targetStyle[setLocal ? translateYProperty.name : translateYProperty.cssName] = value;
|
targetStyle[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value;
|
||||||
break;
|
break;
|
||||||
case Properties.scale:
|
case Properties.scale:
|
||||||
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.cssName] = value.x === 0 ? 0.001 : value.x;
|
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x === 0 ? 0.001 : value.x;
|
||||||
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.cssName] = value.y === 0 ? 0.001 : value.y;
|
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y === 0 ? 0.001 : value.y;
|
||||||
break;
|
break;
|
||||||
case _transform:
|
case _transform:
|
||||||
if (value[Properties.translate] !== undefined) {
|
if (value[Properties.translate] !== undefined) {
|
||||||
targetStyle[setLocal ? translateXProperty.name : translateXProperty.cssName] = value[Properties.translate].x;
|
targetStyle[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value[Properties.translate].x;
|
||||||
targetStyle[setLocal ? translateYProperty.name : translateYProperty.cssName] = value[Properties.translate].y;
|
targetStyle[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value[Properties.translate].y;
|
||||||
}
|
}
|
||||||
if (value[Properties.scale] !== undefined) {
|
if (value[Properties.scale] !== undefined) {
|
||||||
let x = value[Properties.scale].x;
|
let x = value[Properties.scale].x;
|
||||||
let y = value[Properties.scale].y;
|
let y = value[Properties.scale].y;
|
||||||
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.cssName] = x === 0 ? 0.001 : x;
|
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = x === 0 ? 0.001 : x;
|
||||||
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.cssName] = y === 0 ? 0.001 : y;
|
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = y === 0 ? 0.001 : y;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -147,7 +146,7 @@ export class Animation extends AnimationBase {
|
|||||||
private _finishedAnimations: number;
|
private _finishedAnimations: number;
|
||||||
private _cancelledAnimations: number;
|
private _cancelledAnimations: number;
|
||||||
private _mergedPropertyAnimations: Array<PropertyAnimationInfo>;
|
private _mergedPropertyAnimations: Array<PropertyAnimationInfo>;
|
||||||
private _valueSource: number;
|
private _valueSource: "animation" | "keyframe";
|
||||||
|
|
||||||
constructor(animationDefinitions: Array<AnimationDefinitionInternal>, playSequentially?: boolean) {
|
constructor(animationDefinitions: Array<AnimationDefinitionInternal>, playSequentially?: boolean) {
|
||||||
super(animationDefinitions, playSequentially);
|
super(animationDefinitions, playSequentially);
|
||||||
@ -233,7 +232,7 @@ export class Animation extends AnimationBase {
|
|||||||
return _resolveAnimationCurve(curve);
|
return _resolveAnimationCurve(curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createiOSAnimationFunction(propertyAnimations: Array<PropertyAnimation>, index: number, playSequentially: boolean, valueSource: number, finishedCallback: (cancelled?: boolean) => void): Function {
|
private static _createiOSAnimationFunction(propertyAnimations: Array<PropertyAnimation>, index: number, playSequentially: boolean, valueSource: "animation" | "keyframe", finishedCallback: (cancelled?: boolean) => void): Function {
|
||||||
return (cancelled?: boolean) => {
|
return (cancelled?: boolean) => {
|
||||||
|
|
||||||
if (cancelled && finishedCallback) {
|
if (cancelled && finishedCallback) {
|
||||||
@ -256,7 +255,7 @@ export class Animation extends AnimationBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _getNativeAnimationArguments(animation: PropertyAnimationInfo, valueSource: number): AnimationInfo {
|
private static _getNativeAnimationArguments(animation: PropertyAnimationInfo, valueSource: "animation" | "keyframe"): AnimationInfo {
|
||||||
|
|
||||||
let nativeView = <UIView>animation.target._nativeView;
|
let nativeView = <UIView>animation.target._nativeView;
|
||||||
let propertyNameToAnimate = animation.property;
|
let propertyNameToAnimate = animation.property;
|
||||||
@ -266,16 +265,13 @@ export class Animation extends AnimationBase {
|
|||||||
let tempRotate = (animation.target.rotate || 0) * Math.PI / 180;
|
let tempRotate = (animation.target.rotate || 0) * Math.PI / 180;
|
||||||
let abs;
|
let abs;
|
||||||
|
|
||||||
let setLocal = true;
|
let setLocal = valueSource === "animation";
|
||||||
// if (valueSource === undefined) {
|
|
||||||
// valueSource = dependencyObservable.ValueSource.Local;
|
|
||||||
// }
|
|
||||||
|
|
||||||
switch (animation.property) {
|
switch (animation.property) {
|
||||||
case Properties.backgroundColor:
|
case Properties.backgroundColor:
|
||||||
animation._originalValue = animation.target.backgroundColor;
|
animation._originalValue = animation.target.backgroundColor;
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
animation.target.style[setLocal ? backgroundColorProperty.name : backgroundColorProperty.cssName] = value;
|
animation.target.style[setLocal ? backgroundColorProperty.name : backgroundColorProperty.keyframe] = value;
|
||||||
};
|
};
|
||||||
originalValue = nativeView.layer.backgroundColor;
|
originalValue = nativeView.layer.backgroundColor;
|
||||||
if (nativeView instanceof UILabel) {
|
if (nativeView instanceof UILabel) {
|
||||||
@ -286,14 +282,14 @@ export class Animation extends AnimationBase {
|
|||||||
case Properties.opacity:
|
case Properties.opacity:
|
||||||
animation._originalValue = animation.target.opacity;
|
animation._originalValue = animation.target.opacity;
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
animation.target.style[setLocal ? opacityProperty.name : opacityProperty.cssName] = value;
|
animation.target.style[setLocal ? opacityProperty.name : opacityProperty.keyframe] = value;
|
||||||
};
|
};
|
||||||
originalValue = nativeView.layer.opacity;
|
originalValue = nativeView.layer.opacity;
|
||||||
break;
|
break;
|
||||||
case Properties.rotate:
|
case Properties.rotate:
|
||||||
animation._originalValue = animation.target.rotate !== undefined ? animation.target.rotate : 0;
|
animation._originalValue = animation.target.rotate !== undefined ? animation.target.rotate : 0;
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
animation.target.style[setLocal ? rotateProperty.name : rotateProperty.cssName] = value;
|
animation.target.style[setLocal ? rotateProperty.name : rotateProperty.keyframe] = value;
|
||||||
};
|
};
|
||||||
propertyNameToAnimate = "transform.rotation";
|
propertyNameToAnimate = "transform.rotation";
|
||||||
originalValue = nativeView.layer.valueForKeyPath("transform.rotation");
|
originalValue = nativeView.layer.valueForKeyPath("transform.rotation");
|
||||||
@ -309,8 +305,8 @@ export class Animation extends AnimationBase {
|
|||||||
case Properties.translate:
|
case Properties.translate:
|
||||||
animation._originalValue = { x: animation.target.translateX, y: animation.target.translateY };
|
animation._originalValue = { x: animation.target.translateX, y: animation.target.translateY };
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
animation.target.style[setLocal ? translateXProperty.name : translateXProperty.cssName] = value.x;
|
animation.target.style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value.x;
|
||||||
animation.target.style[setLocal ? translateYProperty.name : translateYProperty.cssName] = value.y;
|
animation.target.style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value.y;
|
||||||
};
|
};
|
||||||
propertyNameToAnimate = "transform";
|
propertyNameToAnimate = "transform";
|
||||||
originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
||||||
@ -325,8 +321,8 @@ export class Animation extends AnimationBase {
|
|||||||
}
|
}
|
||||||
animation._originalValue = { x: animation.target.scaleX, y: animation.target.scaleY };
|
animation._originalValue = { x: animation.target.scaleX, y: animation.target.scaleY };
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
animation.target.style[setLocal ? scaleXProperty.name : scaleXProperty.cssName] = value.x;
|
animation.target.style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x;
|
||||||
animation.target.style[setLocal ? scaleYProperty.name : scaleYProperty.cssName] = value.y;
|
animation.target.style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y;
|
||||||
};
|
};
|
||||||
propertyNameToAnimate = "transform";
|
propertyNameToAnimate = "transform";
|
||||||
originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
||||||
@ -339,10 +335,10 @@ export class Animation extends AnimationBase {
|
|||||||
xt: animation.target.translateX, yt: animation.target.translateY
|
xt: animation.target.translateX, yt: animation.target.translateY
|
||||||
};
|
};
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
animation.target.style[setLocal ? translateXProperty.name : translateXProperty.cssName] = value.xt;
|
animation.target.style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value.xt;
|
||||||
animation.target.style[setLocal ? translateYProperty.name : translateYProperty.cssName] = value.yt;
|
animation.target.style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value.yt;
|
||||||
animation.target.style[setLocal ? scaleXProperty.name : scaleXProperty.cssName] = value.xs;
|
animation.target.style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.xs;
|
||||||
animation.target.style[setLocal ? scaleYProperty.name : scaleYProperty.cssName] = value.ys;
|
animation.target.style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.ys;
|
||||||
};
|
};
|
||||||
propertyNameToAnimate = "transform";
|
propertyNameToAnimate = "transform";
|
||||||
value = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation));
|
value = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation));
|
||||||
@ -381,7 +377,7 @@ export class Animation extends AnimationBase {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createNativeAnimation(propertyAnimations: Array<PropertyAnimation>, index: number, playSequentially: boolean, args: AnimationInfo, animation: PropertyAnimation, valueSource: number, finishedCallback: (cancelled?: boolean) => void) {
|
private static _createNativeAnimation(propertyAnimations: Array<PropertyAnimation>, index: number, playSequentially: boolean, args: AnimationInfo, animation: PropertyAnimation, valueSource: "animation" | "keyframe", finishedCallback: (cancelled?: boolean) => void) {
|
||||||
|
|
||||||
let nativeView = <UIView>animation.target._nativeView;
|
let nativeView = <UIView>animation.target._nativeView;
|
||||||
let nativeAnimation = CABasicAnimation.animationWithKeyPath(args.propertyNameToAnimate);
|
let nativeAnimation = CABasicAnimation.animationWithKeyPath(args.propertyNameToAnimate);
|
||||||
@ -415,7 +411,7 @@ export class Animation extends AnimationBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createNativeSpringAnimation(propertyAnimations: Array<PropertyAnimationInfo>, index: number, playSequentially: boolean, args: AnimationInfo, animation: PropertyAnimationInfo, valueSource: number, finishedCallback: (cancelled?: boolean) => void) {
|
private static _createNativeSpringAnimation(propertyAnimations: Array<PropertyAnimationInfo>, index: number, playSequentially: boolean, args: AnimationInfo, animation: PropertyAnimationInfo, valueSource: "animation" | "keyframe", finishedCallback: (cancelled?: boolean) => void) {
|
||||||
|
|
||||||
let nativeView = <UIView>animation.target._nativeView;
|
let nativeView = <UIView>animation.target._nativeView;
|
||||||
|
|
||||||
@ -591,7 +587,7 @@ export class Animation extends AnimationBase {
|
|||||||
export function _getTransformMismatchErrorMessage(view: View): string {
|
export function _getTransformMismatchErrorMessage(view: View): string {
|
||||||
// Order is important: translate, rotate, scale
|
// Order is important: translate, rotate, scale
|
||||||
let result: CGAffineTransform = CGAffineTransformIdentity;
|
let result: CGAffineTransform = CGAffineTransformIdentity;
|
||||||
result = CGAffineTransformTranslate(result, view.translateX || 0, view.translateY || 0);
|
result = CGAffineTransformTranslate(result, Length.toDevicePixels(view.translateX || 0, 0), Length.toDevicePixels(view.translateY || 0, 0));
|
||||||
result = CGAffineTransformRotate(result, (view.rotate || 0) * Math.PI / 180);
|
result = CGAffineTransformRotate(result, (view.rotate || 0) * Math.PI / 180);
|
||||||
result = CGAffineTransformScale(result, view.scaleX || 1, view.scaleY || 1);
|
result = CGAffineTransformScale(result, view.scaleX || 1, view.scaleY || 1);
|
||||||
let viewTransform = NSStringFromCGAffineTransform(result);
|
let viewTransform = NSStringFromCGAffineTransform(result);
|
||||||
|
@ -5,7 +5,18 @@ import {
|
|||||||
KeyframeAnimation as KeyframeAnimationDefinition
|
KeyframeAnimation as KeyframeAnimationDefinition
|
||||||
} from "ui/animation/keyframe-animation";
|
} from "ui/animation/keyframe-animation";
|
||||||
|
|
||||||
import { View, unsetValue } from "ui/core/view";
|
import {
|
||||||
|
View,
|
||||||
|
backgroundColorProperty,
|
||||||
|
scaleXProperty,
|
||||||
|
scaleYProperty,
|
||||||
|
translateXProperty,
|
||||||
|
translateYProperty,
|
||||||
|
rotateProperty,
|
||||||
|
opacityProperty,
|
||||||
|
unsetValue,
|
||||||
|
Color
|
||||||
|
} from "ui/core/view";
|
||||||
import { Animation } from "ui/animation";
|
import { Animation } from "ui/animation";
|
||||||
|
|
||||||
export class KeyframeDeclaration implements KeyframeDeclarationDefinition {
|
export class KeyframeDeclaration implements KeyframeDeclarationDefinition {
|
||||||
@ -30,8 +41,20 @@ export class KeyframeAnimationInfo implements KeyframeAnimationInfoDefinition {
|
|||||||
public keyframes: Array<KeyframeInfo>;
|
public keyframes: Array<KeyframeInfo>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Keyframe {
|
||||||
|
backgroundColor?: Color;
|
||||||
|
scale?: { x: number, y: number };
|
||||||
|
translate?: { x: number, y: number };
|
||||||
|
rotate?: number;
|
||||||
|
opacity?: number;
|
||||||
|
valueSource?: "keyframe" | "animation";
|
||||||
|
duration?: number;
|
||||||
|
curve?: any;
|
||||||
|
forceLayer?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
||||||
public animations: Array<Object>;
|
public animations: Array<Keyframe>;
|
||||||
public delay: number = 0;
|
public delay: number = 0;
|
||||||
public iterations: number = 1;
|
public iterations: number = 1;
|
||||||
|
|
||||||
@ -43,7 +66,7 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
|||||||
private _target: View;
|
private _target: View;
|
||||||
|
|
||||||
public static keyframeAnimationFromInfo(info: KeyframeAnimationInfo) {
|
public static keyframeAnimationFromInfo(info: KeyframeAnimationInfo) {
|
||||||
let animations = new Array<Object>();
|
let animations = new Array<Keyframe>();
|
||||||
let length = info.keyframes.length;
|
let length = info.keyframes.length;
|
||||||
let startDuration = 0;
|
let startDuration = 0;
|
||||||
if (info.isReverse) {
|
if (info.isReverse) {
|
||||||
@ -81,7 +104,7 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static parseKeyframe(info: KeyframeAnimationInfo, keyframe: KeyframeInfo, animations: Array<Object>, startDuration: number): number {
|
private static parseKeyframe(info: KeyframeAnimationInfo, keyframe: KeyframeInfo, animations: Array<Object>, startDuration: number): number {
|
||||||
let animation = {};
|
let animation: Keyframe = {};
|
||||||
for (let declaration of keyframe.declarations) {
|
for (let declaration of keyframe.declarations) {
|
||||||
animation[declaration.property] = declaration.value;
|
animation[declaration.property] = declaration.value;
|
||||||
}
|
}
|
||||||
@ -93,9 +116,10 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
|||||||
duration = (info.duration * duration) - startDuration;
|
duration = (info.duration * duration) - startDuration;
|
||||||
startDuration += duration;
|
startDuration += duration;
|
||||||
}
|
}
|
||||||
animation["duration"] = info.isReverse ? info.duration - duration : duration;
|
animation.duration = info.isReverse ? info.duration - duration : duration;
|
||||||
animation["curve"] = keyframe.curve;
|
animation.curve = keyframe.curve;
|
||||||
animation["forceLayer"] = true;
|
animation.forceLayer = true;
|
||||||
|
animation.valueSource = "keyframe";
|
||||||
animations.push(animation);
|
animations.push(animation);
|
||||||
return startDuration;
|
return startDuration;
|
||||||
}
|
}
|
||||||
@ -153,21 +177,21 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
|||||||
let animation = this.animations[0];
|
let animation = this.animations[0];
|
||||||
|
|
||||||
if ("backgroundColor" in animation) {
|
if ("backgroundColor" in animation) {
|
||||||
view.style[`css-background-color`] = animation["backgroundColor"];
|
view.style[backgroundColorProperty.keyframe] = animation.backgroundColor;
|
||||||
}
|
}
|
||||||
if ("scale" in animation) {
|
if ("scale" in animation) {
|
||||||
view.style["css-scaleX"] = animation["scale"].x;
|
view.style[scaleXProperty.keyframe] = animation.scale.x;
|
||||||
view.style["css-scaleY"] = animation["scale"].y;
|
view.style[scaleYProperty.keyframe] = animation.scale.y;
|
||||||
}
|
}
|
||||||
if ("translate" in animation) {
|
if ("translate" in animation) {
|
||||||
view.style["css-translateX"] = animation["translate"].x;
|
view.style[translateXProperty.keyframe] = animation.translate.x;
|
||||||
view.style["css-translateY"] = animation["translate"].y;
|
view.style[translateYProperty.keyframe] = animation.translate.y;
|
||||||
}
|
}
|
||||||
if ("rotate" in animation) {
|
if ("rotate" in animation) {
|
||||||
view.style["css-rotate"] = animation["rotate"];
|
view.style[rotateProperty.keyframe] = animation.rotate;
|
||||||
}
|
}
|
||||||
if ("opacity" in animation) {
|
if ("opacity" in animation) {
|
||||||
view.style["css-opacity"] = animation["opacity"];
|
view.style[opacityProperty.keyframe] = animation.opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => this.animate(view, 1, iterations), 1);
|
setTimeout(() => this.animate(view, 1, iterations), 1);
|
||||||
@ -212,21 +236,21 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
|||||||
|
|
||||||
private _resetAnimationValues(view: View, animation: Object) {
|
private _resetAnimationValues(view: View, animation: Object) {
|
||||||
if ("backgroundColor" in animation) {
|
if ("backgroundColor" in animation) {
|
||||||
view.style[`css-background-color`] = unsetValue;
|
view.style[backgroundColorProperty.keyframe] = unsetValue;
|
||||||
}
|
}
|
||||||
if ("scale" in animation) {
|
if ("scale" in animation) {
|
||||||
view.style["css-scaleX"] = animation["scale"].x;
|
view.style[scaleXProperty.keyframe] = unsetValue;
|
||||||
view.style["css-scaleY"] = animation["scale"].y;
|
view.style[scaleYProperty.keyframe] = unsetValue;
|
||||||
}
|
}
|
||||||
if ("translate" in animation) {
|
if ("translate" in animation) {
|
||||||
view.style["css-translateX"] = animation["translate"].x;
|
view.style[translateXProperty.keyframe] = unsetValue;
|
||||||
view.style["css-translateY"] = animation["translate"].y;
|
view.style[translateYProperty.keyframe] = unsetValue;
|
||||||
}
|
}
|
||||||
if ("rotate" in animation) {
|
if ("rotate" in animation) {
|
||||||
view.style["css-rotate"] = animation["rotate"];
|
view.style[rotateProperty.keyframe] = unsetValue;
|
||||||
}
|
}
|
||||||
if ("opacity" in animation) {
|
if ("opacity" in animation) {
|
||||||
view.style["css-opacity"] = animation["opacity"];
|
view.style[opacityProperty.keyframe] = unsetValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,6 +9,9 @@ export const unsetValue: any = new Object();
|
|||||||
|
|
||||||
let symbolPropertyMap = {};
|
let symbolPropertyMap = {};
|
||||||
let cssSymbolPropertyMap = {};
|
let cssSymbolPropertyMap = {};
|
||||||
|
|
||||||
|
let cssSymbolResetMap = {};
|
||||||
|
|
||||||
let inheritableProperties = new Array<InheritedProperty<any, any>>();
|
let inheritableProperties = new Array<InheritedProperty<any, any>>();
|
||||||
let inheritableCssProperties = new Array<InheritedCssProperty<any, any>>();
|
let inheritableCssProperties = new Array<InheritedCssProperty<any, any>>();
|
||||||
|
|
||||||
@ -35,7 +38,8 @@ const enum ValueSource {
|
|||||||
Default = 0,
|
Default = 0,
|
||||||
Inherited = 1,
|
Inherited = 1,
|
||||||
Css = 2,
|
Css = 2,
|
||||||
Local = 3
|
Local = 3,
|
||||||
|
Keyframe = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<U>, definitions.Property<T, U> {
|
export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<U>, definitions.Property<T, U> {
|
||||||
@ -359,7 +363,7 @@ export class CssProperty<T extends Style, U> implements definitions.CssProperty<
|
|||||||
const name = options.name;
|
const name = options.name;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
this.cssName = `css-${options.cssName}`;
|
this.cssName = `css:${options.cssName}`;
|
||||||
this.cssLocalName = options.cssName;
|
this.cssLocalName = options.cssName;
|
||||||
|
|
||||||
const key = Symbol(name + ":propertyKey");
|
const key = Symbol(name + ":propertyKey");
|
||||||
@ -541,6 +545,106 @@ export class CssProperty<T extends Style, U> implements definitions.CssProperty<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CssAnimationProperty<T extends Style, U> {
|
||||||
|
public readonly name: string;
|
||||||
|
public readonly cssName: string;
|
||||||
|
|
||||||
|
public readonly native: symbol;
|
||||||
|
public readonly register: (cls: { prototype }) => void;
|
||||||
|
|
||||||
|
public readonly keyframe: string;
|
||||||
|
public readonly defaultValueKey: symbol;
|
||||||
|
|
||||||
|
constructor(private options: definitions.CssAnimationPropertyOptions<T, U>) {
|
||||||
|
const { valueConverter, equalityComparer, valueChanged, defaultValue } = options;
|
||||||
|
const propertyName = options.name;
|
||||||
|
this.name = propertyName;
|
||||||
|
this.cssName = (options.cssName || propertyName);
|
||||||
|
|
||||||
|
const cssName = "css:" + (options.cssName || propertyName);
|
||||||
|
const keyframeName = "keyframe:" + propertyName;
|
||||||
|
this.keyframe = keyframeName;
|
||||||
|
const defaultName = "default:" + propertyName;
|
||||||
|
|
||||||
|
const defaultValueKey = Symbol(defaultName);
|
||||||
|
this.defaultValueKey = defaultValueKey;
|
||||||
|
|
||||||
|
const cssValue = Symbol(cssName);
|
||||||
|
const styleValue = Symbol(propertyName);
|
||||||
|
const keyframeValue = Symbol(keyframeName);
|
||||||
|
const computedValue = Symbol("computed-value:" + propertyName);
|
||||||
|
const computedSource = Symbol("computed-source:" + propertyName);
|
||||||
|
|
||||||
|
const native = this.native = Symbol("native:" + propertyName);
|
||||||
|
const eventName = propertyName + "Change";
|
||||||
|
|
||||||
|
function descriptor(symbol: symbol, propertySource: ValueSource, enumerable: boolean, configurable: boolean, getsComputed: boolean): PropertyDescriptor {
|
||||||
|
return { enumerable, configurable,
|
||||||
|
get: getsComputed ? function(this: T) { return this[computedValue]; } : function(this: T) { return this[symbol]; },
|
||||||
|
set(this: T, value: U) {
|
||||||
|
let prev = this[computedValue];
|
||||||
|
if (value === unsetValue) {
|
||||||
|
this[symbol] = unsetValue;
|
||||||
|
if (this[computedSource] == propertySource) {
|
||||||
|
// Fallback to lower value source.
|
||||||
|
if (this[styleValue] !== unsetValue) {
|
||||||
|
this[computedSource] = ValueSource.Local;
|
||||||
|
this[computedValue] = this[styleValue];
|
||||||
|
} else if (this[cssValue] !== unsetValue) {
|
||||||
|
this[computedSource] = ValueSource.Css;
|
||||||
|
this[computedValue] = this[cssValue];
|
||||||
|
} else {
|
||||||
|
this[computedSource] = ValueSource.Default;
|
||||||
|
this[computedValue] = defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (valueConverter && typeof value === "string") {
|
||||||
|
value = valueConverter(value);
|
||||||
|
}
|
||||||
|
this[symbol] = value;
|
||||||
|
if (this[computedSource] <= propertySource) {
|
||||||
|
this[computedSource] = propertySource;
|
||||||
|
this[computedValue] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let next = this[computedValue];
|
||||||
|
if (prev !== next && (!equalityComparer || !equalityComparer(prev, next))) {
|
||||||
|
valueChanged && valueChanged(this, prev, next);
|
||||||
|
this.view.nativeView && (this.view[native] = next);
|
||||||
|
this.hasListeners(eventName) && this.notify({ eventName, object: this, propertyName, value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultPropertyDescriptor = descriptor(defaultValueKey, ValueSource.Default, false, false, false);
|
||||||
|
const cssPropertyDescriptor = descriptor(cssValue, ValueSource.Css, false, false, false);
|
||||||
|
const stylePropertyDescriptor = descriptor(styleValue, ValueSource.Local, true, true, true);
|
||||||
|
const keyframePropertyDescriptor = descriptor(keyframeValue, ValueSource.Keyframe, false, false, false);
|
||||||
|
|
||||||
|
cssSymbolResetMap[cssValue] = cssName;
|
||||||
|
cssSymbolResetMap[keyframeValue] = keyframeName;
|
||||||
|
|
||||||
|
symbolPropertyMap[computedValue] = this;
|
||||||
|
|
||||||
|
this.register = (cls: { prototype: T }) => {
|
||||||
|
cls.prototype[defaultValueKey] = options.defaultValue;
|
||||||
|
cls.prototype[computedValue] = options.defaultValue;
|
||||||
|
cls.prototype[computedSource] = ValueSource.Default;
|
||||||
|
|
||||||
|
cls.prototype[cssValue] = unsetValue;
|
||||||
|
cls.prototype[styleValue] = unsetValue;
|
||||||
|
cls.prototype[keyframeValue] = unsetValue;
|
||||||
|
|
||||||
|
Object.defineProperty(cls.prototype, defaultName, defaultPropertyDescriptor);
|
||||||
|
Object.defineProperty(cls.prototype, cssName, cssPropertyDescriptor);
|
||||||
|
Object.defineProperty(cls.prototype, propertyName, stylePropertyDescriptor);
|
||||||
|
Object.defineProperty(cls.prototype, keyframeName, keyframePropertyDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U> implements definitions.InheritedCssProperty<T, U> {
|
export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U> implements definitions.InheritedCssProperty<T, U> {
|
||||||
public setInheritedValue: (value: U) => void;
|
public setInheritedValue: (value: U) => void;
|
||||||
|
|
||||||
@ -690,7 +794,7 @@ export class ShorthandProperty<T extends Style, P> implements definitions.Shorth
|
|||||||
const key = Symbol(this.name + ":propertyKey");
|
const key = Symbol(this.name + ":propertyKey");
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
|
||||||
this.cssName = `css-${options.cssName}`;
|
this.cssName = `css:${options.cssName}`;
|
||||||
this.cssLocalName = `${options.cssName}`;
|
this.cssLocalName = `${options.cssName}`;
|
||||||
|
|
||||||
const converter = options.converter;
|
const converter = options.converter;
|
||||||
@ -872,12 +976,12 @@ export function clearInheritedProperties(view: ViewBase): void {
|
|||||||
export function resetCSSProperties(style: Style): void {
|
export function resetCSSProperties(style: Style): void {
|
||||||
let symbols = (<any>Object).getOwnPropertySymbols(style);
|
let symbols = (<any>Object).getOwnPropertySymbols(style);
|
||||||
for (let symbol of symbols) {
|
for (let symbol of symbols) {
|
||||||
const cssProperty = cssSymbolPropertyMap[symbol];
|
let cssProperty;
|
||||||
if (!cssProperty) {
|
if (cssProperty = cssSymbolPropertyMap[symbol]) {
|
||||||
continue;
|
style[cssProperty.cssName] = unsetValue;
|
||||||
|
} else if (cssProperty = cssSymbolResetMap[symbol]) {
|
||||||
|
style[cssProperty] = unsetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
style[cssProperty.cssName] = unsetValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { Source } from "utils/debug";
|
|||||||
import { Background } from "ui/styling/background";
|
import { Background } from "ui/styling/background";
|
||||||
import {
|
import {
|
||||||
ViewBase, getEventOrGestureName, EventData, Style, unsetValue,
|
ViewBase, getEventOrGestureName, EventData, Style, unsetValue,
|
||||||
Property, CssProperty, ShorthandProperty, InheritedCssProperty,
|
Property, CssProperty, CssAnimationProperty, ShorthandProperty, InheritedCssProperty,
|
||||||
gestureFromString, isIOS, traceEnabled, traceWrite, traceCategories, makeParser, makeValidator
|
gestureFromString, isIOS, traceEnabled, traceWrite, traceCategories, makeParser, makeValidator
|
||||||
} from "./view-base";
|
} from "./view-base";
|
||||||
import { observe as gestureObserve, GesturesObserver, GestureTypes, GestureEventData } from "ui/gestures";
|
import { observe as gestureObserve, GesturesObserver, GestureTypes, GestureEventData } from "ui/gestures";
|
||||||
@ -426,17 +426,17 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
|||||||
this.style.rotate = value;
|
this.style.rotate = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
get translateX(): number {
|
get translateX(): Length {
|
||||||
return this.style.translateX;
|
return this.style.translateX;
|
||||||
}
|
}
|
||||||
set translateX(value: number) {
|
set translateX(value: Length) {
|
||||||
this.style.translateX = value;
|
this.style.translateX = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
get translateY(): number {
|
get translateY(): Length {
|
||||||
return this.style.translateY;
|
return this.style.translateY;
|
||||||
}
|
}
|
||||||
set translateY(value: number) {
|
set translateY(value: Length) {
|
||||||
this.style.translateY = value;
|
this.style.translateY = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1352,19 +1352,19 @@ function convertToPaddings(this: void, value: string | Length): [CssProperty<any
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const rotateProperty = new CssProperty<Style, number>({ name: "rotate", cssName: "rotate", defaultValue: 0, valueConverter: (v) => parseFloat(v) });
|
export const rotateProperty = new CssAnimationProperty<Style, number>({ name: "rotate", cssName: "rotate", defaultValue: 0, valueConverter: parseFloat });
|
||||||
rotateProperty.register(Style);
|
rotateProperty.register(Style);
|
||||||
|
|
||||||
export const scaleXProperty = new CssProperty<Style, number>({ name: "scaleX", cssName: "scaleX", defaultValue: 1, valueConverter: (v) => parseFloat(v) });
|
export const scaleXProperty = new CssAnimationProperty<Style, number>({ name: "scaleX", cssName: "scaleX", defaultValue: 1, valueConverter: parseFloat });
|
||||||
scaleXProperty.register(Style);
|
scaleXProperty.register(Style);
|
||||||
|
|
||||||
export const scaleYProperty = new CssProperty<Style, number>({ name: "scaleY", cssName: "scaleY", defaultValue: 1, valueConverter: (v) => parseFloat(v) });
|
export const scaleYProperty = new CssAnimationProperty<Style, number>({ name: "scaleY", cssName: "scaleY", defaultValue: 1, valueConverter: parseFloat });
|
||||||
scaleYProperty.register(Style);
|
scaleYProperty.register(Style);
|
||||||
|
|
||||||
export const translateXProperty = new CssProperty<Style, number>({ name: "translateX", cssName: "translateX", defaultValue: 0, valueConverter: (v) => parseFloat(v) });
|
export const translateXProperty = new CssAnimationProperty<Style, Length>({ name: "translateX", cssName: "translateX", defaultValue: 0, valueConverter: Length.parse, equalityComparer: Length.equals });
|
||||||
translateXProperty.register(Style);
|
translateXProperty.register(Style);
|
||||||
|
|
||||||
export const translateYProperty = new CssProperty<Style, number>({ name: "translateY", cssName: "translateY", defaultValue: 0, valueConverter: (v) => parseFloat(v) });
|
export const translateYProperty = new CssAnimationProperty<Style, Length>({ name: "translateY", cssName: "translateY", defaultValue: 0, valueConverter: Length.parse, equalityComparer: Length.equals });
|
||||||
translateYProperty.register(Style);
|
translateYProperty.register(Style);
|
||||||
|
|
||||||
const transformProperty = new ShorthandProperty<Style, string>({
|
const transformProperty = new ShorthandProperty<Style, string>({
|
||||||
@ -1545,7 +1545,7 @@ export const backgroundImageProperty = new CssProperty<Style, string>({
|
|||||||
});
|
});
|
||||||
backgroundImageProperty.register(Style);
|
backgroundImageProperty.register(Style);
|
||||||
|
|
||||||
export const backgroundColorProperty = new CssProperty<Style, Color>({
|
export const backgroundColorProperty = new CssAnimationProperty<Style, Color>({
|
||||||
name: "backgroundColor", cssName: "background-color", valueChanged: (target, oldValue, newValue) => {
|
name: "backgroundColor", cssName: "background-color", valueChanged: (target, oldValue, newValue) => {
|
||||||
let background = target.backgroundInternal;
|
let background = target.backgroundInternal;
|
||||||
target.backgroundInternal = background.withColor(newValue);
|
target.backgroundInternal = background.withColor(newValue);
|
||||||
@ -1929,7 +1929,7 @@ function opacityConverter(value: any): number {
|
|||||||
throw new Error(`Opacity should be between [0, 1]. Value: ${newValue}`);
|
throw new Error(`Opacity should be between [0, 1]. Value: ${newValue}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const opacityProperty = new CssProperty<Style, number>({ name: "opacity", cssName: "opacity", defaultValue: 1, valueConverter: opacityConverter });
|
export const opacityProperty = new CssAnimationProperty<Style, number>({ name: "opacity", cssName: "opacity", defaultValue: 1, valueConverter: opacityConverter });
|
||||||
opacityProperty.register(Style);
|
opacityProperty.register(Style);
|
||||||
|
|
||||||
export const colorProperty = new InheritedCssProperty<Style, Color>({ name: "color", cssName: "color", equalityComparer: Color.equals, valueConverter: (v) => new Color(v) });
|
export const colorProperty = new InheritedCssProperty<Style, Color>({ name: "color", cssName: "color", equalityComparer: Color.equals, valueConverter: (v) => new Color(v) });
|
||||||
|
@ -389,18 +389,18 @@ export class View extends ViewCommon {
|
|||||||
org.nativescript.widgets.ViewHelper.setScaleY(this.nativeView, float(value));
|
org.nativescript.widgets.ViewHelper.setScaleY(this.nativeView, float(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
get [translateXProperty.native](): number {
|
get [translateXProperty.native](): Length | number {
|
||||||
return org.nativescript.widgets.ViewHelper.getTranslateX(this.nativeView);
|
return org.nativescript.widgets.ViewHelper.getTranslateX(this.nativeView);
|
||||||
}
|
}
|
||||||
set [translateXProperty.native](value: number) {
|
set [translateXProperty.native](value: Length) {
|
||||||
org.nativescript.widgets.ViewHelper.setTranslateX(this.nativeView, float(value));
|
org.nativescript.widgets.ViewHelper.setTranslateX(this.nativeView, Length.toDevicePixels(value, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get [translateYProperty.native](): number {
|
get [translateYProperty.native](): Length | number {
|
||||||
return org.nativescript.widgets.ViewHelper.getTranslateY(this.nativeView);
|
return org.nativescript.widgets.ViewHelper.getTranslateY(this.nativeView);
|
||||||
}
|
}
|
||||||
set [translateYProperty.native](value: number) {
|
set [translateYProperty.native](value: Length) {
|
||||||
org.nativescript.widgets.ViewHelper.setTranslateY(this.nativeView, float(value));
|
org.nativescript.widgets.ViewHelper.setTranslateY(this.nativeView, Length.toDevicePixels(value, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get [zIndexProperty.native](): number {
|
get [zIndexProperty.native](): number {
|
||||||
|
20
tns-core-modules/ui/core/view.d.ts
vendored
20
tns-core-modules/ui/core/view.d.ts
vendored
@ -1,7 +1,7 @@
|
|||||||
declare module "ui/core/view" {
|
declare module "ui/core/view" {
|
||||||
import { GestureTypes, GesturesObserver, GestureEventData, TouchGestureEventData, TouchAction } from "ui/gestures";
|
import { GestureTypes, GesturesObserver, GestureEventData, TouchGestureEventData, TouchAction } from "ui/gestures";
|
||||||
import {
|
import {
|
||||||
ViewBase, Property, CssProperty, InheritedCssProperty, Style, EventData, ShorthandProperty
|
ViewBase, Property, CssProperty, CssAnimationProperty, InheritedCssProperty, Style, EventData, ShorthandProperty
|
||||||
} from "ui/core/view-base";
|
} from "ui/core/view-base";
|
||||||
import { Background } from "ui/styling/background";
|
import { Background } from "ui/styling/background";
|
||||||
import { Font, FontWeight, FontStyle } from "ui/styling/font";
|
import { Font, FontWeight, FontStyle } from "ui/styling/font";
|
||||||
@ -293,12 +293,12 @@ declare module "ui/core/view" {
|
|||||||
/**
|
/**
|
||||||
* Gets or sets the translateX affine transform of the view.
|
* Gets or sets the translateX affine transform of the view.
|
||||||
*/
|
*/
|
||||||
translateX: number;
|
translateX: Length;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the translateY affine transform of the view.
|
* Gets or sets the translateY affine transform of the view.
|
||||||
*/
|
*/
|
||||||
translateY: number;
|
translateY: Length;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the scaleX affine transform of the view.
|
* Gets or sets the scaleX affine transform of the view.
|
||||||
@ -702,16 +702,16 @@ declare module "ui/core/view" {
|
|||||||
export const isEnabledProperty: Property<View, boolean>;
|
export const isEnabledProperty: Property<View, boolean>;
|
||||||
export const isUserInteractionEnabledProperty: Property<View, boolean>;
|
export const isUserInteractionEnabledProperty: Property<View, boolean>;
|
||||||
|
|
||||||
export const rotateProperty: CssProperty<Style, number>;
|
export const rotateProperty: CssAnimationProperty<Style, number>;
|
||||||
export const scaleXProperty: CssProperty<Style, number>;
|
export const scaleXProperty: CssAnimationProperty<Style, number>;
|
||||||
export const scaleYProperty: CssProperty<Style, number>;
|
export const scaleYProperty: CssAnimationProperty<Style, number>;
|
||||||
export const translateXProperty: CssProperty<Style, number>;
|
export const translateXProperty: CssAnimationProperty<Style, Length>;
|
||||||
export const translateYProperty: CssProperty<Style, number>;
|
export const translateYProperty: CssAnimationProperty<Style, Length>;
|
||||||
|
|
||||||
export const clipPathProperty: CssProperty<Style, string>;
|
export const clipPathProperty: CssProperty<Style, string>;
|
||||||
export const colorProperty: InheritedCssProperty<Style, Color>;
|
export const colorProperty: InheritedCssProperty<Style, Color>;
|
||||||
|
|
||||||
export const backgroundColorProperty: CssProperty<Style, Color>;
|
export const backgroundColorProperty: CssAnimationProperty<Style, Color>;
|
||||||
export const backgroundImageProperty: CssProperty<Style, string>;
|
export const backgroundImageProperty: CssProperty<Style, string>;
|
||||||
export const backgroundRepeatProperty: CssProperty<Style, BackgroundRepeat>;
|
export const backgroundRepeatProperty: CssProperty<Style, BackgroundRepeat>;
|
||||||
export const backgroundSizeProperty: CssProperty<Style, string>;
|
export const backgroundSizeProperty: CssProperty<Style, string>;
|
||||||
@ -737,7 +737,7 @@ declare module "ui/core/view" {
|
|||||||
|
|
||||||
export const zIndexProperty: CssProperty<Style, number>;
|
export const zIndexProperty: CssProperty<Style, number>;
|
||||||
export const visibilityProperty: CssProperty<Style, Visibility>;
|
export const visibilityProperty: CssProperty<Style, Visibility>;
|
||||||
export const opacityProperty: CssProperty<Style, number>;
|
export const opacityProperty: CssAnimationProperty<Style, number>;
|
||||||
|
|
||||||
export const minWidthProperty: CssProperty<Style, Length>;
|
export const minWidthProperty: CssProperty<Style, Length>;
|
||||||
export const minHeightProperty: CssProperty<Style, Length>;
|
export const minHeightProperty: CssProperty<Style, Length>;
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
ViewCommon, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty, visibilityProperty, opacityProperty,
|
ViewCommon, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty, visibilityProperty, opacityProperty,
|
||||||
rotateProperty, scaleXProperty, scaleYProperty,
|
rotateProperty, scaleXProperty, scaleYProperty,
|
||||||
translateXProperty, translateYProperty, zIndexProperty, backgroundInternalProperty,
|
translateXProperty, translateYProperty, zIndexProperty, backgroundInternalProperty,
|
||||||
clipPathProperty, layout, traceEnabled, traceWrite, traceCategories, Background, Visibility
|
clipPathProperty, layout, traceEnabled, traceWrite, traceCategories, Background, Visibility, Length
|
||||||
} from "./view-common";
|
} from "./view-common";
|
||||||
|
|
||||||
export * from "./view-common";
|
export * from "./view-common";
|
||||||
@ -232,8 +232,8 @@ export class View extends ViewCommon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public updateNativeTransform() {
|
public updateNativeTransform() {
|
||||||
let translateX = this.translateX || 0;
|
let translateX = Length.toDevicePixels(this.translateX || 0, 0);
|
||||||
let translateY = this.translateY || 0;
|
let translateY = Length.toDevicePixels(this.translateY || 0, 0);
|
||||||
let scaleX = this.scaleX || 1;
|
let scaleX = this.scaleX || 1;
|
||||||
let scaleY = this.scaleY || 1;
|
let scaleY = this.scaleY || 1;
|
||||||
let rotate = this.rotate || 0;
|
let rotate = this.rotate || 0;
|
||||||
@ -363,17 +363,17 @@ export class View extends ViewCommon {
|
|||||||
this.updateNativeTransform();
|
this.updateNativeTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
get [translateXProperty.native](): number {
|
get [translateXProperty.native](): Length | number {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
set [translateXProperty.native](value: number) {
|
set [translateXProperty.native](value: Length) {
|
||||||
this.updateNativeTransform();
|
this.updateNativeTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
get [translateYProperty.native](): number {
|
get [translateYProperty.native](): Length | number {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
set [translateYProperty.native](value: number) {
|
set [translateYProperty.native](value: Length) {
|
||||||
this.updateNativeTransform();
|
this.updateNativeTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
21
tns-core-modules/ui/definitions.d.ts
vendored
21
tns-core-modules/ui/definitions.d.ts
vendored
@ -217,6 +217,27 @@ declare module "ui/core/properties" {
|
|||||||
readonly cssName: string;
|
readonly cssName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CssAnimationPropertyOptions<T, U> {
|
||||||
|
readonly name: string;
|
||||||
|
readonly cssName?: string;
|
||||||
|
readonly defaultValue?: U;
|
||||||
|
readonly equalityComparer?: (x: U, y: U) => boolean;
|
||||||
|
readonly valueChanged?: (target: T, oldValue: U, newValue: U) => void;
|
||||||
|
readonly valueConverter?: (value: string) => U;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CssAnimationProperty<T extends Style, U> {
|
||||||
|
constructor(options: CssAnimationPropertyOptions<T, U>);
|
||||||
|
|
||||||
|
public readonly name: string;
|
||||||
|
public readonly cssName: string;
|
||||||
|
public readonly native: symbol;
|
||||||
|
|
||||||
|
readonly keyframe: string;
|
||||||
|
|
||||||
|
public register(cls: { prototype: T }): void;
|
||||||
|
}
|
||||||
|
|
||||||
export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<U> {
|
export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<U> {
|
||||||
constructor(options: PropertyOptions<T, U>);
|
constructor(options: PropertyOptions<T, U>);
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ imageSourceProperty.register(ImageBase);
|
|||||||
export const srcProperty = new Property<ImageBase, any>({ name: "src"});
|
export const srcProperty = new Property<ImageBase, any>({ name: "src"});
|
||||||
srcProperty.register(ImageBase);
|
srcProperty.register(ImageBase);
|
||||||
|
|
||||||
export const loadModeProperty = new Property<ImageBase, "sync" | "async">({ name: "loadMode", defaultValue: "async" });
|
export const loadModeProperty = new Property<ImageBase, "sync" | "async">({ name: "loadMode", defaultValue: "sync" });
|
||||||
loadModeProperty.register(ImageBase);
|
loadModeProperty.register(ImageBase);
|
||||||
|
|
||||||
export const isLoadingProperty = new Property<ImageBase, boolean>({ name: "isLoading", defaultValue: false, valueConverter: booleanConverter });
|
export const isLoadingProperty = new Property<ImageBase, boolean>({ name: "isLoading", defaultValue: false, valueConverter: booleanConverter });
|
||||||
|
@ -25,9 +25,12 @@ export class Image extends ImageBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setTintColor(value: Color) {
|
private setTintColor(value: Color) {
|
||||||
if (value !== null && this._ios.image && !this._templateImageWasCreated) {
|
if (value && this._ios.image && !this._templateImageWasCreated) {
|
||||||
this._ios.image = this._ios.image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
|
this._ios.image = this._ios.image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
|
||||||
this._templateImageWasCreated = true;
|
this._templateImageWasCreated = true;
|
||||||
|
} else if (this._ios.image && this._templateImageWasCreated) {
|
||||||
|
this._templateImageWasCreated = false;
|
||||||
|
this._ios.image = this._ios.image.imageWithRenderingMode(UIImageRenderingMode.Automatic);
|
||||||
}
|
}
|
||||||
this._ios.tintColor = value ? value.ios : null;
|
this._ios.tintColor = value ? value.ios : null;
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ export class CssState {
|
|||||||
let style = view.style;
|
let style = view.style;
|
||||||
ruleset.declarations.forEach(d => {
|
ruleset.declarations.forEach(d => {
|
||||||
try {
|
try {
|
||||||
// Use the "css-" prefixed name, so that CSS value source is set.
|
// Use the "css:" prefixed name, so that CSS value source is set.
|
||||||
let cssPropName = `css-${d.property}`;
|
let cssPropName = `css:${d.property}`;
|
||||||
if (cssPropName in style) {
|
if (cssPropName in style) {
|
||||||
style[cssPropName] = d.value;
|
style[cssPropName] = d.value;
|
||||||
} else {
|
} else {
|
||||||
|
4
tns-core-modules/ui/styling/style.d.ts
vendored
4
tns-core-modules/ui/styling/style.d.ts
vendored
@ -46,8 +46,8 @@ declare module "ui/styling/style" {
|
|||||||
public rotate: number;
|
public rotate: number;
|
||||||
public scaleX: number;
|
public scaleX: number;
|
||||||
public scaleY: number;
|
public scaleY: number;
|
||||||
public translateX: number;
|
public translateX: Length;
|
||||||
public translateY: number;
|
public translateY: Length;
|
||||||
|
|
||||||
public clipPath: string;
|
public clipPath: string;
|
||||||
public color: Color;
|
public color: Color;
|
||||||
|
Reference in New Issue
Block a user