<?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: Vineet Kalghatgi</title>
    <description>The latest articles on Forem by Vineet Kalghatgi (@vineet192).</description>
    <link>https://forem.com/vineet192</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%2F302667%2F461e4c37-720f-4c2a-86e5-21c681a550db.jpg</url>
      <title>Forem: Vineet Kalghatgi</title>
      <link>https://forem.com/vineet192</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vineet192"/>
    <language>en</language>
    <item>
      <title>Timeline animation with HTML, CSS and JavaScript</title>
      <dc:creator>Vineet Kalghatgi</dc:creator>
      <pubDate>Sun, 28 Jan 2024 01:04:29 +0000</pubDate>
      <link>https://forem.com/vineet192/timeline-animation-with-html-css-and-javascript-3cf7</link>
      <guid>https://forem.com/vineet192/timeline-animation-with-html-css-and-javascript-3cf7</guid>
      <description>&lt;p&gt;A timeline animation is useful when you want to display information with respect to the passage of time. For instance, you can use it in a portfolio website to show your journey as a professional: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2020 - Graduated from XYZ University&lt;/p&gt;

&lt;p&gt;2021 - Joined a brilliant startup&lt;/p&gt;

&lt;p&gt;2023 - Promoted to Senior Developer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or you can use it in a landing page to describe an organization's history and culture:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;1994 - Amazon was founded in a garage&lt;/p&gt;

&lt;p&gt;1997 - Amazon IPOs at $18.00/share&lt;/p&gt;

&lt;p&gt;1998 - Expands beyond books&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;...you get the idea.&lt;/p&gt;




&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;

&lt;p&gt;A container div that contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The central vertical line&lt;/li&gt;
&lt;li&gt;Cards positioned to the right&lt;/li&gt;
&lt;li&gt;Cards positioned to the left
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"line"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'left card'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;2023&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Add your text here&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'right card'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;2022&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Add your text here&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'left card'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;2021&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Add your text here&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'right card'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;2020&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Add your text here&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'left card'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;2020&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Add your text here&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CSS
&lt;/h2&gt;

&lt;p&gt;We shall keep the line centrally positioned relative to the container div by using the &lt;code&gt;relative&lt;/code&gt; and &lt;code&gt;position:absolute&lt;/code&gt; classes. For the cards, the container will behave as a column flexbox using the &lt;code&gt;flex-direction:column&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;nowrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;overflow-x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The card class applies a simple border and sets the initial &lt;code&gt;opacity&lt;/code&gt; to 0. We will use the &lt;code&gt;transition&lt;/code&gt; property to fade it into full opacity and to move it towards the center smoothly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* opacity 0 because it should start off invisible */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will need a &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; class that controls the positioning of the card element. These classes have an initial &lt;code&gt;transform&lt;/code&gt; of &lt;code&gt;100%&lt;/code&gt; and &lt;code&gt;-100%&lt;/code&gt; since we want them to start moving in from the left or right. Using these classes as selectors, we'll display arrow heads with the &lt;code&gt;::after&lt;/code&gt; pseudo elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.right&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.left&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Arrow heads */&lt;/span&gt;
&lt;span class="nc"&gt;.card.left&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-left-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-22px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-22px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card.right&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-right-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-22px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-22px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/docs/Web/API/IntersectionObserver"&gt;&lt;code&gt;IntersectionObserver&lt;/code&gt;&lt;/a&gt; API will allow us to fire a callback whenever the cards come into the view of the screen. This callback will kick off the animation of fading the &lt;code&gt;opacity&lt;/code&gt; back to 1 and moving the cards in from the left or right by setting the &lt;code&gt;transform&lt;/code&gt; to 0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;initObserver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;translateX(0)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;opacity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt; &lt;span class="c1"&gt;// Fire the callback once 80% of the card is visible&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Attach the interesection observer after the window loads&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initObserver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mobile Responsiveness
&lt;/h2&gt;

&lt;p&gt;We can add a couple of media queries in our CSS file for smaller screens to &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce the width of the card&lt;/li&gt;
&lt;li&gt;Reduce the margins&lt;/li&gt;
&lt;li&gt;Bring the initial position of the cards closer to the center &lt;/li&gt;
&lt;li&gt;Reduce the font size
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* left to right doesn't work on some smaller screens so 
          both cards will have right -&amp;gt; left animation */&lt;/span&gt;

    &lt;span class="nc"&gt;.left&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.right&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.left&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.right&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;19vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;7px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.left&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.right&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;And that's it! You've got yourself a simple timeline animation that doesn't use any external dependencies. Here's a working demo:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/vineet192/embed/ZEPaddK?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Open Source Restaurant Menus with Next.js, Express.js and MongoDB</title>
      <dc:creator>Vineet Kalghatgi</dc:creator>
      <pubDate>Mon, 22 Jan 2024 01:58:46 +0000</pubDate>
      <link>https://forem.com/vineet192/open-source-restaurant-menus-with-nextjs-expressjs-and-mongodb-4bc9</link>
      <guid>https://forem.com/vineet192/open-source-restaurant-menus-with-nextjs-expressjs-and-mongodb-4bc9</guid>
      <description>&lt;h1&gt;
  
  
  Check out the live app &lt;a href="https://restaurant-emenu.vercel.app/"&gt;here&lt;/a&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A bulk of the adopters of digital menus since the pandemic were full-service operators, with 54% of casual dining, 50% of fine dining and 48% of family dining restaurants shifting their menus online, according to the National Restaurant Association’s 2021 State of the Restaurant Industry report. Forty percent of operators also added a contactless or mobile payment option last year, according to the NRA. &lt;/p&gt;

&lt;p&gt;It’s not likely that operators are going to shift back. Forty-seven percent of owners or managers that already offer digital menus through a URL or online platform said they are “very likely” to switch to all digital menus, according to Square’s survey.&lt;br&gt;
-- &lt;cite&gt;&lt;a href="https://www.restaurantdive.com/news/88-of-restaurants-considering-swapping-to-digital-menus-survey-says/595558/"&gt;88% of restaurants considering swapping to digital menus, survey says&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, most of the SaaS models for digital menus today are pay-to-use ranging from &lt;b&gt;$15/month&lt;/b&gt; to &lt;b&gt;$100/month&lt;/b&gt; for their lowest tiers, granted the expensive ones offer more end-to-end features.&lt;/p&gt;

&lt;p&gt;I hypothesize that some, if not most, restaurants would be satisfied with a simple mapping of their physical paper menus into a read-only digital version. So, I built an open-source app to solve this. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://restaurant-emenu.vercel.app/menu/6598bbb8e7c555b008b3ba72"&gt;Live menu example&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The main features
&lt;/h2&gt;

&lt;p&gt;Users, the target demographic of whom are "Restaurant owners", can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create/Delete/Search Menus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfywvtf90m0t4o0xb4xi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfywvtf90m0t4o0xb4xi.png" alt="Homepage" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update them by

&lt;ul&gt;
&lt;li&gt;Adding categories like "Appetizers", "Main Course" etc.&lt;/li&gt;
&lt;li&gt;Adding dishes (with a price, description, and title)&lt;/li&gt;
&lt;li&gt;Updating the Restaurant title&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg61ssqaz9ca4w8tm930.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg61ssqaz9ca4w8tm930.png" alt="Editing a Menu" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate and share a public link for each menu created&lt;/li&gt;
&lt;li&gt;Generate a QR code for the aforementioned public link&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mt31mzemv6b7zwpkkuy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mt31mzemv6b7zwpkkuy.png" alt="Options for each menu" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;User authentication is handled by &lt;a href="https://firebase.google.com/"&gt;Google Firebase&lt;/a&gt;. The app currently implements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signup/Login with an email, password combo&lt;/li&gt;
&lt;li&gt;Anonymous guest logins&lt;/li&gt;
&lt;li&gt;Account deletion&lt;/li&gt;
&lt;li&gt;Password recovery via Email&lt;/li&gt;
&lt;li&gt;Email verification on signup&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frontend
&lt;/h2&gt;

&lt;p&gt;I used &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; + &lt;a href="https://react.dev/"&gt;React&lt;/a&gt;. The codebase is currently all Javascript. I'm planning on migrating it to Typescript soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Middleware
&lt;/h2&gt;

&lt;p&gt;The RESTful APIs are served by a &lt;a href="https://nodejs.org/en"&gt;Node.js&lt;/a&gt; + &lt;a href="https://expressjs.com/"&gt;Express.js&lt;/a&gt; server. The server performs CRUD operations on a &lt;a href="https://www.mongodb.com/atlas/database"&gt;MongoDB Atlas&lt;/a&gt; instance. Object modeling with &lt;a href="https://mongoosejs.com/"&gt;Mongoose Js&lt;/a&gt; helped simplify things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database
&lt;/h2&gt;

&lt;p&gt;The database is a MongoDB instance running on the MongoDB Atlas SaaS. A single collection maps each &lt;b&gt;user&lt;/b&gt; with their respective &lt;b&gt;menu&lt;/b&gt; information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/vineet192/Restaurant-Emenu/"&gt;Next.js Frontend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vineet192/restaurant-emenu-backend"&gt;Node.js Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Upcoming Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Images for dishes (probably on a free tier AWS S3 account)&lt;/li&gt;
&lt;li&gt;Toggle to make menus private/public&lt;/li&gt;
&lt;li&gt;Custom fonts&lt;/li&gt;
&lt;li&gt;Custom banner backgrounds&lt;/li&gt;
&lt;li&gt;User-provided logos as opposed to Text titles&lt;/li&gt;
&lt;li&gt;Custom color palettes&lt;/li&gt;
&lt;li&gt;More sign-in options like Google, Facebook, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know what you think, and thanks for reading!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>You NEED to know awk</title>
      <dc:creator>Vineet Kalghatgi</dc:creator>
      <pubDate>Thu, 14 Oct 2021 20:11:11 +0000</pubDate>
      <link>https://forem.com/vineet192/you-need-to-know-awk-33b1</link>
      <guid>https://forem.com/vineet192/you-need-to-know-awk-33b1</guid>
      <description>&lt;h2&gt;
  
  
  In Brief
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;awk&lt;/code&gt; is a powerfull command line tool found included in all modern GNU/linux distributions. It is often excluded from beginner level Linux tutorials, where more fundamental commands like &lt;code&gt;cd&lt;/code&gt; , &lt;code&gt;pwd&lt;/code&gt;, &lt;code&gt;ls&lt;/code&gt; etc are given more priority, and rightfully so. One must have a good grasp on the basic commmand line tools in order  to harness the full power of awk. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;awk&lt;/code&gt; in essence is a pattern scanning and processing language, emphasis on the &lt;em&gt;language&lt;/em&gt; part because &lt;code&gt;awk&lt;/code&gt; possesses functionality akin to most mainstream programming languages. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;awk&lt;/code&gt; loves tabulated data. So to begin with, you'll need a piece of text represented as columns delimited by some common character. You see this pattern often in shells, for instance, the &lt;code&gt;ls -l&lt;/code&gt; command that prints file information delimited by a space :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls -l                                                                                                                              
total 24                                                                                                                                               
lrwxrwxrwx   1 root   root       7 Sep  7 07:45 bin -&amp;gt; usr/bin                                                                                         
drwxr-xr-x   1 root   root       0 Apr 15  2020 boot                                                                                                   
drwxr-xr-x   9 root   root     480 Sep  8 13:34 dev                                                                                                    
drwxr-xr-x   1 root   root    1902 Sep  7 20:29 etc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, for the sake of demonstration, let us use the following &lt;code&gt;sample.txt&lt;/code&gt; to illustrate &lt;code&gt;awk&lt;/code&gt;'s capabilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;emp_id;emp_name;emp_sex;emp_salary;emp_yoj;
1;john;male;3000;2014
2;sarah;female;2500;2018
3;lily;female;5000;2012
4;jack;male;3000;2014
5;mark;male;2500;2017
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;awk&lt;/code&gt; is like any other UNIX command, i.e it takes in options and arguments, however, its power lies in a script argument that can either be included inline or as an external file with a .awk extension. An &lt;code&gt;awk&lt;/code&gt; script has the following basic structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEGIN {commands}
/pattern1/ {commands}
/pattern2/ {commands}
...
/patternN/ {commands}
END {commands}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In essence, &lt;code&gt;awk&lt;/code&gt; loops through each row of the input file and executes commands based on conditions. The patterns correspond to regex patterns that you can use to distinguish different rows. The default pattern matches every row. &lt;/p&gt;

&lt;p&gt;Commands following the BEGIN keyword are executed before the loop, and the ones following the END keyword, after.&lt;br&gt;
&lt;em&gt;Note: the numbering of the pattern has no correlation whatsoever with the row number&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Alright! Lets process some text&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Print only the name and salary of all employees
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;awk 'BEGIN {FS = ";"}
{print $2 " " $4}' test.txt

emp_name emp_salary
john 3000
sarah 2500
lily 5000
jack 3000
mark 2500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The string argument, marked by single quotes, is the &lt;code&gt;awk&lt;/code&gt; script mentioned before. Here's the rundown of its working step by step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the delimiter to ";" using the predefined FS (Field Seperator) variable before processing any rows.&lt;/li&gt;
&lt;li&gt;For every row, print the 3rd and 4th column separated by a space.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Print all the male names.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;awk ' BEGIN { FS = ";" }
{if($3 == "male") print $2;}' test.txt

john
jack
mark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script basically instructs &lt;code&gt;awk&lt;/code&gt; to :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the delimiter to ";" before processing any rows.&lt;/li&gt;
&lt;li&gt;For every row, check if the third column ($3) is "male", if true then print the second column ($2) i.e the name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: A command without a pattern applies to every row&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Derive the average salary.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;awk ' BEGIN { FS = ";"; sum = 0; }
{if (NR &amp;gt; 1) sum += $4;}
END{
    total = NR - 1;
    avg = sum / total;
    print avg;
}' test.txt

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

&lt;/div&gt;



&lt;p&gt;FS is one of many variables have been predefined. In this example, however, we will be defining a couple custom variables. So here is the rundown for this command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before processing any rows, set the delimiter to ";" and a custom variable &lt;code&gt;sum&lt;/code&gt; to 0.&lt;/li&gt;
&lt;li&gt;For every row, if the row number is greater than one, increment the sum variable. 
&lt;em&gt;Note: here the NR variable is predefined and it gives us the row number&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;At the end, after all rows have been processed, set a variable &lt;code&gt;total&lt;/code&gt; to &lt;code&gt;NR - 1&lt;/code&gt;, calculate average as &lt;code&gt;sum / total&lt;/code&gt; and print it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, these three examples encapsulate the sheer power and versatility of the &lt;code&gt;awk&lt;/code&gt; command. It supports features like variables, if else blocks and arithmetic evaluation as seen above, all of which you can find in full fledged programming languages.&lt;/p&gt;

&lt;p&gt;But this is just the tip of the iceberg, &lt;code&gt;awk&lt;/code&gt; even supports arrays, for loops, processing multiple files with just one script, and much more. Therefore &lt;code&gt;awk&lt;/code&gt; is more than just a convenient command line tool, it is a powerful language in in of itself and hopefully, this inspired you to learn more about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;p&gt;If you're interested you can check out &lt;a href="https://www.gnu.org/software/gawk/manual/gawk.html"&gt;The GNU Awk's user guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>bash</category>
    </item>
    <item>
      <title>The Impostor Syndrome</title>
      <dc:creator>Vineet Kalghatgi</dc:creator>
      <pubDate>Fri, 18 Sep 2020 14:28:50 +0000</pubDate>
      <link>https://forem.com/vineet192/the-impostor-syndrome-44df</link>
      <guid>https://forem.com/vineet192/the-impostor-syndrome-44df</guid>
      <description>&lt;p&gt;Developers are viewed by the society as mystical beings performing witchcraft on anything with a keyboard. If you are a developer or even remotely associated with computers, Movie and TV-studios will call you by that magic 6-letter word  &lt;code&gt;HACKER&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You may be depicted as someone who can : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a GUI interface using visual basic to track the killers IP address &lt;iframe width="710" height="399" src="https://www.youtube.com/embed/hkDD03yeLnU"&gt;
&lt;/iframe&gt;
&lt;/li&gt;
&lt;li&gt;Get the power back on from an outage by just typing on your keyboard &lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Q1CzCQ4eT0g"&gt;
&lt;/iframe&gt;
&lt;/li&gt;
&lt;li&gt;Go full on tag team with a fellow &lt;code&gt;HACKER&lt;/code&gt; to type on the same keyboard at the same time to achieve Turbo Hacking. &lt;iframe width="710" height="399" src="https://www.youtube.com/embed/msX4oAXpvUE"&gt;
&lt;/iframe&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well all jokes aside, my point is that programmers are perceived as being extremely smart and when we find ourselves googling solutions or copy pasting snippets, its easy to fall into the trap of feeling like an impostor.&lt;/p&gt;

&lt;p&gt;I would argue that just the mere action of looking up solutions does not make you any less of a developer, what is important is that you understand the structure and logical flow of whatever you're building. When you achieve that, everything else is just minor details.&lt;/p&gt;

&lt;p&gt;If you think about it, googling solutions is no different than going through a book to find the answers, only you are doing it with a powerful search engine. In fact, it is more impressive that developers as a whole generally do not mug up solutions, rather they always figure it out albeit with some help from StackOverflow.&lt;/p&gt;

&lt;p&gt;So if you ever find yourself feeling like an impostor or someone who does not know enough, know that as a developer, you have developed or are developing an implicit skill of understanding solutions rather than remembering them. Therefore it is fine if you forget how to read files in Java, or if its arr.size() or arr.length, whats important is the bigger picture of what you're trying to solve.&lt;/p&gt;

&lt;p&gt;I understand that a deeper conversation can be had on this topic, but this was just my lighthearted take. So in closing I will leave this xkcd panel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PBC4r5oX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://imgs.xkcd.com/comics/impostor_syndrome.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PBC4r5oX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://imgs.xkcd.com/comics/impostor_syndrome.png" alt="imposter_syndrome" width="318" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Why I switched to Linux full time</title>
      <dc:creator>Vineet Kalghatgi</dc:creator>
      <pubDate>Wed, 16 Sep 2020 19:01:06 +0000</pubDate>
      <link>https://forem.com/vineet192/why-i-switched-to-linux-full-time-4lah</link>
      <guid>https://forem.com/vineet192/why-i-switched-to-linux-full-time-4lah</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmki9yzocm9yn1r8rmfpx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmki9yzocm9yn1r8rmfpx.png" alt="My current homescreen setup" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;My current homescreen setup&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have a 4 year old HP pavilion which until recently, was craving for an upgrade. I had also been wanting to get rid of Windows for the longest time, so killing two birds with one stone, I replaced the existing HDD with a new SSD and performed a clean install of &lt;em&gt;Pop_os!&lt;/em&gt; developed by &lt;em&gt;System76&lt;/em&gt; on it (No dual booting). I now use the HDD as an external USB drive with the help of a case, eliminating any worry of data backup.&lt;/p&gt;

&lt;p&gt;So why did I not just reinstall Windows on the new SSD ? Well let me explain&lt;/p&gt;


&lt;h3&gt;
  
  
  1. Linux is completely free.
&lt;/h3&gt;

&lt;p&gt;This holds good not only for the operating system and the kernel, but also for all the software that come bundled with it. When I first bought my laptop, I realized that it did not come with the MS office suite free which means critical functionality like editing documents, excel sheets etc were locked.&lt;/p&gt;

&lt;p&gt;I had to turn to open sourced alternatives like LibreOffice writer, which is coincidentally the default document editing application on most Linux distributions. Not to mention the plethora of paid/proprietary software on windows including Antivirus (Which you probably wont need for Linux as malware affecting Linux is rare, probably owing to its unpopularity currently).&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Pop_os! gets out of your way.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff1lvydljecgpvh99bo3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff1lvydljecgpvh99bo3v.png" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Gnome multitasking with virtual desktops&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While the Gnome desktop environment, the default for pop OS, has its fair share of criticisms, it does hold true to its values of getting out of your way to get work done. Gnome has focused on building a very minimal yet functional desktop environment which is intuitive enough for the average user. The layout may be a bit jarring due its departure from the traditional windows design, but once you start using it, you’ll learn to understand that its almost smartphone-esque in its look and feel.&lt;/p&gt;

&lt;p&gt;If the default design and working is not up to your liking, then you can tweak and customize it however you want. You can get it to behave like MacOS or Windows complete with a start menu. This is one of the advantages of having a completely open sourced operating system, is that you have complete freedom over its customization. Think of it as downloading new launchers/icon-packs/skins on your android phone. You can have it look however you want if you are willing to put in some time for personalisation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv9c3q0pq0jbqzmp8sf7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv9c3q0pq0jbqzmp8sf7z.png" width="600" height="337"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Notifications panel.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Notifications are located at the center of the top bar and applications are accessed through an application drawer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pop OS, as of its 20.04 release, has also released a window tiling manager that is baked into the operating system by default. This allows you to tile and organize all open windows at the click of a button which is extremely useful when multitasking.&lt;/p&gt;

&lt;p&gt;It provides a comprehensive list of keyboard shortcuts that are easy to pick up and dare I say even quite intuitive. Here are some shortcuts that I use everyday (while some are similar to windows shortcuts, it is worth noting that the default gnome is built in such a way that it encourages their use better than windows in my opinion) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;super : Opens recent applications view.  
super + tab : cycles through open applications.

When in tiling mode  
super + g : toggle floating mode.  
super + arrow key : toggle between active windows.  
super + O : change window orientation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These were just a few, however you can find the rest on System76’s website&lt;/p&gt;

&lt;p&gt;&lt;a href="https://support.system76.com/articles/pop-keyboard-shortcuts/"&gt;Pop OS shortcuts&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Linux is very powerful and secure
&lt;/h3&gt;

&lt;p&gt;It should not come as a surprise that the kernel used by most servers as well as all phones using android is much more powerful and capable than Windows.&lt;/p&gt;

&lt;p&gt;Linux supports all the major programming languages ( C/C++, Python, Java, JavaScript etc) in a much more developer friendly way and possesses a much more powerful and versatile terminal than windows. Since Linux was built with servers and server administrators in mind, one can navigate the entire operating system using just the terminal. Something which would be an immense pain in the neck in Windows.&lt;/p&gt;

&lt;p&gt;The terminal might seem daunting for someone who has never used it before, but the beauty of user friendly distributions like Pop OS is that you don’t have to! You can navigate and control the OS through the GUI like you would in windows or MacOS. However, that doesn’t mean that you can’t benefit from at least trying the terminal out. So here are some basic commands that can help boost your productivity :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd - used to change directories  
ls - list directory contents  
pwd - print name of current/working directory  
rm - remove files or directories  
mkdir - make directories  
rmdir - remove empty directories  
clear - clear the terminal screen  
touch - change file timestamps ( Can be used to create a new file)  
kill - send a signal to a process ( provide the PID as an argument)  
top - display Linux processes (task manager)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Linux is lightweight
&lt;/h3&gt;

&lt;p&gt;Compared to Windows, Linux uses far less memory on boot and that results in a much more responsive system, even when several applications are open and/or running in the background.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvojqsc1drz4me3mqbo1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvojqsc1drz4me3mqbo1d.png" alt="Memory usage with terminal and screenshot app open" width="800" height="378"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Memory usage with terminal and screenshot app open&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A lot of my development, especially in my most recent internship, involved using an android emulator which takes upto 2gb of your ram since its basically a virtual machine. This coupled with windows’ almost 4gb ram usage on boot was a recipe for disaster. Linux not only overcomes this but also provides an option to make it an even better experience. The Android Emulator can use hardware acceleration features to improve performance, sometimes drastically.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Package managers are way more organised that .exes and .msis
&lt;/h3&gt;

&lt;p&gt;The main way of installing software on Linux is through package managers. Think of package managers as an app store like the Google play store or Apple’s app store except all the applications are free and so are the updates. You can install/update/remove/purge applications with just a single line of command on the terminal and not have to worry about installers, exe files etc.&lt;/p&gt;

&lt;p&gt;It is also much more secure than windows as you are required to enter the lock password anytime you download/install or uninstall a new piece of software. This way is certainly better than displaying a pop up saying “Do you want to allow this app to make changes to your device ?”.&lt;/p&gt;

&lt;p&gt;So instead of scouring countless websites to find that one 64_bit.exe all you need to do is &lt;em&gt;sudo apt install&lt;/em&gt; anything you need.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Linux is developer friendly
&lt;/h3&gt;

&lt;p&gt;This is probably the main reason why I switched over. Linux simply does a better job of supporting developer activities a lot better than windows. Installing new development environments be it Flutter, Angular, React, Android etc is made extremely easy and painless with the terminal and package managers.&lt;/p&gt;

&lt;p&gt;In Windows, you might have to configure environment variables, build paths, sdk paths manually all of which is automated in Linux. So with the environment setup out of the way and taken care of, I can focus on actually developing software.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Sorting Visualizer built using flutter/dart</title>
      <dc:creator>Vineet Kalghatgi</dc:creator>
      <pubDate>Sat, 28 Dec 2019 12:47:02 +0000</pubDate>
      <link>https://forem.com/vineet192/sorting-visualizer-built-using-flutter-dart-17l2</link>
      <guid>https://forem.com/vineet192/sorting-visualizer-built-using-flutter-dart-17l2</guid>
      <description>&lt;p&gt;GitHub : &lt;a href="https://github.com/vineet192/Sorting-Visualiser"&gt;Sorting Visualizer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just a simple personal project because i'd been wanting to try out flutter for a while. The learning curve isn't too steep if you are already relatively well versed in java, c, c++ or even JavaScript.&lt;/p&gt;

&lt;p&gt;Anyways, since i'm still a beginner, I would love to hear your thoughts on it.&lt;/p&gt;

</description>
      <category>dart</category>
      <category>android</category>
    </item>
  </channel>
</rss>
