{"_id":"5a06037234873d0010b39246","category":{"_id":"5a06037134873d0010b39202","version":"5a06037134873d0010b391fe","project":"578c4badbd223d2000cc1441","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-07-18T21:08:45.730Z","from_sync":false,"order":3,"slug":"develop","title":"Develop"},"parentDoc":null,"user":"578c4a62bd223d2000cc143e","project":"578c4badbd223d2000cc1441","version":{"_id":"5a06037134873d0010b391fe","project":"578c4badbd223d2000cc1441","__v":1,"createdAt":"2017-11-10T19:52:17.163Z","releaseDate":"2017-11-10T19:52:17.163Z","categories":["5a06037134873d0010b391ff","5a06037134873d0010b39200","5a06037134873d0010b39201","5a06037134873d0010b39202","5a06037134873d0010b39203","5a06037134873d0010b39204"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.1.0","version":"2.1.0"},"__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-07-18T20:54:06.700Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":5,"body":"Animations provide useful feedback to users and add \"life\" to an application. Viro enables powerful and simple animations on all components. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Overview\"\n}\n[/block]\nAnimations work by *registering* animations with ```ViroAnimations.registerAnimations()```, then *invoking* the animation by using the animation prop of the component being animated.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Registering Animations\"\n}\n[/block]\nBefore an animation can be used, it must created and registered. Animations are specified by the following properties:\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"properties\",\n    \"h-0\": \"Animation property\",\n    \"1-0\": \"easing\",\n    \"1-1\": \"The pacing of the animation.\\n\\n* ```Linear```: the animation will occur evenly over its duration\\n* ```EaseIn```: the animation will begin slowly and then speed up as it progresses\\n* ```EaseOut```: the animation will begin quickly and then slow as it progresses\\n* ```EaseInEaseOut```: the animation will begin slowly, accelerate through the middle of its duration, and then slow again before completing\\n* ```Bounce```: the animation will begin quickly and *overshoot* its final position before settling into its final resting place\",\n    \"0-1\": \"Dictionary containing the values the component should animate *toward*.\\n\\nAnimatable properties include:\\n\\n* ```opacity```: opacity of an object, [0, 1]\\n* ```positionX```: position of object on x-axis\\n* ```positionY```: position of object on y-axis\\n* ```positionZ```: position of object on z-axis\\n* ```rotateX```: rotation of object around x-axis, in degrees\\n* ```rotateY```: rotation of object around y-axis, in degrees\\n* ```rotateZ```: rotation of object around z-axis, in degrees\\n* ```scaleX```: scale value of object on x-axis\\n* ```scaleY```: scale value of object on y-axis\\n* ```scaleZ```: scale value of object on z-axis\\n* ```material```: the texture, lighting, and other surface properties of the object\",\n    \"2-0\": \"duration\",\n    \"2-1\": \"Length in milliseconds of the animation\",\n    \"3-0\": \"delay\",\n    \"3-1\": \"Delay in milliseconds to wait before starting the animation\",\n    \"h-1\": \"Description\"\n  },\n  \"cols\": 2,\n  \"rows\": 4\n}\n[/block]\nIn the following example, we register an animation that sets the scale of the component to which it is applied to```[1.0, 0.6, 1.0]```, and sets the opacity of said component to ```1.0```. The animation bounces toward its final value, and lasts for five seconds.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ViroAnimations.registerAnimations({\\n    animateImage:{properties:{scaleX:1.0, scaleY:0.6, scaleZ:1.0, \\n                              opacity: 1.0},\\n                  easing:\\\"Bounce\\\", \\n                  duration: 5000},\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Applying Animations\"\n}\n[/block]\nOnce an animation is registered, it needs to be *applied* to the components we wish to animate. To do this, we use the animation prop of the component. Please check the API reference of the component you wish to animate to ensure it supports animations.\n\nThe animation object prop has the following structure: \n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"**animation**\",\n    \"h-0\": \"PropKey\",\n    \"h-1\": \"PropType\",\n    \"1-0\": \"**delay**\",\n    \"2-0\": \"**loop**\",\n    \"3-0\": \"**onFinish**\",\n    \"4-0\": \"**onStart**\",\n    \"5-0\": \"**run**\",\n    \"0-1\": \"**PropTypes.string**\\n\\nThe name of the animation. This should match the name in the Animation registry.\",\n    \"1-1\": \"**PropTypes.number**\\n\\nThe delay in milliseconds to apply before executing the specified animation.\",\n    \"2-1\": \"**PropTypes.bool**\\n\\nTrue if the animation should loop. Set to false by default.\",\n    \"3-1\": \"**PropTypes.func**\\n\\nCallback invoked when the animation has finished. If loop is set to true, this is invoked every time the animation loops.\",\n    \"4-1\": \"**PropTypes.func**\\n\\nCallback invoked when the animation has started. If loop is set to true, this is invoked every time the animation loops.\",\n    \"5-1\": \"**PropTypes.bool**\\n\\nSet to true to start the animation. If you set to false, this will pause the animation. The default value is true.\"\n  },\n  \"cols\": 2,\n  \"rows\": 6\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroImage source={require('./res/myimage.jpg')} \\n           position={[0, -1, -2]} \\n           scale={[0.1, 0.1, 0.1]}\\n           animation={{name:'animateImage', run:true}} \\n/>\",\n      \"language\": \"javascript\",\n      \"name\": null\n    }\n  ]\n}\n[/block]\nIn the example above, we apply the ```animateImage``` animation (which we registered in the section above) to the ```<ViroImage>```. The ```<ViroImage>``` initially has a scale of ```[0.1, 0.1, 0.1]```. ```animateImage``` will animate this scale to ```[1.0, 0.6, 1.0]``` over 5 seconds.\n\nThe animation will run immediately after the ```<ViroImage>``` is added to the scene because ```run``` is set to true. If ```run``` were set to false, you could trigger the animation at any time by setting it to true. After a button press, for example.\n\nNote that you can apply a single animation to multiple components.\n\nThe full code for this animation is below.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"'use strict';\\n\\nimport React, { Component } from 'react';\\nimport {\\n  ViroScene,\\n  ViroImage,\\n  ViroAnimations,\\n} from 'react-viro';\\n\\nvar AnimationTest = React.createClass({\\n  render: function() {\\n    <ViroScene>\\n        <ViroImage source={require('./res/myimage.jpg')}\\n        \\t\\t\\t     position={[0, -1, -2]} \\t\\t\\n        \\t\\t\\t\\t   scale={[.1, .1, .1]} \\n                   animation={{name:'animateImage', \\n                              run:true}}  />\\n    </ViroScene>\\n  }\\n});\\n\\nViroAnimations.registerAnimations({\\n  animateImage:{properties:{scaleX:1, scaleY:.6, scaleZ:1, opacity: 1},  \\n        easing:\\\"Bounce\\\", duration: 5000},\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Looping and Additive Animations\"\n}\n[/block]\nAnimations can be looped, and the target properties for an animation can be set in an additive or multiplicative manner. Below is a simple example showing how to loop an animation that adds to the current property of a component. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var AnimationTest = React.createClass({\\n  render: function() {\\n    <ViroScene>\\n      \\t<ViroImage source={require('./res/myimage.jpg')}\\n         \\t        position={[0, -1, -2]} \\t\\t\\n         \\t        scale={[.1, .1, .1]}\\n                  animation={{name:'loopRotate',\\n                             run:true,\\n                             loop:true}} />\\n    </ViroScene>\\n  }\\n});\\n\\nViroAnimations.registerAnimations({\\n  loopRotate:{properties:{rotateY:\\\"+=45\\\"}, duration:1000},\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe example above rotates an image around the y axis in an infinite loop. The ```rotateY``` property of the ```loopRotate``` animation takes the value ```+=45```. This means it will *add* 45 degrees to the y angle of the component every 1 second. Properties can also be subtracted (-=), multiplied (*=), or divided (/=).\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Chaining Animations\"\n}\n[/block]\nSuppose you have a series of animations that you wish to run in sequence. For example, you have an animation that moves a component horizontally called ```moveRight```, and an animation that rotates a component called ```rotate```, and you would like to run these one after the other. You can do the following:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ViroAnimations.registerAnimations({\\n  moveRight:{properties:{positionX:\\\"+=0.3\\\"}, duration: 10000},\\n  rotate:{properties:{rotateZ:\\\"+=45\\\"}, duration:1000},\\n  rotateAndMovePicture:[\\n      [\\\"moveRight\\\", \\\"rotate\\\"],\\n  ]\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nIn the example above, we define an *animation chain* called ```rotateAndMovePicture```. It is defined as an array of existing animations. This new animation, when applied, will move the component then rotate it.\n\nIf you want animations to run *in parallel* instead of in sequence, simply define an animation as multiple animation chains, as demonstrated in the following snippet. ```rotateAndMovePicture```, when applied, will start both chains at the same time: the component will move right and rotate concurrently.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ViroAnimations.registerAnimations({\\n  moveRight:{properties:{positionX:\\\"+=0.3\\\"}, duration: 10000},\\n  rotate:{properties:{rotateZ:\\\"+=45\\\"}, duration:1000},\\n  rotateAndMovePicture:[\\n      [\\\"moveRight\\\"],\\n      [\\\"rotate\\\"],\\n  ]\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nFinally, you can also run animation chains, each with multiple sequential steps, concurrently in parallel with one another. The following example makes our component move right, then move back to its original position; while this is happening, the component will also rotate.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ViroAnimations.registerAnimations({\\n\\tmoveRight:{properties:{positionX:\\\"+=0.3\\\"}, duration: 10000},\\n\\tmoveLeft:{properties:{positionX:\\\"-=0.3\\\", rotateZ:\\\"+=45\\\"}, duration: 10000},\\n\\trotate:{properties:{rotateZ:\\\"+=45\\\"}, duration:1000},\\n\\trotateAndMovePicture:[\\n\\t\\t[\\\"moveRight\\\", \\\"moveLeft\\\"],\\n\\t\\t[\\\"rotate\\\"]\\n\\t]\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Animation callbacks\"\n}\n[/block]\nAnimation callbacks can be used to perform an action when an animation starts, or after an animation completes. For example, to respond to the end of an animation, add the desired function to the ```onFinish``` property of the animation property. Let's look at an example:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var AnimationOnFinishTest = React.createClass({\\n  render: function() {\\n    <ViroScene>\\n        <ViroImage source={require('./res/myimage.jpg')}\\n                     position={[0, -1, -2]} \\t\\t\\n                     scale={[0.1, 0.1, 0.1]}\\n                     animation={{name:'animateImage', \\n                                run:true, \\n                                onFinish:{this._onAnimationFinished}}}\\n        />\\n    </ViroScene>\\n  },\\n  \\n _onAnimationFinished(){\\n      console.log(\\\"Animation has finished!\\\");\\n  },\\n});\\n\\nViroAnimations.registerAnimations({\\n    animateImage:{properties:{scaleX:1, scaleY:.6, scaleZ:1, opacity: 1},\\n                  easing:\\\"Bounce\\\", duration: 5000},\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe function is invoked after the animation has ended. If the animation is looping, the function is invoked at the end of every loop.\n[block:api-header]\n{\n  \"title\": \"Animating Materials\"\n}\n[/block]\nIn addition to position, rotation, and scale, the *material* used by any Viro object can also be animated from one to another. In the example below, we animate a ViroSurface from red to blue.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var AnimationTest = React.createClass({\\n  render: function() {\\n    return (\\n      <ViroScene >\\n          <ViroSurface materials={[\\\"redColor\\\"]} \\n                       position={[0, -.5, -1]}\\n                       animation={{name:'animateColor', \\n                                  run:{true}, \\n                                  loop:{false},\\n                                  delay:3000}}} \\n           />\\n      </ViroScene>\\n    );\\n  },\\n});\\n\\nViroMaterials.createMaterials({\\n  redColor: {\\n    diffuseColor: \\\"#FF0000\\\"\\n  },\\n  blueColor: {\\n    diffuseColor: \\\"#0000FF\\\"\\n  },\\n});\\n\\nViroAnimations.registerAnimations({\\n    animateColor:{properties:{material:\\\"blueColor\\\"}, duration:3000},\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nBecause material animations can move from one material to any other material, you can use this feature to animate between textures, lighting models, and more.\n\n# Skeletal Animation\n\nSkeletal animation is a technique for animating complex geometries; for example, to make a humanoid character walk. These animations are typically authored in 3D graphics software, and exported as FBX files. Viro has full support for these animations. For more information, please see the [3D Objects](doc:3d-objects) guide.","excerpt":"Animating content in your scenes","slug":"animation","type":"basic","title":"Animation"}

Animation

Animating content in your scenes

Animations provide useful feedback to users and add "life" to an application. Viro enables powerful and simple animations on all components. [block:api-header] { "type": "basic", "title": "Overview" } [/block] Animations work by *registering* animations with ```ViroAnimations.registerAnimations()```, then *invoking* the animation by using the animation prop of the component being animated. [block:api-header] { "type": "basic", "title": "Registering Animations" } [/block] Before an animation can be used, it must created and registered. Animations are specified by the following properties: [block:parameters] { "data": { "0-0": "properties", "h-0": "Animation property", "1-0": "easing", "1-1": "The pacing of the animation.\n\n* ```Linear```: the animation will occur evenly over its duration\n* ```EaseIn```: the animation will begin slowly and then speed up as it progresses\n* ```EaseOut```: the animation will begin quickly and then slow as it progresses\n* ```EaseInEaseOut```: the animation will begin slowly, accelerate through the middle of its duration, and then slow again before completing\n* ```Bounce```: the animation will begin quickly and *overshoot* its final position before settling into its final resting place", "0-1": "Dictionary containing the values the component should animate *toward*.\n\nAnimatable properties include:\n\n* ```opacity```: opacity of an object, [0, 1]\n* ```positionX```: position of object on x-axis\n* ```positionY```: position of object on y-axis\n* ```positionZ```: position of object on z-axis\n* ```rotateX```: rotation of object around x-axis, in degrees\n* ```rotateY```: rotation of object around y-axis, in degrees\n* ```rotateZ```: rotation of object around z-axis, in degrees\n* ```scaleX```: scale value of object on x-axis\n* ```scaleY```: scale value of object on y-axis\n* ```scaleZ```: scale value of object on z-axis\n* ```material```: the texture, lighting, and other surface properties of the object", "2-0": "duration", "2-1": "Length in milliseconds of the animation", "3-0": "delay", "3-1": "Delay in milliseconds to wait before starting the animation", "h-1": "Description" }, "cols": 2, "rows": 4 } [/block] In the following example, we register an animation that sets the scale of the component to which it is applied to```[1.0, 0.6, 1.0]```, and sets the opacity of said component to ```1.0```. The animation bounces toward its final value, and lasts for five seconds. [block:code] { "codes": [ { "code": "ViroAnimations.registerAnimations({\n animateImage:{properties:{scaleX:1.0, scaleY:0.6, scaleZ:1.0, \n opacity: 1.0},\n easing:\"Bounce\", \n duration: 5000},\n});", "language": "javascript" } ] } [/block] [block:api-header] { "type": "basic", "title": "Applying Animations" } [/block] Once an animation is registered, it needs to be *applied* to the components we wish to animate. To do this, we use the animation prop of the component. Please check the API reference of the component you wish to animate to ensure it supports animations. The animation object prop has the following structure: [block:parameters] { "data": { "0-0": "**animation**", "h-0": "PropKey", "h-1": "PropType", "1-0": "**delay**", "2-0": "**loop**", "3-0": "**onFinish**", "4-0": "**onStart**", "5-0": "**run**", "0-1": "**PropTypes.string**\n\nThe name of the animation. This should match the name in the Animation registry.", "1-1": "**PropTypes.number**\n\nThe delay in milliseconds to apply before executing the specified animation.", "2-1": "**PropTypes.bool**\n\nTrue if the animation should loop. Set to false by default.", "3-1": "**PropTypes.func**\n\nCallback invoked when the animation has finished. If loop is set to true, this is invoked every time the animation loops.", "4-1": "**PropTypes.func**\n\nCallback invoked when the animation has started. If loop is set to true, this is invoked every time the animation loops.", "5-1": "**PropTypes.bool**\n\nSet to true to start the animation. If you set to false, this will pause the animation. The default value is true." }, "cols": 2, "rows": 6 } [/block] [block:code] { "codes": [ { "code": "<ViroImage source={require('./res/myimage.jpg')} \n position={[0, -1, -2]} \n scale={[0.1, 0.1, 0.1]}\n animation={{name:'animateImage', run:true}} \n/>", "language": "javascript", "name": null } ] } [/block] In the example above, we apply the ```animateImage``` animation (which we registered in the section above) to the ```<ViroImage>```. The ```<ViroImage>``` initially has a scale of ```[0.1, 0.1, 0.1]```. ```animateImage``` will animate this scale to ```[1.0, 0.6, 1.0]``` over 5 seconds. The animation will run immediately after the ```<ViroImage>``` is added to the scene because ```run``` is set to true. If ```run``` were set to false, you could trigger the animation at any time by setting it to true. After a button press, for example. Note that you can apply a single animation to multiple components. The full code for this animation is below. [block:code] { "codes": [ { "code": "'use strict';\n\nimport React, { Component } from 'react';\nimport {\n ViroScene,\n ViroImage,\n ViroAnimations,\n} from 'react-viro';\n\nvar AnimationTest = React.createClass({\n render: function() {\n <ViroScene>\n <ViroImage source={require('./res/myimage.jpg')}\n \t\t\t position={[0, -1, -2]} \t\t\n \t\t\t\t scale={[.1, .1, .1]} \n animation={{name:'animateImage', \n run:true}} />\n </ViroScene>\n }\n});\n\nViroAnimations.registerAnimations({\n animateImage:{properties:{scaleX:1, scaleY:.6, scaleZ:1, opacity: 1}, \n easing:\"Bounce\", duration: 5000},\n});", "language": "javascript" } ] } [/block] [block:api-header] { "type": "basic", "title": "Looping and Additive Animations" } [/block] Animations can be looped, and the target properties for an animation can be set in an additive or multiplicative manner. Below is a simple example showing how to loop an animation that adds to the current property of a component. [block:code] { "codes": [ { "code": "var AnimationTest = React.createClass({\n render: function() {\n <ViroScene>\n \t<ViroImage source={require('./res/myimage.jpg')}\n \t position={[0, -1, -2]} \t\t\n \t scale={[.1, .1, .1]}\n animation={{name:'loopRotate',\n run:true,\n loop:true}} />\n </ViroScene>\n }\n});\n\nViroAnimations.registerAnimations({\n loopRotate:{properties:{rotateY:\"+=45\"}, duration:1000},\n});", "language": "javascript" } ] } [/block] The example above rotates an image around the y axis in an infinite loop. The ```rotateY``` property of the ```loopRotate``` animation takes the value ```+=45```. This means it will *add* 45 degrees to the y angle of the component every 1 second. Properties can also be subtracted (-=), multiplied (*=), or divided (/=). [block:api-header] { "type": "basic", "title": "Chaining Animations" } [/block] Suppose you have a series of animations that you wish to run in sequence. For example, you have an animation that moves a component horizontally called ```moveRight```, and an animation that rotates a component called ```rotate```, and you would like to run these one after the other. You can do the following: [block:code] { "codes": [ { "code": "ViroAnimations.registerAnimations({\n moveRight:{properties:{positionX:\"+=0.3\"}, duration: 10000},\n rotate:{properties:{rotateZ:\"+=45\"}, duration:1000},\n rotateAndMovePicture:[\n [\"moveRight\", \"rotate\"],\n ]\n});", "language": "javascript" } ] } [/block] In the example above, we define an *animation chain* called ```rotateAndMovePicture```. It is defined as an array of existing animations. This new animation, when applied, will move the component then rotate it. If you want animations to run *in parallel* instead of in sequence, simply define an animation as multiple animation chains, as demonstrated in the following snippet. ```rotateAndMovePicture```, when applied, will start both chains at the same time: the component will move right and rotate concurrently. [block:code] { "codes": [ { "code": "ViroAnimations.registerAnimations({\n moveRight:{properties:{positionX:\"+=0.3\"}, duration: 10000},\n rotate:{properties:{rotateZ:\"+=45\"}, duration:1000},\n rotateAndMovePicture:[\n [\"moveRight\"],\n [\"rotate\"],\n ]\n});", "language": "javascript" } ] } [/block] Finally, you can also run animation chains, each with multiple sequential steps, concurrently in parallel with one another. The following example makes our component move right, then move back to its original position; while this is happening, the component will also rotate. [block:code] { "codes": [ { "code": "ViroAnimations.registerAnimations({\n\tmoveRight:{properties:{positionX:\"+=0.3\"}, duration: 10000},\n\tmoveLeft:{properties:{positionX:\"-=0.3\", rotateZ:\"+=45\"}, duration: 10000},\n\trotate:{properties:{rotateZ:\"+=45\"}, duration:1000},\n\trotateAndMovePicture:[\n\t\t[\"moveRight\", \"moveLeft\"],\n\t\t[\"rotate\"]\n\t]\n});", "language": "javascript" } ] } [/block] [block:api-header] { "type": "basic", "title": "Animation callbacks" } [/block] Animation callbacks can be used to perform an action when an animation starts, or after an animation completes. For example, to respond to the end of an animation, add the desired function to the ```onFinish``` property of the animation property. Let's look at an example: [block:code] { "codes": [ { "code": "var AnimationOnFinishTest = React.createClass({\n render: function() {\n <ViroScene>\n <ViroImage source={require('./res/myimage.jpg')}\n position={[0, -1, -2]} \t\t\n scale={[0.1, 0.1, 0.1]}\n animation={{name:'animateImage', \n run:true, \n onFinish:{this._onAnimationFinished}}}\n />\n </ViroScene>\n },\n \n _onAnimationFinished(){\n console.log(\"Animation has finished!\");\n },\n});\n\nViroAnimations.registerAnimations({\n animateImage:{properties:{scaleX:1, scaleY:.6, scaleZ:1, opacity: 1},\n easing:\"Bounce\", duration: 5000},\n});", "language": "javascript" } ] } [/block] The function is invoked after the animation has ended. If the animation is looping, the function is invoked at the end of every loop. [block:api-header] { "title": "Animating Materials" } [/block] In addition to position, rotation, and scale, the *material* used by any Viro object can also be animated from one to another. In the example below, we animate a ViroSurface from red to blue. [block:code] { "codes": [ { "code": "var AnimationTest = React.createClass({\n render: function() {\n return (\n <ViroScene >\n <ViroSurface materials={[\"redColor\"]} \n position={[0, -.5, -1]}\n animation={{name:'animateColor', \n run:{true}, \n loop:{false},\n delay:3000}}} \n />\n </ViroScene>\n );\n },\n});\n\nViroMaterials.createMaterials({\n redColor: {\n diffuseColor: \"#FF0000\"\n },\n blueColor: {\n diffuseColor: \"#0000FF\"\n },\n});\n\nViroAnimations.registerAnimations({\n animateColor:{properties:{material:\"blueColor\"}, duration:3000},\n});", "language": "javascript" } ] } [/block] Because material animations can move from one material to any other material, you can use this feature to animate between textures, lighting models, and more. # Skeletal Animation Skeletal animation is a technique for animating complex geometries; for example, to make a humanoid character walk. These animations are typically authored in 3D graphics software, and exported as FBX files. Viro has full support for these animations. For more information, please see the [3D Objects](doc:3d-objects) guide.