diff --git a/ui/animation/animation-common.ts b/ui/animation/animation-common.ts index dd58ce806..5a461e57c 100644 --- a/ui/animation/animation-common.ts +++ b/ui/animation/animation-common.ts @@ -27,6 +27,21 @@ export interface PropertyAnimation { curve?: any; } +export class CubicBezierAnimationCurve implements definition.CubicBezierAnimationCurve { + + public x1: number; + public y1: number; + public x2: number; + public y2: number; + + constructor(x1: number, y1: number, x2: number, y2: number) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + } +} + export class Animation implements definition.Animation { public _propertyAnimations: Array; public _playSequentially: boolean; @@ -98,7 +113,7 @@ export class Animation implements definition.Animation { } var propertyAnimations = new Array(); - + // opacity if (animationDefinition.opacity !== undefined) { propertyAnimations.push({ diff --git a/ui/animation/animation.android.ts b/ui/animation/animation.android.ts index cf5c4648a..b669327d3 100644 --- a/ui/animation/animation.android.ts +++ b/ui/animation/animation.android.ts @@ -26,7 +26,7 @@ propertyKeys[common.Properties.translate] = Symbol(keyPrefix + common.Properties export class Animation extends common.Animation implements definition.Animation { private _animatorListener: android.animation.Animator.AnimatorListener; private _nativeAnimatorsArray: any; - private _animatorSet: android.animation.AnimatorSet; + private _animatorSet: android.animation.AnimatorSet; private _animators: Array; private _propertyUpdateCallbacks: Array; private _propertyResetCallbacks: Array; @@ -102,7 +102,7 @@ export class Animation extends common.Animation implements definition.Animation // It has been cancelled return; } - + var i = 0; var length = this._propertyUpdateCallbacks.length; for (; i < length; i++) { @@ -145,7 +145,7 @@ export class Animation extends common.Animation implements definition.Animation var density = utils.layout.getDisplayDensity(); var xyObjectAnimators: any; var animatorSet: android.animation.AnimatorSet; - + var key = propertyKeys[propertyAnimation.property]; if (key) { propertyAnimation.target[key] = propertyAnimation; @@ -158,7 +158,7 @@ export class Animation extends common.Animation implements definition.Animation } } } - + switch (propertyAnimation.property) { case common.Properties.opacity: @@ -270,7 +270,7 @@ export class Animation extends common.Animation implements definition.Animation var i = 0; var length = animators.length; for (; i < length; i++) { - + // Duration if (propertyAnimation.duration !== undefined) { animators[i].setDuration(propertyAnimation.duration); @@ -281,7 +281,7 @@ export class Animation extends common.Animation implements definition.Animation animators[i].setStartDelay(propertyAnimation.delay); } - // Repeat Count + // Repeat Count if (propertyAnimation.iterations !== undefined && animators[i] instanceof android.animation.ValueAnimator) { (animators[i]).setRepeatCount(Animation._getAndroidRepeatCount(propertyAnimation.iterations)); } @@ -307,6 +307,7 @@ var easeIn = new android.view.animation.AccelerateInterpolator(1); var easeOut = new android.view.animation.DecelerateInterpolator(1); var easeInOut = new android.view.animation.AccelerateDecelerateInterpolator(); var linear = new android.view.animation.LinearInterpolator(); +var bounce = new android.view.animation.BounceInterpolator(); export function _resolveAnimationCurve(curve: any): any { switch (curve) { case enums.AnimationCurve.easeIn: @@ -321,8 +322,16 @@ export function _resolveAnimationCurve(curve: any): any { case enums.AnimationCurve.linear: trace.write("Animation curve resolved to android.view.animation.LinearInterpolator().", trace.categories.Animation); return linear; + case enums.AnimationCurve.spring: + trace.write("Animation curve resolved to android.view.animation.BounceInterpolator().", trace.categories.Animation); + return bounce; default: trace.write("Animation curve resolved to original: " + curve, trace.categories.Animation); + if (curve instanceof common.CubicBezierAnimationCurve) { + var animationCurve = curve; + var interpolator = (android).support.v4.view.animation.PathInterpolatorCompat.create(animationCurve.x1, animationCurve.y1, animationCurve.x2, animationCurve.y2); + return interpolator; + } return curve; } } diff --git a/ui/animation/animation.d.ts b/ui/animation/animation.d.ts index 028ece8b8..a8d4925ce 100644 --- a/ui/animation/animation.d.ts +++ b/ui/animation/animation.d.ts @@ -7,10 +7,10 @@ */ export interface AnimationDefinition { /** - * The view whose property is to be animated. + * The view whose property is to be animated. */ target?: viewModule.View; - + /** * Animates the opacity of the view. Value should be a number between 0.0 and 1.0 */ @@ -35,24 +35,24 @@ * Animates the rotate affine transform of the view. Value should be a number specifying the rotation amount in degrees. */ rotate?: number; - + /** * The length of the animation in milliseconds. The default duration is 300 milliseconds. */ duration?: number; /** - * The amount of time, in milliseconds, to delay starting the animation. + * The amount of time, in milliseconds, to delay starting the animation. */ delay?: number; - + /** * Specifies how many times the animation should be played. Default is 1. * iOS animations support fractional iterations, i.e. 1.5. * To repeat an animation infinitely, use Number.POSITIVE_INFINITY */ iterations?: number; - + /** * An optional animation curve. Possible values are contained in the [AnimationCurve enumeration](../enums/AnimationCurve/README.md). * Alternatively, you can pass an instance of type UIViewAnimationCurve for iOS or android.animation.TimeInterpolator for Android. @@ -60,6 +60,20 @@ curve?: any; } + /** + * Defines a custom animation timing curve by using the cubic-bezier function. + * Possible values are numeric values from 0 to 1 + */ + export class CubicBezierAnimationCurve { + + public x1: number; + public y1: number; + public x2: number; + public y2: number; + + constructor(x1: number, y1: number, x2: number, y2: number); + } + /** * Defines a pair of values (horizontal and vertical) for translate and scale animations. */ @@ -81,4 +95,4 @@ //@private export function _resolveAnimationCurve(curve: any): any; //@endprivate -} \ No newline at end of file +} diff --git a/ui/animation/animation.ios.ts b/ui/animation/animation.ios.ts index c6d4295c2..3b9736eb6 100644 --- a/ui/animation/animation.ios.ts +++ b/ui/animation/animation.ios.ts @@ -11,6 +11,18 @@ var _skip = "_skip"; var FLT_MAX = 340282346638528859811704183484516925440.000000; +declare var CASpringAnimation:any; + +class AnimationInfo +{ + public propertyNameToAnimate: string; + public fromValue: any; + public toValue: any; + public duration: number; + public repeatCount: number; + public delay: number; +} + class AnimationDelegateImpl extends NSObject { public nextAnimation: Function; @@ -55,21 +67,18 @@ class AnimationDelegateImpl extends NSObject { } (this._propertyAnimation.target)._resumePresentationLayerUpdates(); - } - public animationDidStopFinished(anim: CAAnimation, flag: boolean): void { + public animationDidStopFinished(anim: CAAnimation, finished: boolean): void { if (this._finishedCallback) { - var cancelled = !flag; - // This could either be the master finishedCallback or an nextAnimationCallback depending on the playSequentially argument values. - this._finishedCallback(cancelled); + this._finishedCallback(!finished); } - if (!flag) { + if (!finished) { if ((this._propertyAnimation)._propertyResetCallback) { (this._propertyAnimation)._propertyResetCallback((this._propertyAnimation)._originalValue); } } - if (flag && this.nextAnimation) { + if (finished && this.nextAnimation) { this.nextAnimation(); } } @@ -83,10 +92,8 @@ export class Animation extends common.Animation implements definition.Animation public play(): Promise { var animationFinishedPromise = super.play(); - this._finishedAnimations = 0; this._cancelledAnimations = 0; - this._iOSAnimationFunction(); return animationFinishedPromise; } @@ -139,151 +146,265 @@ export class Animation extends common.Animation implements definition.Animation } }; - this._iOSAnimationFunction = Animation._createiOSAnimationFunction(this._mergedPropertyAnimations, 0, this._playSequentially, animationFinishedCallback, this); + this._iOSAnimationFunction = Animation._createiOSAnimationFunction(this._mergedPropertyAnimations, 0, this._playSequentially, animationFinishedCallback); } - private static _createiOSAnimationFunction(propertyAnimations: Array, index: number, playSequentially: boolean, finishedCallback: (cancelled?: boolean) => void, that:Animation): Function { + private static _createiOSAnimationFunction(propertyAnimations: Array, index: number, playSequentially: boolean, finishedCallback: (cancelled?: boolean) => void): Function { return (cancelled?: boolean) => { + if (cancelled && finishedCallback) { trace.write("Animation " + (index - 1).toString() + " was cancelled. Will skip the rest of animations and call finishedCallback(true).", trace.categories.Animation); finishedCallback(cancelled); return; } + var animation = propertyAnimations[index]; - var nativeView = animation.target._nativeView; - var propertyNameToAnimate = animation.property; - var value = animation.value; - var originalValue; - var presentationLayer = nativeView.layer.presentationLayer(); - var tempRotate = animation.target.rotate * Math.PI / 180; - var abs + var args = Animation._getNativeAnimationArguments(animation); - switch (animation.property) { - case common.Properties.backgroundColor: - (animation)._originalValue = animation.target.backgroundColor; - (animation)._propertyResetCallback = (value) => { animation.target.backgroundColor = value }; - if (presentationLayer != null) { - originalValue = presentationLayer.backgroundColor; - } - else { - originalValue = nativeView.layer.backgroundColor; - } - value = value.CGColor; - break; - case common.Properties.opacity: - (animation)._originalValue = animation.target.opacity; - (animation)._propertyResetCallback = (value) => { animation.target.opacity = value }; - if (presentationLayer != null) { - originalValue = presentationLayer.opacity; - } - else { - originalValue = nativeView.layer.opacity; - } - break; - case common.Properties.rotate: - (animation)._originalValue = animation.target.rotate; - (animation)._propertyResetCallback = (value) => { animation.target.rotate = value }; - propertyNameToAnimate = "transform.rotation"; - if (presentationLayer != null) { - originalValue = presentationLayer.valueForKeyPath("transform.rotation"); - } - else { - originalValue = nativeView.layer.valueForKeyPath("transform.rotation"); - } - value = value * Math.PI / 180; - abs = fabs(originalValue - value); - if (abs < 0.001 && originalValue !== tempRotate) { - originalValue = tempRotate; - } - break; - case common.Properties.translate: - (animation)._originalValue = { x:animation.target.translateX, y:animation.target.translateY }; - (animation)._propertyResetCallback = (value) => { animation.target.translateX = value.x; animation.target.translateY = value.y; }; - propertyNameToAnimate = "transform" - if (presentationLayer != null) { - originalValue = NSValue.valueWithCATransform3D(presentationLayer.transform); - } - else { - originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform); - } - value = NSValue.valueWithCATransform3D(CATransform3DTranslate(nativeView.layer.transform, value.x, value.y, 0)); - break; - case common.Properties.scale: - (animation)._originalValue = { x:animation.target.scaleX, y:animation.target.scaleY }; - (animation)._propertyResetCallback = (value) => { animation.target.scaleX = value.x; animation.target.scaleY = value.y; }; - propertyNameToAnimate = "transform" - if (presentationLayer != null) { - originalValue = NSValue.valueWithCATransform3D(presentationLayer.transform); - } - else { - originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform); - } - value = NSValue.valueWithCATransform3D(CATransform3DScale(nativeView.layer.transform, value.x, value.y, 1)); - break; - case _transform: - if (presentationLayer != null) { - originalValue = NSValue.valueWithCATransform3D(presentationLayer.transform); - } - else { - originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform); - } - (animation)._originalValue = { xs:animation.target.scaleX, ys:animation.target.scaleY, - xt:animation.target.translateX, yt:animation.target.translateY }; - (animation)._propertyResetCallback = (value) => { - animation.target.translateX = value.xt; - animation.target.translateY = value.yt; - animation.target.scaleX = value.xs; - animation.target.scaleY = value.ys; - }; - propertyNameToAnimate = "transform" - value = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation)); - break; - default: - throw new Error("Cannot animate " + animation.property); - } - - var nativeAnimation = CABasicAnimation.animationWithKeyPath(propertyNameToAnimate); - nativeAnimation.fromValue = originalValue; - nativeAnimation.toValue = value; - if (animation.duration !== undefined) { - nativeAnimation.duration = animation.duration / 1000.0; + if (animation.curve === enums.AnimationCurve.spring) { + Animation._createNativeSpringAnimation(propertyAnimations, index, playSequentially, args, animation, finishedCallback); } else { - nativeAnimation.duration = 0.3; - }; - if (animation.delay !== undefined) { - nativeAnimation.beginTime = CACurrentMediaTime() + (animation.delay / 1000.0); + Animation._createNativeAnimation(propertyAnimations, index, playSequentially, args, animation, finishedCallback); } + } + } - if (animation.iterations !== undefined) { - if (animation.iterations === Number.POSITIVE_INFINITY) { - nativeAnimation.repeatCount = FLT_MAX; - } - else { - nativeAnimation.repeatCount = animation.iterations - 1; - } - } - if (animation.curve !== undefined) { - trace.write("The animation curve is " + animation.curve, trace.categories.Animation); - nativeAnimation.timingFunction = animation.curve; - } + private static _getNativeAnimationArguments(animation: common.PropertyAnimation): AnimationInfo { - var animationDelegate: AnimationDelegateImpl = AnimationDelegateImpl.initWithFinishedCallback(finishedCallback, animation); - nativeAnimation.setValueForKey(animationDelegate, "delegate"); + var nativeView = animation.target._nativeView; + var presentationLayer = nativeView.layer.presentationLayer(); + var propertyNameToAnimate = animation.property; + var value = animation.value; + var originalValue; - nativeView.layer.addAnimationForKey(nativeAnimation, propertyNameToAnimate); + var tempRotate = animation.target.rotate * Math.PI / 180; + var abs - var callback = undefined; - if (index+1 < propertyAnimations.length) { - callback = Animation._createiOSAnimationFunction(propertyAnimations, index+1, playSequentially, finishedCallback, that); - if (!playSequentially) { - callback(); - } - else { - animationDelegate.nextAnimation = callback; - } + switch (animation.property) { + case common.Properties.backgroundColor: + (animation)._originalValue = animation.target.backgroundColor; + (animation)._propertyResetCallback = (value) => { animation.target.backgroundColor = value }; + if (presentationLayer != null) { + originalValue = presentationLayer.backgroundColor; + } + else { + originalValue = nativeView.layer.backgroundColor; + } + if (nativeView instanceof UILabel) { + originalValue = nativeView.layer.backgroundColor; + nativeView.setValueForKey(UIColor.clearColor(), "backgroundColor"); + } + value = value.CGColor; + break; + case common.Properties.opacity: + (animation)._originalValue = animation.target.opacity; + (animation)._propertyResetCallback = (value) => { animation.target.opacity = value }; + if (presentationLayer != null) { + originalValue = presentationLayer.opacity; + } + else { + originalValue = nativeView.layer.opacity; + } + break; + case common.Properties.rotate: + (animation)._originalValue = animation.target.rotate; + (animation)._propertyResetCallback = (value) => { animation.target.rotate = value }; + propertyNameToAnimate = "transform.rotation"; + if (presentationLayer != null) { + originalValue = presentationLayer.valueForKeyPath("transform.rotation"); + } + else { + originalValue = nativeView.layer.valueForKeyPath("transform.rotation"); + } + value = value * Math.PI / 180; + abs = fabs(originalValue - value); + if (abs < 0.001 && originalValue !== tempRotate) { + originalValue = tempRotate; + } + break; + case common.Properties.translate: + (animation)._originalValue = { x:animation.target.translateX, y:animation.target.translateY }; + (animation)._propertyResetCallback = (value) => { animation.target.translateX = value.x; animation.target.translateY = value.y; }; + propertyNameToAnimate = "transform" + if (presentationLayer != null) { + originalValue = NSValue.valueWithCATransform3D(presentationLayer.transform); + } + else { + originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform); + } + value = NSValue.valueWithCATransform3D(CATransform3DTranslate(nativeView.layer.transform, value.x, value.y, 0)); + break; + case common.Properties.scale: + (animation)._originalValue = { x:animation.target.scaleX, y:animation.target.scaleY }; + (animation)._propertyResetCallback = (value) => { animation.target.scaleX = value.x; animation.target.scaleY = value.y; }; + propertyNameToAnimate = "transform" + if (presentationLayer != null) { + originalValue = NSValue.valueWithCATransform3D(presentationLayer.transform); + } + else { + originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform); + } + value = NSValue.valueWithCATransform3D(CATransform3DScale(nativeView.layer.transform, value.x, value.y, 1)); + break; + case _transform: + if (presentationLayer != null) { + originalValue = NSValue.valueWithCATransform3D(presentationLayer.transform); + } + else { + originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform); + } + (animation)._originalValue = { xs:animation.target.scaleX, ys:animation.target.scaleY, + xt:animation.target.translateX, yt:animation.target.translateY }; + (animation)._propertyResetCallback = (value) => { + animation.target.translateX = value.xt; + animation.target.translateY = value.yt; + animation.target.scaleX = value.xs; + animation.target.scaleY = value.ys; + }; + propertyNameToAnimate = "transform" + value = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation)); + break; + default: + throw new Error("Cannot animate " + animation.property); + } + + var duration = 0.3; + if (animation.duration !== undefined) { + duration = animation.duration / 1000.0; + } + + var delay = undefined; + if (animation.delay) { + delay = animation.delay / 1000.0; + } + + var repeatCount = undefined; + if (animation.iterations !== undefined) { + if (animation.iterations === Number.POSITIVE_INFINITY) { + repeatCount = FLT_MAX; + } + else { + repeatCount = animation.iterations - 1; } } + + return { + propertyNameToAnimate: propertyNameToAnimate, + fromValue: originalValue, + toValue: value, + duration: duration, + repeatCount: repeatCount, + delay: delay + }; + } + + private static _createNativeAnimation(propertyAnimations: Array, index: number, playSequentially: boolean, args: AnimationInfo, animation: common.PropertyAnimation, finishedCallback: (cancelled?: boolean) => void) { + + var nativeView = animation.target._nativeView; + var nativeAnimation = CABasicAnimation.animationWithKeyPath(args.propertyNameToAnimate); + nativeAnimation.fromValue = args.fromValue; + nativeAnimation.toValue = args.toValue; + nativeAnimation.duration = args.duration; + if (args.repeatCount !== undefined) { + nativeAnimation.repeatCount = args.repeatCount; + } + if (args.delay !== undefined) { + nativeAnimation.beginTime = CACurrentMediaTime() + args.delay; + } + if (animation.curve !== undefined) { + nativeAnimation.timingFunction = animation.curve; + } + + var animationDelegate = AnimationDelegateImpl.initWithFinishedCallback(finishedCallback, animation); + nativeAnimation.setValueForKey(animationDelegate, "delegate"); + + nativeView.layer.addAnimationForKey(nativeAnimation, args.propertyNameToAnimate); + + var callback = undefined; + if (index+1 < propertyAnimations.length) { + callback = Animation._createiOSAnimationFunction(propertyAnimations, index+1, playSequentially, finishedCallback); + if (!playSequentially) { + callback(); + } + else { + animationDelegate.nextAnimation = callback; + } + } + } + + private static _createNativeSpringAnimation(propertyAnimations: Array, index: number, playSequentially: boolean, args: AnimationInfo, animation: common.PropertyAnimation, finishedCallback: (cancelled?: boolean) => void) { + + var nativeView = animation.target._nativeView; + + var callback = undefined; + var nextAnimation; + if (index + 1 < propertyAnimations.length) { + callback = Animation._createiOSAnimationFunction(propertyAnimations, index + 1, playSequentially, finishedCallback); + if (!playSequentially) { + callback(); + } + else { + nextAnimation = callback; + } + } + + var delay = 0; + if (args.delay) { + delay = args.delay; + } + + UIView.animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion(args.duration, delay, 0.2, 0, + UIViewKeyframeAnimationOptions.UIViewKeyframeAnimationOptionCalculationModeLinear, + () => { + if (args.repeatCount !== undefined) { + UIView.setAnimationRepeatCount(args.repeatCount); + } + + switch (animation.property) { + case common.Properties.backgroundColor: + animation.target.backgroundColor = args.toValue; + break; + case common.Properties.opacity: + animation.target.opacity = args.toValue; + break; + case common.Properties.rotate: + nativeView.layer.setValueForKey(args.toValue, args.propertyNameToAnimate); + break; + case _transform: + (animation)._originalValue = nativeView.layer.transform; + nativeView.layer.setValueForKey(args.toValue, args.propertyNameToAnimate); + (animation)._propertyResetCallback = function (value) { + nativeView.layer.transform = value; + } + break; + } + }, function (finished:boolean) { + if (finished) { + if (animation.property === _transform) { + if (animation.value[common.Properties.translate] !== undefined) { + animation.target.translateX = animation.value[common.Properties.translate].x; + animation.target.translateY = animation.value[common.Properties.translate].y; + } + if (animation.value[common.Properties.scale] !== undefined) { + animation.target.scaleX = animation.value[common.Properties.scale].x; + animation.target.scaleY = animation.value[common.Properties.scale].y; + } + } + } + else { + if ((animation)._propertyResetCallback) { + (animation)._propertyResetCallback((animation)._originalValue); + } + } + if (finishedCallback) { + var cancelled = !finished; + finishedCallback(cancelled); + } + if (finished && nextAnimation) { + nextAnimation(); + } + }); } private static _createNativeAffineTransform(animation: common.PropertyAnimation): CATransform3D { @@ -353,8 +474,10 @@ export class Animation extends common.Animation implements definition.Animation value: {}, duration: propertyAnimations[i].duration, delay: propertyAnimations[i].delay, - iterations: propertyAnimations[i].iterations + iterations: propertyAnimations[i].iterations, + curve: propertyAnimations[i].curve }; + trace.write("Curve: " + propertyAnimations[i].curve, trace.categories.Animation); newTransformAnimation.value[propertyAnimations[i].property] = propertyAnimations[i].value; trace.write("Created new transform animation: " + common.Animation._getAnimationInfo(newTransformAnimation), trace.categories.Animation); @@ -388,7 +511,16 @@ export function _resolveAnimationCurve(curve: any): any { return CAMediaTimingFunction.functionWithName(kCAMediaTimingFunctionEaseInEaseOut); case enums.AnimationCurve.linear: return CAMediaTimingFunction.functionWithName(kCAMediaTimingFunctionLinear); + case enums.AnimationCurve.spring: + return curve; default: + if (curve instanceof CAMediaTimingFunction) { + return curve; + } + else if (curve instanceof common.CubicBezierAnimationCurve) { + var animationCurve = curve; + return CAMediaTimingFunction.functionWithControlPoints(animationCurve.x1, animationCurve.y1, animationCurve.x2, animationCurve.y2); + } return undefined; } } diff --git a/ui/enums/enums.d.ts b/ui/enums/enums.d.ts index 36a370753..a800d2fd9 100644 --- a/ui/enums/enums.d.ts +++ b/ui/enums/enums.d.ts @@ -1,5 +1,7 @@ declare module "ui/enums" { + import animationModule = require("ui/animation"); + /** * Represents a soft keyboard flavor. */ @@ -9,25 +11,25 @@ * iOS: [UIKeyboardTypeNumbersAndPunctuation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIKeyboardType) */ export var datetime: string; - + /** * Android: [TYPE_CLASS_PHONE](http://developer.android.com/reference/android/text/InputType.html#TYPE_CLASS_PHONE) * iOS: [UIKeyboardTypePhonePad](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIKeyboardType) */ export var phone: string; - + /** * Android: [TYPE_CLASS_NUMBER](http://developer.android.com/reference/android/text/InputType.html#TYPE_CLASS_NUMBER) | android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL | [TYPE_NUMBER_FLAG_SIGNED](http://developer.android.com/reference/android/text/InputType.html#TYPE_NUMBER_FLAG_SIGNED) | [TYPE_NUMBER_FLAG_DECIMAL](http://developer.android.com/reference/android/text/InputType.html#TYPE_NUMBER_FLAG_DECIMAL) * iOS: [UIKeyboardTypeNumbersAndPunctuation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIKeyboardType) */ export var number: string; - + /** * Android: [TYPE_CLASS_TEXT](http://developer.android.com/reference/android/text/InputType.html#TYPE_CLASS_TEXT) | [TYPE_TEXT_VARIATION_URI](http://developer.android.com/reference/android/text/InputType.html#TYPE_TEXT_VARIATION_URI) * iOS: [UIKeyboardTypeURL](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIKeyboardType) */ export var url: string; - + /** * Android: [TYPE_CLASS_TEXT](http://developer.android.com/reference/android/text/InputType.html#TYPE_CLASS_TEXT) | [TYPE_TEXT_VARIATION_EMAIL_ADDRESS](http://developer.android.com/reference/android/text/InputType.html#TYPE_TEXT_VARIATION_EMAIL_ADDRESS) * iOS: [UIKeyboardTypeEmailAddress](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIKeyboardType) @@ -56,13 +58,13 @@ * iOS: [UIReturnKeyGo](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIReturnKeyType) */ export var go: string; - + /** * Android: [IME_ACTION_SEARCH](http://developer.android.com/reference/android/view/inputmethod/EditorInfo.html#IME_ACTION_SEARCH) * iOS: [UIReturnKeySearch](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIReturnKeyType) */ export var search: string; - + /** * Android: [IME_ACTION_SEND](http://developer.android.com/reference/android/view/inputmethod/EditorInfo.html#IME_ACTION_SEND) * iOS: [UIReturnKeySend](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/index.html#//apple_ref/c/tdef/UIReturnKeyType) @@ -324,17 +326,17 @@ export var none: string; /** - * Capitalize the first letter of each word automatically. + * Capitalize the first letter of each word automatically. */ export var words: string; /** - * Capitalize the first letter of each sentence automatically. + * Capitalize the first letter of each sentence automatically. */ export var sentences: string; - + /** - * Capitalize all characters automatically. + * Capitalize all characters automatically. */ export var allCharacters: string; } @@ -402,7 +404,7 @@ */ export var popup: string; } - + /** * Specifies different font styles. */ @@ -411,7 +413,7 @@ * Normal font style. */ export var normal: string; - + /** * Italic font style. */ @@ -426,7 +428,7 @@ * No decoration. */ export var none: string; - + /** * Text decoration underline. */ @@ -446,7 +448,7 @@ * No transform. */ export var none: string; - + /** * Text transform capitalize. */ @@ -456,7 +458,7 @@ * Text transform uppercase. */ export var uppercase: string; - + /** * Text transform lowercase. */ @@ -471,13 +473,13 @@ * Normal wrap. */ export var normal: string; - + /** * No wrap. */ export var nowrap: string; } - + /** * Specifies different font weights. */ @@ -486,13 +488,13 @@ * Normal font weight. */ export var normal: string; - + /** * Bold font weight. */ export var bold: string; } - + /** * Specifies background repeat. */ @@ -522,6 +524,7 @@ * Represents an animation curve type. */ module AnimationCurve { + /** * An ease-in curve causes the animation to begin slowly, and then speed up as it progresses. */ @@ -536,10 +539,20 @@ * An ease-in ease-out curve causes the animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing. */ export var easeInOut: string; - + /** * A linear animation curve causes an animation to occur evenly over its duration. */ export var linear: string; + + /** + * A spring animation curve causes an animation to produce a spring (bounce) effect. + */ + export var spring: string; + + /** + * A custom cubic bezier function defined by its two control points. Possible values are numeric values from 0 to 1 + */ + export function cubicBezier(x1: number, y1: number, x2: number, y2: number): animationModule.CubicBezierAnimationCurve; } -} \ No newline at end of file +} diff --git a/ui/enums/enums.ts b/ui/enums/enums.ts index 5fe522f3d..09c974880 100644 --- a/ui/enums/enums.ts +++ b/ui/enums/enums.ts @@ -1,4 +1,6 @@ -export module KeyboardType { +import animationModule = require("ui/animation"); + +export module KeyboardType { export var datetime = "datetime"; export var phone = "phone"; export var number = "number"; @@ -162,4 +164,8 @@ export module AnimationCurve { export var easeOut = "easeOut"; export var easeInOut = "easeInOut"; export var linear = "linear"; -} \ No newline at end of file + export var spring = "spring"; + export function cubicBezier(x1: number, y1: number, x2: number, y2: number): animationModule.CubicBezierAnimationCurve { + return new animationModule.CubicBezierAnimationCurve(x1, y1 ,x2, y2); + } +}