<?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: Po-Hsiang (Matthew) Lu</title>
    <description>The latest articles on Forem by Po-Hsiang (Matthew) Lu (@matteo1222).</description>
    <link>https://forem.com/matteo1222</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%2F860393%2F8c2ad86a-f7a2-417b-b250-680b65d0f103.png</url>
      <title>Forem: Po-Hsiang (Matthew) Lu</title>
      <link>https://forem.com/matteo1222</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/matteo1222"/>
    <language>en</language>
    <item>
      <title>feDisplacementMap Explained</title>
      <dc:creator>Po-Hsiang (Matthew) Lu</dc:creator>
      <pubDate>Fri, 15 Jul 2022 10:08:37 +0000</pubDate>
      <link>https://forem.com/matteo1222/explained-4a4b</link>
      <guid>https://forem.com/matteo1222/explained-4a4b</guid>
      <description>&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feDisplacementMap"&gt;feDisplacementMap&lt;/a&gt; is one of the SVG filters that always seems daunting for me to understand. But once I looked into it, it is not so complicated and is actually fun to play with. &lt;/p&gt;

&lt;p&gt;Let's first see what this SVG filter can do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FlKPefeF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7vqqxyc83do8pwjnuzx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FlKPefeF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7vqqxyc83do8pwjnuzx.png" alt="Diagram of how feDisplacementMap works" width="662" height="685"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;feDisplacementMap&lt;/code&gt; takes in two input source &lt;code&gt;in&lt;/code&gt; and &lt;code&gt;in2&lt;/code&gt;. &lt;code&gt;in&lt;/code&gt; is the image to be displaced, and &lt;code&gt;in2&lt;/code&gt; is used to calculated how &lt;code&gt;in&lt;/code&gt; will be displaced. In this case, we used a forest image for &lt;code&gt;in&lt;/code&gt; and an image created with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feTurbulence"&gt;feTurbulence&lt;/a&gt;. We can therefore create a ripple-like effect on the forest image.&lt;/p&gt;

&lt;p&gt;In essence, what &lt;code&gt;feDisplacementMap&lt;/code&gt; is doing is looping through each pixel on an image and move the pixel around based on a transformation formula.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transformation Formula
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;P'(x,y) ← P( x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a breakdown of the formula:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;P'(x, y)&lt;/code&gt; on the left is the coordinates after transformation&lt;/li&gt;
&lt;li&gt;The right part is how it is transformed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;XC(x,y)&lt;/code&gt; and &lt;code&gt;YC(x,y)&lt;/code&gt; means the RGB value of the given coordinates on the &lt;code&gt;in2&lt;/code&gt; image divided by 255, so it will be between 0 and 1&lt;/li&gt;
&lt;li&gt;The larger the &lt;code&gt;scale&lt;/code&gt; is, the more a pixel is displaced&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;filter&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;feDisplacementMap&lt;/span&gt; &lt;span class="na"&gt;in2=&lt;/span&gt;&lt;span class="s"&gt;"turbulence"&lt;/span&gt; &lt;span class="na"&gt;in=&lt;/span&gt;&lt;span class="s"&gt;"SourceGraphic"&lt;/span&gt; &lt;span class="na"&gt;scale=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; 
        &lt;span class="na"&gt;xChannelSelector=&lt;/span&gt;&lt;span class="s"&gt;"R"&lt;/span&gt; &lt;span class="na"&gt;yChannelSelector=&lt;/span&gt;&lt;span class="s"&gt;"G"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we compare the syntax of &lt;code&gt;feDisplacementMap&lt;/code&gt; and the transformation formula, we realize that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scale corresponds to &lt;code&gt;scale&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;xChannelSelector specifies which color channel to look at for &lt;code&gt;XC(x,y)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;yChannelSelector specifies which color channel to look at for &lt;code&gt;YC(x,y)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: SourceGraphic is the original input to the SVG filter, which is the forest image.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's the full example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;defs&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;filter&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"displace"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;feTurbulence&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"turbulence"&lt;/span&gt; &lt;span class="na"&gt;baseFrequency=&lt;/span&gt;&lt;span class="s"&gt;"0.1 0.1"&lt;/span&gt; &lt;span class="na"&gt;result=&lt;/span&gt;&lt;span class="s"&gt;"turbulence"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;feDisplacementMap&lt;/span&gt; &lt;span class="na"&gt;in2=&lt;/span&gt;&lt;span class="s"&gt;"turbulence"&lt;/span&gt; &lt;span class="na"&gt;in=&lt;/span&gt;&lt;span class="s"&gt;"SourceGraphic"&lt;/span&gt; &lt;span class="na"&gt;scale=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;xChannelSelector=&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt; &lt;span class="na"&gt;yChannelSelector=&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/defs&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;image&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://images.unsplash.com/photo-1441974231531-c6227db76b6e?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=1171&amp;amp;q=80"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt; &lt;span class="na"&gt;filter=&lt;/span&gt;&lt;span class="s"&gt;"url(#displace)"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Now that we understand &lt;code&gt;feDisplacementMap&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We can go creative to experiment with interesting graphics with &lt;code&gt;feDisplacementMap&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--awYtuLEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gtggj09legt80yo4logn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--awYtuLEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gtggj09legt80yo4logn.gif" alt="GIF of a Glitch Text effect using feDisplacementMap" width="754" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>svg</category>
    </item>
    <item>
      <title>Use Nginx to serve static React site with gzip and HTTP2</title>
      <dc:creator>Po-Hsiang (Matthew) Lu</dc:creator>
      <pubDate>Wed, 25 May 2022 13:38:19 +0000</pubDate>
      <link>https://forem.com/matteo1222/use-nginx-to-serve-static-react-site-with-gzip-and-http2-50lo</link>
      <guid>https://forem.com/matteo1222/use-nginx-to-serve-static-react-site-with-gzip-and-http2-50lo</guid>
      <description>&lt;p&gt;Let's start with pre-compressing our React app when we run the build process. To do this, install a npm package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install compress-create-react-app --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, change the build script in package.json to below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build": "react-scripts build &amp;amp;&amp;amp; compress-cra"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever we run npm run build, our project will be built and compressed files will be created automatically.&lt;/p&gt;

&lt;p&gt;Next, to serve our static files with gzip and HTTP2 using Nginx, we will need to check if we have the modules needed. The modules required are "ngx_http_gzip_static_module" and "ngx_http_v2_module". Run the following command and check if the output contains "--with-http_gzip_static_module" and "--with-http_v2_module".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nginx -V
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the server block of our Nginx configuration that enables gzip and HTTP2. Note that to use HTTP2, we will first need HTTPS. If HTTPS is not yet activated, follow the guide of &lt;a href="https://letsencrypt.org/"&gt;Let's Encrypt&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
  listen 443 ssl http2;
  ssl_certificate /PATH/TO/YOUR/CERTIFICATE;
  ssl_certificate_key /PATH/TO/YOUR/CERTIFICATE/KEY;
  location / {
    alias /PATH/TO/YOUR/BUILD/FOLDER;
    gzip_static on;
  }
  server_name YOURSERVERNAME;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The gzip_static directive allows Nginx to serve files with .gz extensions, while the http2 activates the support for HTTP2.&lt;/p&gt;

</description>
      <category>react</category>
      <category>nginx</category>
    </item>
  </channel>
</rss>
