<?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: Markus Tiefenbacher</title>
    <description>The latest articles on Forem by Markus Tiefenbacher (@tiefenb).</description>
    <link>https://forem.com/tiefenb</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%2F55742%2Fb7c697ca-67d5-44ad-a9fc-16332809316f.jpeg</url>
      <title>Forem: Markus Tiefenbacher</title>
      <link>https://forem.com/tiefenb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tiefenb"/>
    <language>en</language>
    <item>
      <title>For fun and learning: playing around with JavaScript face detection and html5 canvas</title>
      <dc:creator>Markus Tiefenbacher</dc:creator>
      <pubDate>Fri, 10 Apr 2020 11:36:52 +0000</pubDate>
      <link>https://forem.com/btdev/for-fun-and-learning-playing-around-with-javascript-face-detection-and-html5-canvas-3km4</link>
      <guid>https://forem.com/btdev/for-fun-and-learning-playing-around-with-javascript-face-detection-and-html5-canvas-3km4</guid>
      <description>&lt;p&gt;It’s easter and wanted to make some fun for my coworkers and what should be better than some Covid-19 fun in this surreal times.&lt;/p&gt;

&lt;p&gt;I had the idea to put every model in our webshop a surgical mask on their face.&lt;/p&gt;

&lt;p&gt;But how should I solve this?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Face Detection!&lt;/em&gt;&lt;br&gt;
This was a topic I ever wanted to discover and so it was a perfect match for this. I started reading the &lt;a href="https://github.com/justadudewhohacks/face-api.js" rel="noopener noreferrer"&gt;face-api.js&lt;/a&gt; documentation and after some hours of playing around with it I was ready to ship the easter egg on our testing server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flctgbucs7ik46v48bfrr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flctgbucs7ik46v48bfrr.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself:
&lt;/h2&gt;

&lt;p&gt;I made also a version where you can try it yourself: &lt;a href="https://tiefenb.github.io/use-a-mask/" rel="noopener noreferrer"&gt;https://tiefenb.github.io/use-a-mask/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;... and here are the source code: &lt;a href="https://github.com/tiefenb/use-a-mask" rel="noopener noreferrer"&gt;https://github.com/tiefenb/use-a-mask&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactions so far:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm07frd0hxpro04cock0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm07frd0hxpro04cock0g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Learnings:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image" rel="noopener noreferrer"&gt;Loading images for HTML5 canvas is only possible with images with crossorigin attribute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;crossorigin attribute has to be set on the image tag before the image is loaded - it’s not possible afterwards. That means also, if you create the image element with JavaScript you have to add the crossorigin-attribute before the src-attribute.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/16546061/1156058" rel="noopener noreferrer"&gt;Rotating an single image in html5 canvas is not possible in the way most of us think. you have to rotate the canvas-context, than you put on the canvas the image and you rotate the canvas-context back to your normal angle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/15504471/1156058" rel="noopener noreferrer"&gt;Putting an image on a canvas is only possible after the image is full loaded - so you have to listen in the image.onload event&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;face-api.js tensorflow.js-models are quite big - better to make detection it on the server not the client&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thank's for reading and happy easter!&lt;/p&gt;

</description>
      <category>facedetectionhtml5canvas</category>
    </item>
    <item>
      <title>Dear appear.js, I have met someone new. Her name is IntersectionObserver.</title>
      <dc:creator>Markus Tiefenbacher</dc:creator>
      <pubDate>Tue, 14 May 2019 13:19:10 +0000</pubDate>
      <link>https://forem.com/btdev/dear-appear-js-i-have-met-someone-new-her-name-is-intersectionobserver-5h01</link>
      <guid>https://forem.com/btdev/dear-appear-js-i-have-met-someone-new-her-name-is-intersectionobserver-5h01</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2lmg5c5gnm74vdbq332a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2lmg5c5gnm74vdbq332a.jpg" alt="appear.js IntersectionObserver Meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dear &lt;a href="https://creativelive.github.io/appear/" rel="noopener noreferrer"&gt;appear.js&lt;/a&gt;, I have met someone new. It was more or less a good time with you. But I want to break up and you have to leave your stack.&lt;/p&gt;

&lt;p&gt;The new one? Her name's IntersectionObserver. She is nice to me. She is smart, pretty syntax and very fast in doing things. I think I will have a good time with her.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enough with joking.&lt;/strong&gt;&lt;br&gt;
At blue-tomato.com, we used some &lt;a href="https://appelsiini.net/projects/lazyload/v1/" rel="noopener noreferrer"&gt;jQuery based image lazy loading library&lt;/a&gt; and &lt;a href="https://creativelive.github.io/appear/" rel="noopener noreferrer"&gt;appear.js&lt;/a&gt; for lazyloading things and doing effect based on elements in the viewpoint.&lt;/p&gt;

&lt;p&gt;Both libraries listen on the scroll event and looking if the actual scroll position is in the range of the given elements position.&lt;/p&gt;

&lt;p&gt;This technic was the default for long time, but since IntersectionObserver comes up, it was clear to switch sometimes to this. The main problem with the old method was the listing on the scroll-event was very expensive to browser performance.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Making a navigation bar sticky with appear.js
&lt;/h3&gt;

&lt;p&gt;In this example, after the &lt;code&gt;.main-content&lt;/code&gt; became visible, the &lt;code&gt;.navigation&lt;/code&gt; bar will get the CSS class &lt;code&gt;.navigation--sticky&lt;/code&gt; and will become sticky. When &lt;code&gt;.main-content&lt;/code&gt; disappers (e.g. by scrolling back to the top of the page) the &lt;code&gt;.navigation&lt;/code&gt; bar will become static by removing the &lt;code&gt;.navigation--sticky&lt;/code&gt; class.&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="nf"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&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;.main-content&lt;/span&gt;&lt;span class="dl"&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;appear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&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;disappear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;removeClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making a navigation bar sticky with InteractionObserver
&lt;/h3&gt;

&lt;p&gt;With InteractionObserver this would work in this way:&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;var&lt;/span&gt; &lt;span class="nx"&gt;element&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.main-content&lt;/span&gt;&lt;span class="dl"&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;element&lt;/span&gt;&lt;span class="p"&gt;)&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;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="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;element&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;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intersectionRatio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;removeClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;rootMargin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px 0px&lt;/span&gt;&lt;span class="dl"&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.00&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;element&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;
  
  
  Whats that rootMargin and thresold?
&lt;/h2&gt;

&lt;p&gt;Appear.js has only some "bounds" option to let it fire some pixels before the element is really in the viewport. IntersectionObserver has a really powerful and flexible method to control this via the root/rootMargin and thresold options. Have an eye on this article from Smashing Magazine where Denys Mishonnuc explains this very detailed: &lt;a href="https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/#intersectionobserver-initialization" rel="noopener noreferrer"&gt;https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/#intersectionobserver-initialization&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>webdev</category>
      <category>breakup</category>
    </item>
  </channel>
</rss>
