<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>React Native on GeekyHub</title>
    <link>https://www.geekyhub.in/tags/react-native/</link>
    <description>Recent content in React Native on GeekyHub</description>
    <generator>Hugo -- 0.148.1</generator>
    <language>en</language>
    <lastBuildDate>Sun, 06 Feb 2022 13:27:58 +0530</lastBuildDate>
    <atom:link href="https://www.geekyhub.in/tags/react-native/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Animate SVG in React Native</title>
      <link>https://www.geekyhub.in/post/animate-svg-using-react-native-renanimated-2/</link>
      <pubDate>Sat, 05 Feb 2022 11:00:00 +0530</pubDate>
      <guid>https://www.geekyhub.in/post/animate-svg-using-react-native-renanimated-2/</guid>
      <description>Animating SVG in React-Native using react-native-reanimated.</description>
      <content:encoded><![CDATA[<p>Here, by animating SVG, I mean to change the property of SVG elements dynamically, which will look live-like.</p>
<p>In react native, we can generate/render an SVG using the <a href="https://github.com/react-native-svg/react-native-svg">react-native-svg</a> library. A complex SVG comprises many more minor elements that could be animated individually. But here, for example, we will take only one piece, a circle.</p>
<p>The following code will draw a circle with a radius of 50 units.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-react" data-lang="react"><span style="display:flex;"><span>&lt;<span style="color:#f92672">Svg</span> <span style="color:#a6e22e">width</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>} <span style="color:#a6e22e">height</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>}&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">Circle</span> <span style="color:#a6e22e">cx</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;55&#34;</span> <span style="color:#a6e22e">cy</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;55&#34;</span> <span style="color:#a6e22e">r</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;50&#34;</span> <span style="color:#a6e22e">stroke</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;black&#34;</span> <span style="color:#a6e22e">strokeWidth</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">5</span>} /&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">Svg</span>&gt;
</span></span></code></pre></div><p>Suppose we want to animate it to become large and small.
To achieve this, I will use <a href="https://docs.swmansion.com/react-native-reanimated/">React Native Reanimated</a>. To learn more about it, you can check out its documentation.</p>
<p>Logically, I am trying to increase or decrease the radius.</p>
<p>Since the radius value is a prop, I will use <code>useAnimatedProps</code>. But, first of all, convert Circle to an animated component.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-react" data-lang="react"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">AnimatedCircle</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">Animated</span>.<span style="color:#a6e22e">createAnimatedComponent</span>(<span style="color:#a6e22e">Circle</span>);
</span></span></code></pre></div><p>Now, I can re-write component as</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-react" data-lang="react"><span style="display:flex;"><span>&lt;<span style="color:#f92672">Svg</span> <span style="color:#a6e22e">width</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>} <span style="color:#a6e22e">height</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>}&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">AnimatedCircle</span> <span style="color:#a6e22e">cx</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;55&#34;</span> <span style="color:#a6e22e">cy</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;55&#34;</span> <span style="color:#a6e22e">r</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;50&#34;</span> <span style="color:#a6e22e">stroke</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;black&#34;</span> <span style="color:#a6e22e">strokeWidth</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">5</span>} /&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">Svg</span>&gt;
</span></span></code></pre></div><p>Next step is to store the stroke width and radius. width can be stored in a simple constat, but for the radius we will use <a href="https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/shared-values"><code>useSharedValue</code></a>, so that it can be used by woklet to animate.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-react" data-lang="react"><span style="display:flex;"><span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> ()=&gt;{
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">radius</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">useSharedValue</span>(<span style="color:#ae81ff">50</span>);
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">strokeWidth</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">5</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> (
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">Svg</span> <span style="color:#a6e22e">width</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>} <span style="color:#a6e22e">height</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>}&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">AnimatedCircle</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">cx</span><span style="color:#f92672">=</span>{<span style="color:#e6db74">`</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">strokeWidth</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>}
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">cy</span><span style="color:#f92672">=</span>{<span style="color:#e6db74">`</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">strokeWidth</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>}
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">r</span><span style="color:#f92672">=</span>{<span style="color:#e6db74">`</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>}
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">stroke</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;black&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">strokeWidth</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">strokeWidth</span>}
</span></span><span style="display:flex;"><span>      /&gt;
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#f92672">Svg</span>&gt;
</span></span><span style="display:flex;"><span>  )
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Here, I need some event or action to trigger the radius change. I&rsquo;ll use a button press. (withSpring is default provided animation which is not necessary to use but this looks cool 🤞)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-react" data-lang="react"><span style="display:flex;"><span>&lt;<span style="color:#f92672">Button</span> <span style="color:#a6e22e">mode</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;contained&#34;</span> <span style="color:#a6e22e">onPress</span><span style="color:#f92672">=</span>{() =&gt; {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span>(<span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span> <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">80</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">withSpring</span>(<span style="color:#ae81ff">80</span>)
</span></span><span style="display:flex;"><span>  }<span style="color:#66d9ef">else</span>{
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">withSpring</span>(<span style="color:#ae81ff">50</span>)
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}}&gt;
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">Press</span>
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">Button</span>&gt;
</span></span></code></pre></div><p>You&rsquo;ll notice that even after pressing the button, nothing happens. It is because change of sharedValue doesn&rsquo;t trigger re-render of the react component. finally animated props comes into the picture. Instead of passing prop directly, we will pass it using animated prop.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-react" data-lang="react"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">animatedProps</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">useAnimatedProps</span>(() =&gt; ({
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">cx</span><span style="color:#f92672">:</span> <span style="color:#e6db74">`</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">strokeWidth</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">cy</span><span style="color:#f92672">:</span> <span style="color:#e6db74">`</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">strokeWidth</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">r</span><span style="color:#f92672">:</span><span style="color:#e6db74">`</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">radius</span>.<span style="color:#a6e22e">value</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>
</span></span><span style="display:flex;"><span>}));
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-react" data-lang="react"><span style="display:flex;"><span>&lt;<span style="color:#f92672">Svg</span> <span style="color:#a6e22e">width</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>} <span style="color:#a6e22e">height</span><span style="color:#f92672">=</span>{<span style="color:#ae81ff">200</span>}&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">AnimatedCircle</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">animatedProps</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">animatedProps</span>}
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">stroke</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;black&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">strokeWidth</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">strokeWidth</span>}
</span></span><span style="display:flex;"><span>  /&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">Svg</span>&gt;
</span></span></code></pre></div><p>Result, is something like this.
<figure>
    <img loading="lazy" src="circle-animation.gif" width="300px"/> 
</figure>
</p>
<p>This is a relatively simple example, but I hope I successfully demonstrated the possibilities.
Here is the <a href="https://gist.github.com/vikas-0/24c785c2a178a790b3b7352b400cc400">link</a> of complete code of the result if you are interested.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
