{"id":7245,"date":"2019-06-23T20:15:38","date_gmt":"2019-06-23T20:15:38","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=7245"},"modified":"2019-06-23T20:29:21","modified_gmt":"2019-06-23T20:29:21","slug":"animejs","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/animejs\/","title":{"rendered":"animejs"},"content":{"rendered":"<p>I was working on some code to display a green circle with a tick (for success) and a red circle with a cross (for failure) within rows in ag-Grid to denote whether service calls succeeded or failed for each row of data. Having the graphics seemed good but what I really wanted was to animate the display of these graphics to make it obvious to the user that these graphics changes\/updated.<\/p>\n<p><a href=\"https:\/\/animejs.com\/\" rel=\"noopener noreferrer\" target=\"_blank\">animejs<\/a> looked to be a perfect solution to the problem.<\/p>\n<p><em>There&#8217;s lots of great examples using animejs <a href=\"https:\/\/codepen.io\/collection\/XLebem\/#\" rel=\"noopener noreferrer\" target=\"_blank\">here<\/a>.<\/em><\/p>\n<p>Obviously to begin with I&#8217;ve created a React application using the standard scaffolding, and then using yarn installed anime, i.e.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nyarn add animejs\r\nyarn add @types\/animejs\r\n<\/pre>\n<p>We&#8217;ll create a standard React component (SuccessFailureComponent.tsx) for displaying our new animated component.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport React from 'react';\r\nimport anime from &quot;animejs&quot;;\r\n\r\ninterface SuccessFailureProps {\r\n    success: boolean;\r\n}\r\n\r\nexport class SuccessFailureComponent \r\n   extends React.Component&lt;SuccessFailureProps, {}&gt; {\r\n      render() {\r\n         \/\/ to be implemented\r\n      }\r\n}\r\n<\/pre>\n<p>In this code we&#8217;ve added the property <em>success<\/em>, which when true will display the green circle with a tick and when false the red circle with the cross.<\/p>\n<p>To begin with we&#8217;ll add the following code to draw our graphics to the render function<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst backColour = this.props.success ? \r\n   &quot;#0c3&quot; : \r\n   &quot;red&quot;;\r\nconst symbol = this.props.success ? \r\n   &quot;M9 16l5 5 9-9&quot;: \r\n   &quot;M9 9l14 14 M23 9L9 23&quot;;\r\n\r\nreturn (\r\n   &lt;svg className=&quot;status&quot; xmlns=&quot;http:\/\/www.w3.org\/2000\/svg&quot;\r\n      width=&quot;32&quot;\r\n      height=&quot;32&quot;\r\n      viewBox=&quot;0 0 42 42&quot;&gt;\r\n      &lt;circle className=&quot;circle&quot;\r\n         cx=&quot;16&quot;\r\n         cy=&quot;16&quot;\r\n         r=&quot;16&quot;\r\n         fill={backColour}\/&gt;\r\n      &lt;path d={symbol}\r\n         fill=&quot;none&quot;\r\n         stroke=&quot;white&quot;\r\n         stroke-width=&quot;2.5&quot;   \r\n         stroke-linecap=&quot;round&quot;\/&gt; :\r\n   &lt;\/svg&gt;\r\n);\r\n<\/pre>\n<p>In the above we use the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/SVG\/Tutorial\" rel=\"noopener noreferrer\" target=\"_blank\">Scalable Vector Graphics<\/a> element to wrap drawing primitives to first draw a circle with the required fill colour and then using the <em>symbol<\/em> const which is the drawing of a tick or cross.<\/p>\n<p>If we run the React app at this point (assuming we&#8217;ve also added the following component to the App.tsx render method<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n&lt;SuccessFailureComponent success={false}\/&gt;\r\n&lt;SuccessFailureComponent success={true}\/&gt;\r\n<\/pre>\n<p>then we&#8217;ll see the two SVG graphics displayed.<\/p>\n<p><strong>Animating our graphics<\/strong><\/p>\n<p>We&#8217;ve come all this way in a post about animation and not animated anything, so let&#8217;s now do that. Back in the component, add <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\ncomponentDidMount() {\r\n   var timeline = anime.timeline({ \r\n      autoplay: true\r\n   });\r\n\r\n   timeline\r\n      .add({\r\n         targets: '.status',\r\n         scale: &#x5B;{ \r\n            value: &#x5B;0, 1], \r\n            duration: 600, \r\n            easing: 'easeOutQuad' }\r\n         ]\r\n      });\r\n}\r\n<\/pre>\n<p>When the application is refreshed you&#8217;ll see the graphics scale from nothing to full sized.<\/p>\n<p>In the first line we create the anime timeline which has parameters which will simply start the animation immediately. We then use the <em>add<\/em> function with the target &#8220;status&#8221; (our SVG element) to scale the SVG from nothing to full sized with a duration of 600ms. Finally we specify the easing function to use.<\/p>\n<p>We can also add more animation transitions to the timeline, for example the following additions to the timeline code (above) will result in the icons moving right by 10 pixels then returning to where they started<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n.add({\r\n   targets: '.status',            \r\n   translateX: 10\r\n})\r\n.add({\r\n   targets: '.status',\r\n   translateX: 0\r\n});\r\n<\/pre>\n<p>Or maybe we&#8217;d like to just spin the graphics using<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n.add({\r\n   targets: '.status',            \r\n   rotate: 360\r\n});\r\n<\/pre>\n<p>There&#8217;s more than just the timeline function, there&#8217;s also stagger which allows the animation of multiple elements. Also keyframes which allows us to create an array of keyframes for our animations.<\/p>\n<p>This <a href=\"https:\/\/easings.net\/en\" rel=\"noopener noreferrer\" target=\"_blank\">easings.net<\/a> is a great resource for seeing how different easing functions might look. If you want to (for example) add a little bounce back to the easing try, easeOutBack.<\/p>\n<p>The <a href=\"https:\/\/animejs.com\/documentation\/\" rel=\"noopener noreferrer\" target=\"_blank\">anime documentation<\/a> also has some great examples along with the documentation of fairly simple transitions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was working on some code to display a green circle with a tick (for success) and a red circle with a cross (for failure) within rows in ag-Grid to denote whether service calls succeeded or failed for each row of data. Having the graphics seemed good but what I really wanted was to animate [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[256],"tags":[],"class_list":["post-7245","post","type-post","status-publish","format-standard","hentry","category-animejs"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=7245"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7245\/revisions"}],"predecessor-version":[{"id":7254,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7245\/revisions\/7254"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=7245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=7245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=7245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}