diff --git a/img/modules/animation/hello-world.gif b/img/modules/animation/hello-world.gif
new file mode 100644
index 000000000..dab9031ad
Binary files /dev/null and b/img/modules/animation/hello-world.gif differ
diff --git a/ui/animation-code.md b/ui/animation-code.md
new file mode 100644
index 000000000..9d7f57355
--- /dev/null
+++ b/ui/animation-code.md
@@ -0,0 +1,135 @@
+---
+title: Animations with Code
+description: Animated view properties by using code.
+slug: animations-code
+position: 11
+publish: false
+---
+
+# Animations with code
+
+The easiest way to animate a **single** [`View`](../ApiReference/ui/core/view/View.md) is by using the `View.animate` method which accepts an [`AnimationDefinition`](../ApiReference/ui/animation/AnimationDefinition.md), immediately starts the animation and then returns its finished promise.
+
+__Example 20: How to execute animation on single view.__
+
+``` JavaScript
+view.animate({
+ translate: { x: 0, y: 100},
+ duration: 1000,
+ curve: enums.AnimationCurve.easeIn
+});
+```
+``` TypeScript
+view.animate({
+ translate: { x: 0, y: 100},
+ duration: 1000,
+ curve: enums.AnimationCurve.easeIn
+});
+```
+
+> You should create an [`Animation`](../ApiReference/ui/animation/Animation.md) class in order to be able to **cancel** the animation. This is demonstrated below.
+
+## The AnimationDefinition interface
+
+The [`AnimationDefinition`](../ApiReference/ui/animation/AnimationDefinition.md) interface is central for defining an animation for **one or more properties** of a **single** [`View`](../ApiReference/ui/core/view/View.md). The animatable properties are:
+
+ - **opacity**
+ - **backgroundColor**
+ - **translateX** and **translateY**
+ - **scaleX** and **scaleY**
+ - **rotate**
+
+The [`AnimationDefinition`](../ApiReference/ui/animation/AnimationDefinition.md) interface has the following members:
+
+ - **target**: The view whose property is to be animated.
+ - **opacity**: Animates the opacity of the view. Value should be a number between 0.0 and 1.0.
+ - **backgroundColor**: Animates the backgroundColor of the view.
+ - **translate**: Animates the translate affine transform of the view. Value should be a [`Pair`](../ApiReference/ui/animation/Pair.md).
+ - **scale**: Animates the scale affine transform of the view. Value should be a [`Pair`](../ApiReference/ui/animation/Pair.md).
+ - **rotate**: Animates the rotate affine transform of the view. Value should be a number specifying the rotation amount in degrees.
+ - **duration**: The length of the animation in milliseconds. The default duration is 300 milliseconds.
+ - **delay**: The amount of time, in milliseconds, to delay starting the animation.
+ - **iterations**: 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`.
+ - **curve**: An optional animation curve. Possible values are contained in the [AnimationCurve enumeration](../ApiReference/ui/enums/AnimationCurve/README.md). Alternatively, you can pass an instance of type [`UIViewAnimationCurve`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/c/tdef/UIViewAnimationCurve) for iOS or [`android.animation.TimeInterpolator`](http://developer.android.com/reference/android/animation/TimeInterpolator.html) for Android.
+
+ All members of the interface are **optional** and have default values with the following exceptions:
+
+ - target is only optional when calling the `animate` method of a [`View`](../ApiReference/ui/core/view/View.md) instance since it is set automatically for you.
+ - You must specify at least one property from this list: opacity, backgroundColor, scale, rotate or translate.
+
+## The Animation class
+
+The [`Animation`](../ApiReference/ui/animation/Animation.md) class represents a **set** of one or more [`AnimationDefinitions`]({{site.baseurl}}/ApiReference/ui/animation/AnimationDefinition.md) that can be played either **simultaneously or sequentially**. **This class is typically used when you need to animate several views together**. The constructor of the [`Animation`](../ApiReference/ui/animation/Animation.md) class accepts an array of [`AnimationDefinitions`](../ApiReference/ui/animation/AnimationDefinition.md) and a boolean parameter indicating whether to play the animations sequentially. Creating an instance of the [`Animation`](../ApiReference/ui/animation/Animation.md) class does not start the animation playback. The class has four members:
+
+ - **play**: A method that starts the animation and returns the instance it was called on for fluent animation chaining.
+ - **cancel**: A void method that stops the animation.
+ - **finished**: A promise that will be resolved when the animation finishes or rejected when the animation is cancelled or stops for another reason.
+ - **isPlaying**: A boolean property returning __True__ if the animation is currently playing.
+
+## Animating multiple properties
+
+It is easy to animate multiple properties at once; just pass the desired animatable properties and the corresponding values when calling the animate function.
+
+__Example 21: How to animate multiple properties.__
+
+``` JavaScript
+view.animate({
+ backgroundColor: new color.Color("#3D5AFE"),
+ opacity: 0.5,
+ translate: { x: 100, y: 100 },
+ rotate: 180,
+ duration: 3000
+});
+```
+``` TypeScript
+view.animate({
+ backgroundColor: new color.Color("#3D5AFE"),
+ opacity: 0.5,
+ translate: {x: 100, y: 100},
+ rotate: 180,
+ duration: 3000
+});
+```
+
+
+
+## Chaining animations with promises
+
+The animate method returns a promise that you can use to chain animations, as shown in __Example 21__.
+
+__Example 22: How to create chain animations.__
+
+``` JavaScript
+view.animate({ opacity: 0 })
+ .then(function () { return view.animate({ opacity: 1 }); })
+ .then(function () { return view.animate({ translate: { x: 100, y: 100 } }); })
+ .then(function () { return view.animate({ translate: { x: 0, y: 0 } }); })
+ .then(function () { return view.animate({ scale: { x: 3, y: 3 } }); })
+ .then(function () { return view.animate({ scale: { x: 1, y: 1 } }); })
+ .then(function () { return view.animate({ rotate: 180 }); })
+ .then(function () { return view.animate({ rotate: 0 }); })
+ .then(function () {
+ console.log("Animation finished");
+})
+ .catch(function (e) {
+ console.log(e.message);
+});
+```
+``` TypeScript
+view.animate({ opacity: 0 })
+ .then(() => view.animate({ opacity: 1 }))
+ .then(() => view.animate({ translate: { x: 100, y: 100 } }))
+ .then(() => view.animate({ translate: { x: 0, y: 0 } }))
+ .then(() => view.animate({ scale: { x: 3, y: 3 } }))
+ .then(() => view.animate({ scale: { x: 1, y: 1 } }))
+ .then(() => view.animate({ rotate: 180 }))
+ .then(() => view.animate({ rotate: 0 }))
+ .then(() => {
+ console.log("Animation finished");
+ })
+ .catch((e) => {
+ console.log(e.message);
+ });
+```
+
+
diff --git a/ui/animation-css.md b/ui/animation-css.md
new file mode 100644
index 000000000..4b2c5a2fd
--- /dev/null
+++ b/ui/animation-css.md
@@ -0,0 +1,301 @@
+---
+title: Animations with CSS
+description: Animate view properties by using CSS stylesheets.
+slug: animation-css
+position: 10
+publish: false
+---
+
+# CSS Animations
+
+CSS animations are based on the simple and easy to use standard [CSS3 animations API](http://www.w3schools.com/css/css3_animations.asp). You can use them to animate almost every native view without even having to know JavaScript. You have the potential to alter the appearance and behavior of an element whenever a state change occurs, such as when it is touched or activated. You can use multiple frames and change the animation direction. Finally, with CSS animations, you can separate the animation code from your application logic.
+
+CSS animations consist of two components: a style describing the CSS animation and a set of keyframes that indicate the start and end states of the animation's style, as well as possible intermediate waypoints. You can change as many animatable CSS properties you want, as many times you want.
+
+__Example 1__ binds the "example" animation to the button element. The animation lasts 4 seconds. It will gradually change the background-color of the button element from "red" to "green".
+
+__Example 1: How to cerate simple animation using CSS.__
+
+``` CSS
+@keyframes example {
+ from { background-color: red; }
+ to { background-color: green; }
+}
+
+.view {
+ animation-name: example;
+ animation-duration: 4s;
+ animation-fill-mode: forwards;
+}
+```
+
+To get an animation to work, you must bind the animation to an element:
+
+``` JavaScript
+view1.className = "example";
+```
+``` TypeScript
+view1.className = "example";
+```
+``` XML
+
+```
+
+> If the **animation-duration** property is not specified, the animation will use a default value - 0.3 seconds.
+
+## Animatable properties
+
+CSS animations support the same animatable properties used in code-based animations:
+
+- **opacity**
+- **background-color**: Corresponds with the backgroundColor.
+- **transform: translate**: Corresponds with translateX and translateY properties.
+- **transform: scale**: Corresponds with scaleX and scaleY properties.
+- **transform: rotate**: Corresponds with the rotate property.
+
+> You cannot set a single x or y field in scale and translate. If you set only x in translate, y will be assumed 0; If you set only y in scale, x will be assumed 1.
+
+## Animation properties
+
+A CSS animation is defined by using the animation property and its sub-properties. Those include timing, duration, delay and other animation properties. The actual animation appearance is defined with the @keyframes rule.
+
+The following list presents all animation properties:
+
+- **animation-name**: Specifies the name of the @keyframes rule that should be used.
+- **animation-delay**: Specifies the time between the style is applied and the beginning of the animation.
+- **animation-duration**: The length of the animation in seconds.
+- **animation-iteration-count**: Specifies how many times the animation should be played. Default is 1. To repeat an animation forever, use infinite.
+- **animation-timing-function**: Defines how the animation transitions through keyframes by establishing acceleration curves.
+- **animation-fill-mode**: Configures what values are applied by the animation after it is executing.
+- **animation-direction**: Configures whether or not the animation should alternate direction on each run through the sequence or reset to the start point and repeat itself.
+- **animation**: The shorthand property allows setting all animation properties in a single line.
+
+## Animation keyframes
+
+To set multiple points at which an element should undergo a transition, use the **@keyframes** rule, shown in __Example 2__. It includes the animation name, any animation breakpoints, and the properties intended to be animated.
+
+__Example 2: How to use **@keyframes** rule.__
+
+``` CSS
+@keyframes example {
+ from { background-color: red; }
+ to { background-color: green; }
+}
+```
+
+__Example 2__ defines an animation with two keyframes. The "from" represents 0% (the start of the animation) and "to" represents 100% (the final value). You can add more keyframes by using percent.
+
+__Example 3__ shows how to change the background color when the animation is 25% complete, 50% complete, and again when the animation is 100% complete.
+
+__Example 3: Changing background color in different animation stages.__
+
+``` CSS
+@keyframes example {
+ 0% { background-color: red; }
+ 25% { background-color: yellow; }
+ 50% { background-color: blue; }
+ 100% { background-color: green; }
+}
+```
+
+You can set multiple properties in a keyframe, as shown in __Example 4__.
+
+__Example 4: Changing multiple properties in different animation stages.__
+
+``` CSS
+@keyframes example {
+ 0% { background-color: red; transform: translate(0, 0); }
+ 25% { background-color: yellow; transform: translate(200, 0); }
+ 50% { background-color: blue; transform: translate(200, 200); }
+ 75% { background-color: green; transform: translate(0, 200); }
+ 100% { background-color: red; transform: translate(0, 0); }
+}
+```
+
+You can combine keyframes, as shown in __Example 5__.
+
+__Example 5: Set up properties for several keyframes__
+
+``` CSS
+@keyframes example {
+ 0%, 50% { background-color: red; transform: translate(0, 0); }
+ 25%, 75% { background-color: yellow; transform: translate(200, 0); }
+ 100% { background-color: red; transform: translate(0, 0); }
+}
+```
+
+## Delay an animation
+
+The **animation-delay** property specifies a delay (in seconds) before the animation starts:
+
+__Example 6: Set up a dealy before the animation starts__
+
+``` CSS
+.view {
+ background-color: red;
+ animation-name: example;
+ animation-duration: 4s;
+ animation-delay: 2s;
+}
+```
+
+## Set how many times an animation should run
+
+The **animation-iteration-count** property defines the number of times an animation should run. The animation in __Example 7__ will play two times before it stops.
+
+__Example 7: How to use `animation-iteration-count` property__
+
+``` CSS
+.view {
+ background-color: red;
+ animation-name: example;
+ animation-duration: 4s;
+ animation-iteration-count: 2;
+}
+```
+
+If you want to play an animation forever, set this property to "infinite".
+
+``` CSS
+animation-iteration-count: infinite;
+```
+
+## Specify the speed curve of the animation
+
+The **animation-timing-function** property specifies the speed curve of the animation. It can have one of the following values:
+
+- **ease**: Specifies an animation with a slow start, then fast, then end slowly (this is the default).
+- **linear**: Specifies an animation with the same speed from start to end.
+- **ease-in**: Specifies an animation with a slow start.
+- **ease-out**: Specifies an animation with a slow end.
+- **ease-in-out**: Specifies an animation with a slow start and slow end.
+- **spring**: Specifies a spring animation.
+- **cubic-bezier(n,n,n,n)**: Lets you define your own values in a cubic-bezier function, as shown in __Example 8__.
+
+__Example 8: How to specify the speed curve using cubic-bezier function.__
+
+``` CSS
+.view {
+ animation-name: example;
+ animation-timing-function: cubic-bezier(0.1, 0.1, 1.0, 1.0);
+}
+```
+
+## Determine the result when the animation ends
+
+The **animation-fill-mode** property determines the element style when the animation finishes. Its default value is "none". In this case, all animated values will be reset to the state before the animation started. You should choose "forwards" in order to preserve the property values set during the animation.
+
+__Example 9: How to use **animation-fill-mode** property__
+
+``` CSS
+.view {
+ background-color: red;
+ animation-name: example;
+ animation-duration: 2s;
+ animation-fill-mode: forwards;
+}
+```
+
+## Animation direction
+
+You can use the **animation-direction** property to play a CSS animation in reverse direction, as shown in __Example 10__.
+
+__Example 10: How to reverse animation direction.__
+
+``` CSS
+.view {
+ background-color: red;
+ animation-name: example;
+ animation-duration: 4s;
+ animation-direction: reverse;
+}
+```
+
+## Animation shorthand
+
+The **animation** property allows setting all seven animation properties with a single line:
+
+__Example 11: How to use animation shorthand property__
+
+``` CSS
+.view {
+ animation: example 4s ease-in-out 2s infinite reverse forwards;
+}
+```
+
+The supported syntax is:
+
+animation: name duration timing-function delay iteration-count direction fill-mode;
+
+You can combine two animations in the **animation** property by using commas:
+
+__Example 12: How to combine several animations in the **animation** property__
+
+``` CSS
+.view {
+ animation: example 4s ease-in-out 2s infinite reverse, second-animation-example 5s ease-out;
+}
+```
+
+## Pseudo selectors
+
+A pseudo selector is used to define a special state of an element. For example, when a button is touched by the user. You can use pseudo selectors to trigger animations:
+
+__Example 13: How to trigger animation on element special state__
+
+``` CSS
+.button {
+ background-color: green;
+}
+
+.button:highlighted {
+ animation-name: highlight;
+ animation-duration: 2s;
+ animation-fill-mode: forwards;
+}
+
+@keyframes highlight {
+ from { background-color: yellow; }
+ to { background-color: red; }
+}
+```
+
+> As of version 2.0, only the **Button** component has a built-in special state "highlighted" to indicate that it is touched by the user.
+
+## Access CSS animations from code
+
+The simplest way to trigger a CSS animation is by changing the element **className** property:
+
+__Example 14: How to trigger CSS animation__
+
+```JavaScript
+var view = page.getViewById("view");
+view.className = "transparent";
+```
+```TypeScript
+let view = page.getViewById("view");
+view.className = "transparent";
+```
+
+All keyframes defined in CSS can be accessed with code by using the **getKeyframeAnimationWithName** method. This allows further customization of animation properties:
+
+__Example 15: Accesing CSS defined keyframe in the code via **getKeyframeAnimationWithName** method__
+
+``` JavaScript
+var view = page.getViewById("view");
+var animationInfo = page.getKeyframeAnimationWithName("bounce");
+animationInfo.duration = 2000;
+var keyframeAnimation = keyframeAnimation.KeyframeAnimation.keyframeAnimationFromInfo(animationInfo);
+animation.play(view).then(() => {
+ console.log("Played with code!");
+});
+```
+``` TypeScript
+let view = page.getViewById("view");
+let animationInfo = page.getKeyframeAnimationWithName("bounce");
+animationInfo.duration = 2000;
+let keyframeAnimation = keyframeAnimation.KeyframeAnimation.keyframeAnimationFromInfo(animationInfo);
+animation.play(view).then(() => {
+ console.log("Played with code!");
+});
+```
diff --git a/ui/animation-examples.md b/ui/animation-examples.md
new file mode 100644
index 000000000..a77a28719
--- /dev/null
+++ b/ui/animation-examples.md
@@ -0,0 +1,363 @@
+---
+title: Animation Examples
+description: Examples demonstrating how to animate view properties.
+position: 12
+slug: animation-examples
+publish: false
+---
+
+# Animation examples
+
+This article contains examples demonstrating how to animate the animatable view propertires. A full list of all animatable properties and a detailed explanation of the animations API is presented [here](./animation.md).
+
+The full source code for all samples is located [here](https://github.com/NativeScript/animation-demo).
+
+## Animated opacity
+
+
+
+``` JavaScript
+view.animate({
+ opacity: 0,
+ duration: 3000
+});
+```
+``` TypeScript
+view.animate({
+ opacity: 0,
+ duration: 3000
+});
+```
+``` CSS
+.view {
+ animation-name: opacity;
+ animation-duration: 3;
+}
+@keyframes opacity {
+ from { opacity: 1; }
+ to { opacity: 0; }
+}
+```
+
+## Animate background color
+
+
+
+``` JavaScript
+view.animate({
+ backgroundColor: new colorModule.Color("#3D5AFE"),
+ duration: 3000
+});
+```
+``` TypeScript
+view.animate({
+ backgroundColor: new colorModule.Color("#3D5AFE"),
+ duration: 3000
+});
+```
+``` CSS
+.view {
+ animation-name: backgroundColor;
+ animation-duration: 3;
+}
+@keyframes backgroundColor {
+ from { background-color: white; }
+ to { background-color: #3D5AFE; }
+}
+```
+
+## Animate position
+
+
+
+``` JavaScript
+view.animate({
+ translate: { x: 100, y: 100},
+ duration: 3000
+});
+```
+``` TypeScript
+view.animate({
+ translate: { x: 100, y: 100},
+ duration: 3000
+});
+```
+``` CSS
+.view {
+ animation-name: translate;
+ animation-duration: 3;
+}
+@keyframes translate {
+ from { transform: translate(0, 0); }
+ to { transform: translate(100, 100); }
+}
+```
+
+## Animate scale
+
+
+
+``` JavaScript
+view.animate({
+ scale: { x: 2, y: 2},
+ duration: 3000
+});
+```
+``` TypeScript
+view.animate({
+ scale: { x: 2, y: 2},
+ duration: 3000
+});
+```
+``` CSS
+.view {
+ animation-name: scale;
+ animation-duration: 3;
+}
+@keyframes scale {
+ from { transform: scale(1, 1); }
+ to { transform: scale(2, 2); }
+}
+```
+
+## Animate rotate
+
+
+
+``` JavaScript
+view.animate({
+ rotate: 360,
+ duration: 3000
+});
+```
+``` TypeScript
+view.animate({
+ rotate: 360,
+ duration: 3000
+});
+```
+``` CSS
+.view {
+ animation-name: rotate;
+ animation-duration: 3;
+}
+@keyframes rotate {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+```
+
+## Chaining animations with AnimationSet
+
+
+
+``` JavaScript
+var definitions = new Array();
+definitions.push({ target: view1, translate: { x: 200, y: 0 }, duration: 3000 });
+definitions.push({ target: view2, translate: { x: 0, y: 200 }, duration: 3000 });
+definitions.push({ target: view3, translate: { x: -200, y: 0 }, duration: 3000 });
+definitions.push({ target: view4, translate: { x: 0, y: -200 }, duration: 3000 });
+var playSequentially = true;
+var animationSet = new animationModule.Animation(definitions, playSequentially);
+animationSet.play().then(function () {
+ console.log("Animation finished");
+})
+ .catch(function (e) {
+ console.log(e.message);
+});
+```
+``` TypeScript
+var definitions = new Array();
+definitions.push({target: view1, translate: {x: 200, y: 0}, duration: 3000 });
+definitions.push({target: view2, translate: {x: 0, y: 200}, duration: 3000 });
+definitions.push({target: view3, translate: {x: -200, y: 0}, duration: 3000 });
+definitions.push({target: view4, translate: {x: 0, y: -200}, duration: 3000 });
+var playSequentially = true;
+var animationSet = new animationModule.Animation(definitions, playSequentially);
+animationSet.play().then(() => {
+ console.log("Animation finished");
+})
+.catch((e) => {
+ console.log(e.message);
+});
+```
+
+## Animating multiple views
+
+
+
+``` JavaScript
+var definitions = new Array();
+var a1 = {
+ target: view1,
+ translate: { x: 200, y: 0 },
+ duration: 3000
+};
+definitions.push(a1);
+var a2 = {
+ target: view2,
+ translate: { x: 0, y: 200 },
+ duration: 3000
+};
+definitions.push(a2);
+var a3 = {
+ target: view3,
+ translate: { x: -200, y: 0 },
+ duration: 3000
+};
+definitions.push(a3);
+var a4 = {
+ target: view4,
+ translate: { x: 0, y: -200 },
+ duration: 3000
+};
+definitions.push(a4);
+var animationSet = new animationModule.Animation(definitions);
+animationSet.play().then(function () {
+ console.log("Animation finished");
+})
+ .catch(function (e) {
+ console.log(e.message);
+});
+```
+``` TypeScript
+var definitions = new Array();
+var a1: animationModule.AnimationDefinition = {
+ target: view1,
+ translate: {x: 200, y: 0},
+ duration: 3000
+};
+definitions.push(a1);
+
+var a2: animationModule.AnimationDefinition = {
+ target: view2,
+ translate: {x: 0, y: 200},
+ duration: 3000
+};
+definitions.push(a2);
+
+var a3: animationModule.AnimationDefinition = {
+ target: view3,
+ translate: {x: -200, y: 0},
+ duration: 3000
+};
+definitions.push(a3);
+
+var a4: animationModule.AnimationDefinition = {
+ target: view4,
+ translate: {x: 0, y: -200},
+ duration: 3000
+};
+definitions.push(a4);
+
+var animationSet = new animationModule.Animation(definitions);
+
+animationSet.play().then(() => {
+ console.log("Animation finished");
+})
+.catch((e) => {
+ console.log(e.message);
+});
+```
+
+## Reusing animations
+
+
+
+``` JavaScript
+var animation1 = view.createAnimation({ opacity: 0 });
+var animation2 = view.createAnimation({ opacity: 1 });
+animation1.play()
+ .then(function () { return animation2.play(); })
+ .then(function () { return animation1.play(); })
+ .then(function () { return animation2.play(); })
+ .then(function () { return animation1.play(); })
+ .then(function () { return animation2.play(); })
+ .then(function () {
+ console.log("Animation finished");
+})
+ .catch(function (e) {
+ console.log(e.message);
+});
+```
+``` TypeScript
+var animation1 = view.createAnimation({opacity: 0});
+var animation2 = view.createAnimation({opacity: 1});
+
+animation1.play()
+.then(()=>animation2.play())
+.then(()=>animation1.play())
+.then(()=>animation2.play())
+.then(()=>animation1.play())
+.then(()=>animation2.play())
+.then(() => {
+ console.log("Animation finished");
+})
+.catch((e) => {
+ console.log(e.message);
+});
+```
+
+## Slide-in effect
+
+
+
+``` JavaScript
+var item = new imageModule.Image();
+item.src = "~/res/icon_100x100.png";
+item.width = 90;
+item.height = 90;
+item.style.margin = "5,5,5,5";
+item.translateX = -300;
+item.opacity = 0;
+item.on("loaded", function (args) {
+ args.object.animate({ translate: { x: 0, y: 0 }, opacity: 1 });
+});
+wrapLayout.addChild(item);
+```
+``` TypeScript
+var item = new imageModule.Image();
+item.src = "~/res/icon_100x100.png";
+item.width = 90;
+item.height = 90;
+item.style.margin = "5,5,5,5";
+item.translateX = -300;
+item.opacity = 0;
+item.on("loaded", (args: observable.EventData) => {
+ (args.object).animate({translate: { x: 0, y: 0 }, opacity: 1});
+});
+wrapLayout.addChild(item);
+```
+
+## Infinite animations
+
+
+
+``` JavaScript
+animationSet = new animationModule.Animation([{
+ target: view,
+ rotate: 360,
+ duration: 3000,
+ iterations: Number.POSITIVE_INFINITY,
+ curve: view.ios ? UIViewAnimationCurve.UIViewAnimationCurveLinear : new android.view.animation.LinearInterpolator
+ }]);
+animationSet.play().catch(function (e) {
+ console.log("Animation stoppped!");
+});
+// Call animationSet.cancel() to stop it;
+```
+``` TypeScript
+animationSet = new animationModule.Animation([{
+ target: view,
+ rotate: 360,
+ duration: 3000,
+ iterations: Number.POSITIVE_INFINITY,
+ curve: view.ios ? UIViewAnimationCurve.UIViewAnimationCurveLinear : new android.view.animation.LinearInterpolator
+}]);
+animationSet.play().catch((e) => {
+ console.log("Animation stoppped!");
+});
+// Call animationSet.cancel() to stop it;
+```
+
+
diff --git a/ui/animation.md b/ui/animation.md
index 346650017..c190ec48b 100644
--- a/ui/animation.md
+++ b/ui/animation.md
@@ -6,70 +6,89 @@ slug: animations
previous_url: /animation
---
-# Animation API
-
-## AnimationDefinition Interface
-The [`AnimationDefinition`]({{site.baseurl}}/ApiReference/ui/animation/AnimationDefinition.md) interface is central for defining an animation for **one or more properties** of a **single** [`View`]({{site.baseurl}}/ApiReference/ui/core/view/View.md). The animatable properties are:
- - opacity
- - backgroundColor
- - translateX and translateY
- - scaleX and scaleY
- - rotate
-
-The [`AnimationDefinition`]({{site.baseurl}}/ApiReference/ui/animation/AnimationDefinition.md) interface has the following members:
- - target: The view whose property is to be animated.
- - opacity: Animates the opacity of the view. Value should be a number between 0.0 and 1.0.
- - backgroundColor: Animates the backgroundColor of the view.
- - translate: Animates the translate affine transform of the view. Value should be a [`Pair`]({{site.baseurl}}/ApiReference/ui/animation/Pair.md).
- - scale: Animates the scale affine transform of the view. Value should be a [`Pair`]({{site.baseurl}}/ApiReference/ui/animation/Pair.md).
- - rotate: Animates the rotate affine transform of the view. Value should be a number specifying the rotation amount in degrees.
- - duration: The length of the animation in milliseconds. The default duration is 300 milliseconds.
- - delay: The amount of time, in milliseconds, to delay starting the animation.
- - iterations: 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
- - curve: An optional animation curve. Possible values are contained in the [AnimationCurve enumeration]({{site.baseurl}}/ApiReference/ui/enums/AnimationCurve/README.md). Alternatively, you can pass an instance of type [`UIViewAnimationCurve`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/c/tdef/UIViewAnimationCurve) for iOS or [`android.animation.TimeInterpolator`](http://developer.android.com/reference/android/animation/TimeInterpolator.html) for Android.
-
- All members of the interface are **optional** and have default values with the following exceptions:
- - target is only optional when calling the **animate** method of a [`View`]({{site.baseurl}}/ApiReference/ui/core/view/View.md) instance since it is set automatically for you.
- - You must specify at least one property among opacity, backgroundColor, scale, rotate and translate.
-
-## Animation Class
-The [`Animation`]({{site.baseurl}}/ApiReference/ui/animation/Animation.md) class represents a **set** of one or more [`AnimationDefinitions`]({{site.baseurl}}/ApiReference/ui/animation/AnimationDefinition.md) which can be played either **simultaneously or sequentially**. **This class is typically used when you need to animate several views together**. The constructor of the the [`Animation`]({{site.baseurl}}/ApiReference/ui/animation/Animation.md) class accepts an array of [`AnimationDefinitions`]({{site.baseurl}}/ApiReference/ui/animation/AnimationDefinition.md) and a boolean parameter indicating whether to play the animations sequentially. Creating an instance of the [`Animation`]({{site.baseurl}}/ApiReference/ui/animation/Animation.md) class does not start the animation playback. The class has four members:
- - play: a method that starts the animation and returns the instance it was called on for fluent animation chaining.
- - cancel: a void method which stops the animation.
- - finished: a promise which will be resolved when the animation finishes or rejected when the animation is cancelled or stops for another reason.
- - isPlaying: a boolean property returning true if the animation is currently playing.
-
-## View.animate Method
-In case you need to animate a **single** [`View`]({{site.baseurl}}/ApiReference/ui/core/view/View.md) and you don't need to be able to **cancel** the animation, you can simply use the shortcut **View.animate** method which accepts an [`AnimationDefinition`]({{site.baseurl}}/ApiReference/ui/animation/AnimationDefinition.md), immediately starts the animation and returns its finished promise.
-
-## Animation curves
-
-By default the animation moves with a linear speed without acceleration or deceleration. This might look unnatural and different from the real world where objects need time to reach their top speed and can't stop immediately. The animation curve (called sometimes easing function) is used to give animations an illusion of inertia. It controls the animation speed by modifying the fraction of the duration. NativeScript comes with a number of predefined animation curves:
-
-- The simplest animation curve is linear. It maintains a constant speed while the animation is running:
+# Animations
-
+One of the ways to improve the attractiveness of your application is by adding animations. NativeScript exposes a simple and easy, but powerful enough API to allow animating almost every native element in your application.
-- The ease-in curve causes the animation to begin slowly, and then speed up as it progresses.
+For your convenience, we expose two ways of creating animations:
-
+- [Declarative](./animation-css.md) - you will use the easy and familiar CSS3 animations API
+- [Imperative](./animation-code.md) - take full control of any animation by calling animation methods directly with code
-- An ease-out curve causes the animation to begin quickly, and then slow down as it completes.
+[Here](./animation-examples.md) you wlll find a detailed set of examples demonstating the different animations that can be achieved with NativeScript.
-
+##Hello world example
+In __Example 1__ we will change the background color of a button from "red" to "green". You can use JavaScript or TypeScript code to do the following:
-- 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.
+__Example 1: Changing background color animation with code.__
-
+
+
+``` JavaScript
+view.backgroundColor = new colorModule.Color("red");
+view.animate({ backgroundColor: new colorModule.Color("green"), duration: 2000 });
+```
+``` TypeScript
+view.backgroundColor = new colorModule.Color("red");
+view.animate({ backgroundColor: new colorModule.Color("green"), duration: 2000 });
+```
+
+As _Example 2_ shows, you can express the same animation in CSS with the following definition:
+
+__Example2: Changing background color animation with CSS.__
+
+``` CSS
+@keyframes example {
+ from { background-color: red; }
+ to { background-color: green; }
+}
+.view {
+ animation-name: example;
+ animation-duration: 2s;
+ animation-fill-mode: forwards;
+}
+```
+
+> CSS animations apply with lower precedence, like any other CSS settings, so any local values set in your element will cancel the animation.
+
+NativeScript lets you animate the following properties:
+
+- **opacity**
+- **backgroundColor**
+- **translateX** and **translateY**
+- **scaleX** and **scaleY**
+- **rotate**
+In every animation, you can control the following properties:
-- A spring animation curve causes an animation to produce a spring (bounce) effect.
+- **duration**: The length of the animation.
+- **delay**: The amount of time to delay starting the animation.
+- **iterations**: Specifies how many times the animation should be played.
+- **timing function**: The speed curve of the animation. Available options are defined below.
+##Animation curves
+
+By default, an animation moves with a linear speed without acceleration or deceleration. This might look unnatural and different from the real world where objects need time to reach their top speed and can't stop immediately. The animation curve (sometimes called an easing function) is used to give animations an illusion of inertia. It controls the animation speed by modifying the fraction of the duration. NativeScript comes with a number of predefined animation curves.
+
+- **linear**: The simplest animation curve is linear. It maintains a constant speed while the animation is running:
+
+
+- **Ease-in**: The ease-in curve causes the animation to begin slowly, and then speed up as it progresses.
+
+
+- **Ease-out**: An ease-out curve causes the animation to begin quickly, and then slow down as it completes.
+
+
+- **Ease-in-out**: 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.
+
+
+- **Spring**: A spring animation curve causes an animation to produce a spring (bounce) effect.

+In NativeScript, the animation curve is represented by the AnimationCurve enumeration and can be specified with the curve property of the animation. In CSS, the animation curve is defined by using the animation-timing-function property (see __Example 3__):
-In NativeScript the animation curve is represented by the AnimationCurve enumeration and can be specified with the curve property of the animation:
+__Example 3: How to customize the animation timing function__
``` JavaScript
view.animate({
@@ -85,8 +104,22 @@ view.animate({
curve: enums.AnimationCurve.easeIn
});
```
+``` CSS
+.view {
+ animation-name: example;
+ animation-duration: 1;
+ animation-timing-function: ease-in;
+ animation-fill-mode: forwards;
+}
+@keyframes example {
+ from { transform: translate(0, 0); }
+ to { transform: translate(0, 100); }
+}
+```
+
+It is easy to create your own animation curve by passing in the x and y components of two control points of a cubic Bezier curve (as shown in __Example 4__). Using Bezier curves is a common technique to create smooth curves in computer graphics and they are widely used in vector-based drawing tools. The values passed to the cubicBezier method control the curve shape. The animation speed will be adjusted based on the resulting path.
-It is easy to create your own animation curve by passing in the x and y components of two control points of a cubic Bezier curve. Using Bezier curves is a common technique to create smooth curves in computer graphics and they are widely used in vector-based drawing tools. The values passed to the cubicBezier method control the curve shape. The animation speed will be adjusted based on the resulting path.
+__Example 4: How to create own animation curve via cubic Bezier__

@@ -104,344 +137,17 @@ view.animate({
curve: enums.AnimationCurve.cubicBezier(0.1, 0.1, 0.1, 1)
});
```
-
-
-
-# Examples
-
-The full source code for all samples is located [`here`](https://github.com/NativeScript/animation-demo).
-
-## Opacity
-
-``` JavaScript
-view.animate({
- opacity: 0,
- duration: 3000
-});
-```
-``` TypeScript
-view.animate({
- opacity: 0,
- duration: 3000
-});
+``` CSS
+.view {
+ animation-name: example;
+ animation-duration: 1;
+ animation-timing-function: cubicBezier(0.1, 0.1, 0.1, 1);
+ animation-fill-mode: forwards;
+}
```
-## Background Color
-
-``` JavaScript
-view.animate({
- backgroundColor: new colorModule.Color("#3D5AFE"),
- duration: 3000
-});
-```
-``` TypeScript
-view.animate({
- backgroundColor: new colorModule.Color("#3D5AFE"),
- duration: 3000
-});
-```
-
-## Translate
-
-``` JavaScript
-view.animate({
- translate: { x: 100, y: 100},
- duration: 3000
-});
-```
-``` TypeScript
-view.animate({
- translate: { x: 100, y: 100},
- duration: 3000
-});
-```
-
-## Scale
-
-``` JavaScript
-view.animate({
- scale: { x: 2, y: 2},
- duration: 3000
-});
-```
-``` TypeScript
-view.animate({
- scale: { x: 2, y: 2},
- duration: 3000
-});
-```
-
-## Rotate
-
-``` JavaScript
-view.animate({
- rotate: 360,
- duration: 3000
-});
-```
-``` TypeScript
-view.animate({
- rotate: 360,
- duration: 3000
-});
-```
-
-## Multiple Properties
-
-``` JavaScript
-view.animate({
- backgroundColor: new color.Color("#3D5AFE"),
- opacity: 0.5,
- translate: { x: 100, y: 100 },
- rotate: 180,
- duration: 3000
-});
-```
-``` TypeScript
-view.animate({
- backgroundColor: new color.Color("#3D5AFE"),
- opacity: 0.5,
- translate: {x: 100, y: 100},
- rotate: 180,
- duration: 3000
-});
-```
-
-## Chaining with Promises
-
-``` JavaScript
-view.animate({ opacity: 0 })
- .then(function () { return view.animate({ opacity: 1 }); })
- .then(function () { return view.animate({ translate: { x: 100, y: 100 } }); })
- .then(function () { return view.animate({ translate: { x: 0, y: 0 } }); })
- .then(function () { return view.animate({ scale: { x: 3, y: 3 } }); })
- .then(function () { return view.animate({ scale: { x: 1, y: 1 } }); })
- .then(function () { return view.animate({ rotate: 180 }); })
- .then(function () { return view.animate({ rotate: 0 }); })
- .then(function () {
- console.log("Animation finished");
-})
- .catch(function (e) {
- console.log(e.message);
-});
-```
-``` TypeScript
-view.animate({ opacity: 0 })
- .then(() => view.animate({ opacity: 1 }))
- .then(() => view.animate({ translate: { x: 100, y: 100 } }))
- .then(() => view.animate({ translate: { x: 0, y: 0 } }))
- .then(() => view.animate({ scale: { x: 3, y: 3 } }))
- .then(() => view.animate({ scale: { x: 1, y: 1 } }))
- .then(() => view.animate({ rotate: 180 }))
- .then(() => view.animate({ rotate: 0 }))
- .then(() => {
- console.log("Animation finished");
- })
- .catch((e) => {
- console.log(e.message);
- });
-```
-
-## Chaining with Animation Set
-
-``` JavaScript
-var definitions = new Array();
-definitions.push({ target: view1, translate: { x: 200, y: 0 }, duration: 3000 });
-definitions.push({ target: view2, translate: { x: 0, y: 200 }, duration: 3000 });
-definitions.push({ target: view3, translate: { x: -200, y: 0 }, duration: 3000 });
-definitions.push({ target: view4, translate: { x: 0, y: -200 }, duration: 3000 });
-var playSequentially = true;
-var animationSet = new animationModule.Animation(definitions, playSequentially);
-animationSet.play().then(function () {
- console.log("Animation finished");
-})
- .catch(function (e) {
- console.log(e.message);
-});
-```
-``` TypeScript
-var definitions = new Array();
-definitions.push({target: view1, translate: {x: 200, y: 0}, duration: 3000 });
-definitions.push({target: view2, translate: {x: 0, y: 200}, duration: 3000 });
-definitions.push({target: view3, translate: {x: -200, y: 0}, duration: 3000 });
-definitions.push({target: view4, translate: {x: 0, y: -200}, duration: 3000 });
-var playSequentially = true;
-var animationSet = new animationModule.Animation(definitions, playSequentially);
-animationSet.play().then(() => {
- console.log("Animation finished");
-})
-.catch((e) => {
- console.log(e.message);
-});
-```
-
-## Multiple Views
-
-``` JavaScript
-var definitions = new Array();
-var a1 = {
- target: view1,
- translate: { x: 200, y: 0 },
- duration: 3000
-};
-definitions.push(a1);
-var a2 = {
- target: view2,
- translate: { x: 0, y: 200 },
- duration: 3000
-};
-definitions.push(a2);
-var a3 = {
- target: view3,
- translate: { x: -200, y: 0 },
- duration: 3000
-};
-definitions.push(a3);
-var a4 = {
- target: view4,
- translate: { x: 0, y: -200 },
- duration: 3000
-};
-definitions.push(a4);
-var animationSet = new animationModule.Animation(definitions);
-animationSet.play().then(function () {
- console.log("Animation finished");
-})
- .catch(function (e) {
- console.log(e.message);
-});
-```
-``` TypeScript
-var definitions = new Array();
-var a1: animationModule.AnimationDefinition = {
- target: view1,
- translate: {x: 200, y: 0},
- duration: 3000
-};
-definitions.push(a1);
-
-var a2: animationModule.AnimationDefinition = {
- target: view2,
- translate: {x: 0, y: 200},
- duration: 3000
-};
-definitions.push(a2);
-
-var a3: animationModule.AnimationDefinition = {
- target: view3,
- translate: {x: -200, y: 0},
- duration: 3000
-};
-definitions.push(a3);
-
-var a4: animationModule.AnimationDefinition = {
- target: view4,
- translate: {x: 0, y: -200},
- duration: 3000
-};
-definitions.push(a4);
-
-var animationSet = new animationModule.Animation(definitions);
-
-animationSet.play().then(() => {
- console.log("Animation finished");
-})
-.catch((e) => {
- console.log(e.message);
-});
-```
-
-## Reusing Animations
-
-``` JavaScript
-var animation1 = view.createAnimation({ opacity: 0 });
-var animation2 = view.createAnimation({ opacity: 1 });
-animation1.play()
- .then(function () { return animation2.play(); })
- .then(function () { return animation1.play(); })
- .then(function () { return animation2.play(); })
- .then(function () { return animation1.play(); })
- .then(function () { return animation2.play(); })
- .then(function () {
- console.log("Animation finished");
-})
- .catch(function (e) {
- console.log(e.message);
-});
-```
-``` TypeScript
-var animation1 = view.createAnimation({opacity: 0});
-var animation2 = view.createAnimation({opacity: 1});
-
-animation1.play()
-.then(()=>animation2.play())
-.then(()=>animation1.play())
-.then(()=>animation2.play())
-.then(()=>animation1.play())
-.then(()=>animation2.play())
-.then(() => {
- console.log("Animation finished");
-})
-.catch((e) => {
- console.log(e.message);
-});
-```
-
-## Slide-in Effect
-
-``` JavaScript
-var item = new imageModule.Image();
-item.src = "~/res/icon_100x100.png";
-item.width = 90;
-item.height = 90;
-item.style.margin = "5,5,5,5";
-item.translateX = -300;
-item.opacity = 0;
-item.on("loaded", function (args) {
- args.object.animate({ translate: { x: 0, y: 0 }, opacity: 1 });
-});
-wrapLayout.addChild(item);
-```
-``` TypeScript
-var item = new imageModule.Image();
-item.src = "~/res/icon_100x100.png";
-item.width = 90;
-item.height = 90;
-item.style.margin = "5,5,5,5";
-item.translateX = -300;
-item.opacity = 0;
-item.on("loaded", (args: observable.EventData) => {
- (args.object).animate({translate: { x: 0, y: 0 }, opacity: 1});
-});
-wrapLayout.addChild(item);
-```
+
-## Infinite
-
-``` JavaScript
-animationSet = new animationModule.Animation([{
- target: view,
- rotate: 360,
- duration: 3000,
- iterations: Number.POSITIVE_INFINITY,
- curve: view.ios ? UIViewAnimationCurve.UIViewAnimationCurveLinear : new android.view.animation.LinearInterpolator
- }]);
-animationSet.play().catch(function (e) {
- console.log("Animation stoppped!");
-});
-// Call animationSet.cancel() to stop it;
-```
-``` TypeScript
-animationSet = new animationModule.Animation([{
- target: view,
- rotate: 360,
- duration: 3000,
- iterations: Number.POSITIVE_INFINITY,
- curve: view.ios ? UIViewAnimationCurve.UIViewAnimationCurveLinear : new android.view.animation.LinearInterpolator
-}]);
-animationSet.play().catch((e) => {
- console.log("Animation stoppped!");
-});
-// Call animationSet.cancel() to stop it;
-```
+
+More detailed examples are available on the [Animation Examples](./animation-examples.md) page.