<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cong Nguyen</title>
    <description>The latest articles on DEV Community by Cong Nguyen (@congnd).</description>
    <link>https://dev.to/congnd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F48398%2F006ed0af-d6fd-4d96-8a34-43902a64843c.jpeg</url>
      <title>DEV Community: Cong Nguyen</title>
      <link>https://dev.to/congnd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/congnd"/>
    <language>en</language>
    <item>
      <title>Having fun with CoreAnimation</title>
      <dc:creator>Cong Nguyen</dc:creator>
      <pubDate>Sun, 03 Jan 2021 08:34:58 +0000</pubDate>
      <link>https://dev.to/congnd/having-fun-with-coreanimation-5i8</link>
      <guid>https://dev.to/congnd/having-fun-with-coreanimation-5i8</guid>
      <description>&lt;p&gt;In this article, I'm going to create an animation like this using pure CAAnimation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/nVD6nYqEohCsD25P3o/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/nVD6nYqEohCsD25P3o/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This animation is constructed by combining the following pieces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rocket animation: pushes the balloons up at a fast speed to simulate a rocket's taking off&lt;/li&gt;
&lt;li&gt;spring animation: rotates and scales the ballons to make it look like being pressed in a strong pressure&lt;/li&gt;
&lt;li&gt;bezier animation: moves the balloons up along a bezier path to make it look like being moved naturally&lt;/li&gt;
&lt;li&gt;3d rotation animation: rotates the ballons 3D to make it look like being affected by wind&lt;/li&gt;
&lt;li&gt;opacity animation: goes away smoothly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll go through all of them in turn.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rocket animation
&lt;/h3&gt;

&lt;p&gt;This animation mimics the rocket's taking off effect in a small portion of the time. &lt;br&gt;
It does nothing but moving the layer from the start point to the endpoint along a straight line.&lt;/p&gt;
&lt;h3&gt;
  
  
  Spring animation
&lt;/h3&gt;

&lt;p&gt;This animation occurs simultaneously with the rocket animation above to make the animated object&lt;br&gt;
more interesting by adding a bouncing animation. So basically, we are not going to move the layer&lt;br&gt;
in this animation but just make it bigger and then smaller overtime. &lt;/p&gt;

&lt;p&gt;To make the layer look like a rocket, we scale the layer horizontally to a very small value &lt;br&gt;
in the beginning and then scale it back to a normal aspect at the end of the animation.&lt;/p&gt;

&lt;p&gt;After combining this with the rocket animation above, our animation now looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/avpqHEufHTlNZ0PJCr/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/avpqHEufHTlNZ0PJCr/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Bezier animation
&lt;/h3&gt;

&lt;p&gt;After reaching the endpoint of the rocket animation, we will move the object along a bezier path. &lt;br&gt;
If you don't know what a bezier path is then you should take a look at &lt;a href="https://en.wikipedia.org/wiki/B%C3%A9zier_curve"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In short, bezier paths are curves that are defined by a set of &lt;code&gt;control points&lt;/code&gt; to create a smooth connection between the start and the endpoint. I'm not going to deep dive into the detail of Bezier paths because it's quite complicated and painful to explain so if you are interested, please read the link above. But you can look at the below images for easy to imagine what are they.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LG2wdqMI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/B%25C3%25A9zier_2_big.gif/240px-B%25C3%25A9zier_2_big.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LG2wdqMI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/B%25C3%25A9zier_2_big.gif/240px-B%25C3%25A9zier_2_big.gif" width="240"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EoHw9IHh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/B%25C3%25A9zier_4_big.gif/240px-B%25C3%25A9zier_4_big.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EoHw9IHh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/B%25C3%25A9zier_4_big.gif/240px-B%25C3%25A9zier_4_big.gif" width="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time, we will use a bezier path animation to make the view less boring and more natural.&lt;/p&gt;

&lt;p&gt;Create bezier animation is quite easy. All we have to do is create a bezier path then CAAnimation will handle the rest for us.&lt;/p&gt;

&lt;p&gt;Create a Bezier path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIBezierPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;startPoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;endPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;posX&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;controlPoint1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;controlPoint2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addCurve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;endPoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;controlPoint1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;controlPoint1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;controlPoint2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;controlPoint2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create CAAnimation like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;animation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CAKeyframeAnimation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;#keyPath(&lt;/span&gt;&lt;span class="nf"&gt;CALayer.position&lt;/span&gt;&lt;span class="kd"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;animation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgPath&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, your bezier animation looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/0BvUKguh3rL7FNQQ2m/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/0BvUKguh3rL7FNQQ2m/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3D rotation animation
&lt;/h3&gt;

&lt;p&gt;We can easily create this effect by animating the &lt;code&gt;transform&lt;/code&gt; property on CALayer which is also an animatable property. Since CAAnimation supports rotations over &lt;br&gt;
all 3 axes but there is no depth of field effect so we will add scale factors &lt;br&gt;
to somehow simulate that effect to make it more like real 3D rotation.&lt;/p&gt;

&lt;p&gt;Here is the sample code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;animation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CABasicAnimation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;#keyPath(&lt;/span&gt;&lt;span class="nf"&gt;CALayer.transform&lt;/span&gt;&lt;span class="kd"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;rotation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CATransform3DMakeRotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;finalScale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;transoform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CATransform3DScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;finalScale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;finalScale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;animation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;transoform&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this animation only, it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ypwEVIY4yQwtHsDzEp/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ypwEVIY4yQwtHsDzEp/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Opacity animation
&lt;/h3&gt;

&lt;p&gt;Probably, this is the easiest one. Just use animate a basic animation that controls the opacity value of the layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;animation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CABasicAnimation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;#keyPath(&lt;/span&gt;&lt;span class="nf"&gt;CALayer.opacity&lt;/span&gt;&lt;span class="kd"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;animation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Combining all the animations together
&lt;/h3&gt;

&lt;p&gt;CAAnimation allows us to group multiple animations into one and run them concurrently. &lt;br&gt;
We'll do it by using a subclass of CAAnimation called CAAnimationGroup. &lt;br&gt;
Configuring CAAnimationGroup is not that hard except for one thing that we have to configure &lt;br&gt;
the beginning time and end time of all the sub animations properly in order to achieve what we want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;animationGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CAAnimationGroup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;animationGroup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;animations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c1"&gt;// put your sub animations here&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then control the whole animation's duration as usual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;animationGroup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You probably want to do something like cleaning after the animation completed. If so, you can use CATransaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;CATransaction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kt"&gt;CATransaction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setCompletionBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// perform cleaning here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;iconView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animationGroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;forKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;CATransaction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After combining all the animations above together, eventually, we'll get this final animation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/nVD6nYqEohCsD25P3o/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/nVD6nYqEohCsD25P3o/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out the source code here: &lt;a href="https://github.com/congnd/FunWithCoreAnimation"&gt;https://github.com/congnd/FunWithCoreAnimation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>caanimation</category>
      <category>swift</category>
      <category>ios</category>
      <category>coreanimation</category>
    </item>
    <item>
      <title>MiMoSim - Another way to scroll in macOS</title>
      <dc:creator>Cong Nguyen</dc:creator>
      <pubDate>Mon, 15 Jun 2020 06:32:28 +0000</pubDate>
      <link>https://dev.to/congnd/mimosim-another-way-to-scroll-in-macos-5fil</link>
      <guid>https://dev.to/congnd/mimosim-another-way-to-scroll-in-macos-5fil</guid>
      <description>&lt;h2&gt;
  
  
  Feature
&lt;/h2&gt;

&lt;p&gt;Scroll content by moving the mouse in a circular path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download the MiMoSim app from the release page or you can build from source code&lt;/li&gt;
&lt;li&gt;Double-click to run MiMoSim&lt;/li&gt;
&lt;li&gt;Since MiMoSim listens to the keyboard events (to understand when you want to start and end a scroll session) and mouse events (to understand which direction and how fast scroll do you want), you will be asked to give MiMoSim accessibility privilege. Open your System Preferences → Privacy → Accessibility, and grant accessibility privilege to MiMoSim by checking MiMoSim item on the list.&lt;/li&gt;
&lt;li&gt;Double-click again to run MiMoSim&lt;/li&gt;
&lt;li&gt;Now you will see a small MiMoSim icon in the system's status bar&lt;/li&gt;
&lt;li&gt;Start using MiMoSim&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Press and hold the control key (the mouse now is in P1 position on the screen)&lt;/li&gt;
&lt;li&gt;Move the mouse in any direction a short distance ~ 50pt&lt;/li&gt;
&lt;li&gt;Then you will see the scrolling wheel appears with P1 as its center point.&lt;/li&gt;
&lt;li&gt;Now move the mouse in a circular path, and you will see the content under the mouse being moved in sync with your mouse movement. &lt;/li&gt;
&lt;li&gt;Move your mouse in the clockwise (CW) direction to scroll up, and counterclockwise (CCW) direction to scroll down.&lt;/li&gt;
&lt;li&gt;Release the control key to finish&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Watch this video for more detail:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/VlE2XT3h_F8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/congnd"&gt;
        congnd
      &lt;/a&gt; / &lt;a href="https://github.com/congnd/MiMoSim"&gt;
        MiMoSim
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A tiny macOS app that allows you to scroll contents in an interesting way
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://raw.githubusercontent.com/congnd/MiMoSim/master//resources/Banner.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nyGXt0dd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/congnd/MiMoSim/master/resources/Banner.png" alt="MiMoSim"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/congnd/MiMoSim/master//LICENSE"&gt;&lt;img src="https://camo.githubusercontent.com/83d3746e5881c1867665223424263d8e604df233d0a11aae0813e0414d433943/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="MIT licensed"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;MiMoSim is a tiny macOS app that allows you to scroll content in an interesting way.&lt;/p&gt;
&lt;h2&gt;
Feature&lt;/h2&gt;
&lt;p&gt;Scroll content by moving the mouse in a circular path.&lt;/p&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Download the MiMoSim app from the release page or you can build from source code&lt;/li&gt;
&lt;li&gt;Double-click to run MiMoSim&lt;/li&gt;
&lt;li&gt;Since MiMoSim listens to the keyboard events (to understand when you want to start and end a scroll session) and mouse events (to understand which direction and how fast scroll do you want), you will be asked to give MiMoSim accessibility privilege. Open your System Preferences → Privacy → Accessibility, and grant accessibility privilege to MiMoSim by checking MiMoSim item on the list.&lt;/li&gt;
&lt;li&gt;Double-click again to run MiMoSim&lt;/li&gt;
&lt;li&gt;Now you will see a small MiMoSim icon in the system's status bar&lt;/li&gt;
&lt;li&gt;Start using MiMoSim&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Press and hold the control key (the mouse now is in P1 position on the screen)&lt;/li&gt;
&lt;li&gt;Move the…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/congnd/MiMoSim"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>macos</category>
      <category>swift</category>
      <category>scrolling</category>
      <category>mouse</category>
    </item>
  </channel>
</rss>
