<?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>Forem: Lucas Paetow</title>
    <description>The latest articles on Forem by Lucas Paetow (@lptw).</description>
    <link>https://forem.com/lptw</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%2F239159%2F75a5dedc-3918-46e6-b61f-31e07264fc93.jpg</url>
      <title>Forem: Lucas Paetow</title>
      <link>https://forem.com/lptw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lptw"/>
    <language>en</language>
    <item>
      <title>Innovation from within the team?</title>
      <dc:creator>Lucas Paetow</dc:creator>
      <pubDate>Wed, 14 Jul 2021 12:16:08 +0000</pubDate>
      <link>https://forem.com/studio_m_song/innovation-from-within-the-team-20co</link>
      <guid>https://forem.com/studio_m_song/innovation-from-within-the-team-20co</guid>
      <description>&lt;p&gt;(Photo by &lt;a href="https://unsplash.com/@sunlifter?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Tomasz Frankowski&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you bring innovation to long term client projects?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can you still be creative and try wild ideas?
&lt;/h3&gt;

&lt;p&gt;We are working on a big project with many other people for quite some time now and we all will be working there for quite some more time. We have our set meetings, alignments, refinements, plannings, lunch times, reviews, and everything else for a smooth ride. But sometimes I wish I could bring more to the table, add my own ideas to existing stories or create new ones entirely. &lt;/p&gt;

&lt;p&gt;Many of us have some expertise through other &lt;a href="https://dev.to/s2engineers/do-i-need-to-do-private-side-projects-to-be-become-a-professional-web-developer-5137"&gt;(side) projects&lt;/a&gt; or previous jobs and have ideas in that direction. For example, I really enjoy working with &lt;a href="https://dev.to/lptw/series/9148"&gt;animations&lt;/a&gt; and therefore often see opportunities where to add them to increase the usability of the project. If I see some possibility to add them, I could of course write a ticket but it might never see the light of day on the bottom of the backlog (even if it suits the long term goals of the client).&lt;/p&gt;

&lt;h3&gt;
  
  
  But should it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Is this kind of thinking more of a luxury problem? &lt;/li&gt;
&lt;li&gt;Does the client always know which ticket order is best because in the end, all we can do is give advice to the best of our knowledge and priorities are always shifting anyways?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What about you
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Were you able to convince your client to let you bring in your own ideas to even further improve the product? &lt;/li&gt;
&lt;li&gt;If so, how? &lt;/li&gt;
&lt;li&gt;With your own process like an “innovation sprint” or separate backlog? &lt;/li&gt;
&lt;li&gt;Or did you find another solution entirely?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>discuss</category>
      <category>help</category>
      <category>webdev</category>
      <category>innovation</category>
    </item>
    <item>
      <title>Advance your animations cRAFt to the next level</title>
      <dc:creator>Lucas Paetow</dc:creator>
      <pubDate>Wed, 14 Oct 2020 12:29:56 +0000</pubDate>
      <link>https://forem.com/studio_m_song/advance-your-animations-craft-to-the-next-level-1heg</link>
      <guid>https://forem.com/studio_m_song/advance-your-animations-craft-to-the-next-level-1heg</guid>
      <description>&lt;h2&gt;
  
  
  The Javascript way
&lt;/h2&gt;

&lt;p&gt;When animations get more complex and page reflows (the browser's process of recalculating element dimensions &lt;a href="https://dev.to/s2engineers/better-animations-with-this-one-flip-n-trick-205a"&gt;Read more about it in the first part of this series&lt;/a&gt;) can’t be avoided, we need help from JavaScript to achieve smooth motion.&lt;/p&gt;

&lt;p&gt;With these JavaScript animations, we can't just declare a transition time and easing function (like with CSS transitions), we have to create them ourselves. This will get better eventually with the web animation API, &lt;a href="https://caniuse.com/#search=Web%20Animations%20API"&gt;whichs support is still not great for older browsers&lt;/a&gt;. Until then, we have to manually update the screen in many little steps to make it seem fluid. A good way to do it is with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame"&gt;requestAnimationFrame&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before requestAnimationFrame was a widely available, &lt;code&gt;setTimeout&lt;/code&gt; or &lt;code&gt;setInterval&lt;/code&gt; were used for this 'updating-the-screen-in-many-little-steps'-mechanism. To make them run every frame of a 60 Hz display, they both were given a timing argument of &lt;code&gt;1000/60&lt;/code&gt; milliseconds. But this was a hack and sometimes, depending on the complexity of the animation, the browser couldn't make it with the calculation to the next screen update / interval / step (roughly 10ms). The animation wouldn't progress in the current frame but twice in the next one. This effect can add up and the animation might appear to be buggy.&lt;/p&gt;

&lt;h4&gt;
  
  
  requestAnimationFrame to the rescue.
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;requestAnimationFrame&lt;/code&gt; helps to orchestrate the animations and will ensure to run a callback / an animation step before the next screen update. It tells the browser about the intention of animating something and the browser in return can prepare and optimize beforehand.&lt;br&gt;
Keep in mind that this function is only animating one frame. To use this in a full-scale animation, it needs to run again and again until the animation is done. This can be done with the function calling itself after each small step (a function calling itself is also known as a recursive function):&lt;/p&gt;

&lt;p&gt;This is a very basic animation function taken from &lt;a href="https://javascript.info/js-animation#structured-animation"&gt;JavaScript.info&lt;/a&gt; (but with variables renamed for clarity):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function animateWith({duration, easing, animationStep}) {

  let startTime = performance.now();

  requestAnimationFrame(function animation(currentTime) {
    let timeFraction = (currentTime - startTime) / duration;
    if (timeFraction &amp;gt; 1) timeFraction = 1;

    let progress = easing(timeFraction)

    animationStep(progress);

    if (timeFraction &amp;lt; 1) {
      requestAnimationFrame(animation);
    }

  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(This might look complicated at first but don’t be intimidated, we will go through this in a bit)&lt;/p&gt;

&lt;p&gt;It will be used like this (e.g. for animating the width of an element):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let element = document.getElementByID("progress")

animateWith({
  duration: 1000,
  easing(timeFraction) {
    return timeFraction;
  },
  animationStep(progress) {
    element.style.width = progress * 100 + '%';
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implementing this "animation engine" can be done differently but most implementations revolve around some key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a way to keep track of the animation progress (time elapsed of a total time can be expressed as progress),&lt;/li&gt;
&lt;li&gt;the change in the DOM layout based on that progress&lt;/li&gt;
&lt;li&gt;re-running the function again until the duration is up, often by recalling itself&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The Animation Function explained
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;The whole animation function begins by setting a starting time, which is kept alive in a closure (or stored in a variable)&lt;/li&gt;
&lt;li&gt;The inner function (the actual animation function) is called within the next frame&lt;/li&gt;
&lt;li&gt;In here the current progress of the animation, the &lt;code&gt;timeFraction&lt;/code&gt;, gets determined by subtracting the starting time from the current time (note for the current time parameter: requestAnimationFrame automatically gets a timestamp as an argument when it is called, which is used here for the current time). The resulting difference (the absolute time progressed since the starting time) will be divided by the duration to give us a relative time value between 0 and 1 of how much the full duration is already passed.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This &lt;code&gt;timeFraction&lt;/code&gt; is also used for the easing of the animation (the speeding up or slowing down of the motion to make it seem more natural). To archive this, the &lt;code&gt;timeFraction&lt;/code&gt; will get transformed to fit an easing curve (or a curve on a XY-coordinate graph — suddenly math becomes useful again)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;not transforming the values at all (just returning them) is equal to a linear easing, the motion will be at the same pace for the whole duration. For example a linear progression for numbers from 0-1 could be &lt;code&gt;0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In something else, like an ease-in function, the numbers would be transformed to the power of 2 (seen below) and our example numbers from the linear progression would look differently: &lt;code&gt;0.01, 0.04, 0.09, 0.16, 0.25, 0.36, 0.49, 0.64, 0.81, 1&lt;/code&gt;. They start much slower at first but progress faster in the second half
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function quad(timeFraction) {
// pow is the power of n
  return Math.pow(timeFraction, 2)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;more easing functions can be found here &lt;a href="https://easings.net/"&gt;Easing Functions Cheat Sheet&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The transformed timing fraction (progress) is then given to the actual DOM-changing &lt;code&gt;animationStep&lt;/code&gt; function. Since the progress is always between 0 and 1, it's great for the use of percentage-based value changes&lt;/li&gt;
&lt;li&gt;The last step is to determine if the function should run again. This is also based on progress and the reason why it can’t or shouldn't succeed 1 as value, because 1 means 100% of the duration is passed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Great, let's see it in action
&lt;/h4&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/still-field-t31vi"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;CODE EXAMPLE&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://codesandbox.io/s/github/LucasPaetow/rAF-Animation/tree/master/"&gt;CodeSandbox&lt;/a&gt; to see the code&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://boring-bohr-d84e30.netlify.app/"&gt;live site&lt;/a&gt; to just see it in action&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Some tips and tricks
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you want to animate properties that you also need for the calculations, like &lt;code&gt;height&lt;/code&gt; or &lt;code&gt;width&lt;/code&gt;, you can use &lt;code&gt;minHeight/ maxHeight&lt;/code&gt; or &lt;code&gt;minWidth/maxWidth&lt;/code&gt; for the animation instead. This way you won't have difficulties recalculating the original values again.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Animating values from 0 to your desired value is just &lt;code&gt;desiredValue * progress&lt;/code&gt; and the opposite is &lt;code&gt;desiredValue * (1-progress)&lt;/code&gt; but if you want to animate partial values to 1, the formula gets a little more complicated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;partialValue + (desiredValue - partialValue) * progress&lt;/code&gt; or for the opposite &lt;code&gt;partialValue + (desiredValue - partialValue) * (1 * progress)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only new thing here is &lt;code&gt;(desiredValue - partialValue)&lt;/code&gt;, which means the amount without the starting value. For example, animating opacity from 0.25 to 1 this part would be the missing 0.75 and only these get animated.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codeiscolorful</category>
      <category>animation</category>
    </item>
    <item>
      <title>Better Animations with this one FLIP`n trick</title>
      <dc:creator>Lucas Paetow</dc:creator>
      <pubDate>Tue, 06 Oct 2020 15:20:17 +0000</pubDate>
      <link>https://forem.com/studio_m_song/better-animations-with-this-one-flip-n-trick-205a</link>
      <guid>https://forem.com/studio_m_song/better-animations-with-this-one-flip-n-trick-205a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Animations are great. They guide the user focus and can make a site feel snappy and fast. But if done incorrectly, they will do the opposite: they will make the site feel sluggish and janky.&lt;/p&gt;

&lt;h3&gt;
  
  
  Janky?
&lt;/h3&gt;

&lt;p&gt;When the browser needs to change the appearance of an element, it needs to recalculate every element affected by the change.&lt;br&gt;
When a lot of elements are affected and need to be recalculated, the browser has to work longer for the calculations. If this process exceeds the time the screen takes to refresh it, it skips a frame.&lt;/p&gt;

&lt;p&gt;An example: Most devices run at 60 frames per second. So the recalculation per frame shouldn’t take longer than roughly 10ms (1sec/60 =&amp;gt; 16.66ms - housekeeping from the browser). Otherwise, the animation is not smooth and “stutters”&lt;/p&gt;

&lt;h2&gt;
  
  
  How to do it then?
&lt;/h2&gt;

&lt;p&gt;There are two ways to make animations feel smooth and keep them at 60 FPS and jank-free:&lt;/p&gt;

&lt;h3&gt;
  
  
  The CSS way
&lt;/h3&gt;

&lt;p&gt;Every change to the DOM triggers the calculation of the “critical render path” to bring the pixel updates to the screen. This involves up to 3 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layout / Reflow&lt;/strong&gt;&lt;br&gt;
In this step, the browser starts calculating the dimensions and space for each element, starting from the document root. This results in the elements &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model"&gt;box-model&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Paint&lt;/strong&gt;&lt;br&gt;
This step is about creating layers and filling them with pixels. Including but not limited to text, colors, images, borders, and shadows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compositing&lt;/strong&gt;&lt;br&gt;
Here the browser will send the layers to the GPU to finally draw them in the correct order onto the screen. This happens on a different thread.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more of these steps are involved, the more work the browser has to do. Since the &lt;code&gt;transform&lt;/code&gt; and &lt;code&gt;opacity&lt;/code&gt; properties only require changes of the compositing step, they are very efficient.&lt;/p&gt;

&lt;h4&gt;
  
  
  How? With a FLIP
&lt;/h4&gt;

&lt;p&gt;You might think, these transforms may only really work for small visual changes (e.g. a button press) but they can also animate seemingly heavy layout changes like expanding a card or transitioning to a new view.&lt;/p&gt;

&lt;p&gt;Instead of scaling / transitioning / rotating an elements' starting appearance to make it look like the end appearance, (for example scaling up a card to a full-screen view) you would do the opposite: change the card to its final form and scale it down to the previous size without animation. This step happens so fast, it looks like nothing happened. Afterwards, you animate the difference (which is now a scale operation).&lt;/p&gt;

&lt;p&gt;This process involves 4 steps and therefore coined the term FLIP (First, Last, Invert, Play - &lt;a href="https://aerotwist.com/blog/flip-your-animations/"&gt;originaliy by Paul Lewis&lt;/a&gt;):&lt;/p&gt;

&lt;h4&gt;
  
  
  An Example: Apple News
&lt;/h4&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/jolly-flower-f6byv"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;




&lt;p&gt;CODE EXAMPLE&lt;br&gt;
&lt;a href="https://codesandbox.io/s/github/LucasPaetow/FLIP-Animation/tree/master"&gt;CodeSandbox&lt;/a&gt; to see the code&lt;br&gt;
&lt;a href="https://goofy-saha-574aca.netlify.app/"&gt;live site&lt;/a&gt; to just see it in action&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First&lt;/strong&gt;: get the dimensions of the starting element
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;first = collapsedImage.getBoundingClientRect();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick refresher: &lt;code&gt;getBoundingClientRect()&lt;/code&gt; returns an object of values for height, width, top, right, bottom, left, x and y.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Last&lt;/strong&gt;: change the layout and get its dimensions.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  collapsedCard.classList.add("active");
    ...
  last = fullscreenImage.getBoundingClientRect();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, changing the layout is done via modifying the display-property. It's a simple yet very visual change, which triggers reflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Invert&lt;/strong&gt;: Transform the element from it's last form to the starting form
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  widthDifference = first.width / last.width;
  heightDifference = first.height / last.height;
  xDifference = first.left - last.left;
  yDifference = first.top - last.top;

    ...
  requestAnimationFrame(() =&amp;gt; {
        fullscreenImage.style.transform = `translate(${xDifference}px, ${yDifference}px) scale(${widthDifference}, ${heightDifference})`;
        fullscreenImage.style.transition = "transform 0ms";
    ...
  });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the next possible repaint, the image gets translated and scaled so it is placed over on the starting image. This change happens without a transition and is not visually noticeable (if the calculation for the change takes under 100ms, we will perceive it as instantaneously)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Play&lt;/strong&gt;: Visually animate the difference
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  requestAnimationFrame(() =&amp;gt; {
        ...
    requestAnimationFrame(() =&amp;gt; {
        fullscreenImage.style.transform = "";
        fullscreenImage.style.transition = `transform ${transitionTime}ms ${easing}`;
    });
  });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, on the next possible repaint, the changes get reverted, but this time with an easing. So it falls back into its original shape with a nice and smooth transition.&lt;br&gt;
This has to be done with at least one frame between the two actions. Otherwise, javascript would just batch the commands together and we wouldn't see any visual effects. For the separation of these commands, we can use a requestAnimationFrame within a requestAnimationFrame. More on this topic will follow soon.&lt;/p&gt;

&lt;h4&gt;
  
  
  Things to consider
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Some CSS properties (especially &lt;code&gt;border-radius&lt;/code&gt;) might look different during this process and ruin the illusion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example: a 200x200px box with 'border-radius: 20px' and &lt;code&gt;transform: scale(0.5)&lt;/code&gt; looks different than a 100x100px box with the same border-radius (percentage based values work, though)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beware: since it has to be done for each element, it gets complicated fast, especially if multiple elements are affected (modern frameworks might help reduce the complexity)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stay tuned
&lt;/h3&gt;

&lt;p&gt;More on requestAnimationFrame and performant javascript animation will follow next week.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>codeiscolorful</category>
      <category>animation</category>
    </item>
  </channel>
</rss>
