Ombromanie: Creating Hand Shadow stories with Azure Speech and TensorFlow.js Handposes

Published Feb 22 2021 09:00 AM 1,231 Views
Microsoft

 

Have you ever tried to cast hand shadows on a wall? It is the easiest thing in the world, and yet to do it well requires practice and just the right setup. To cultivate your #cottagecore aesthetic, try going into a completely dark room with just one lit candle, and casting hand shadows on a plain wall. The effect is startlingly dramatic. What fun!

 

jelooper_0-1613690550387.jpeg

 

Even a tea light suffices to create a great effect

In 2020, and now into 2021, many folks are reverting back to basics as they look around their houses, reopening dusty corners of attics and basements and remembering the simple crafts that they used to love. Papermaking, anyone? All you need is a few tools and torn up, recycled paper. Pressing flowers? All you need is newspaper, some heavy books, and patience. And hand shadows? Just a candle.

 

jelooper_1-1613690550389.jpeg

 

This TikTok creator has thousands of views for their handshadow tutorials

But what's a developer to do when trying to capture that #cottagecore vibe in a web app?

High Tech for the Cottage

While exploring the art of hand shadows, I wondered whether some of the recent work I had done for body poses might be applicable to hand poses. What if you could tell a story on the web using your hands, and somehow save a video of the show and the narrative behind it, and send it to someone special? In lockdown, what could be more amusing than sharing shadow stories between friends or relatives, all virtually?

 

 

Hand shadow casting is a folk art probably originating in China; if you go to tea houses with stage shows, you might be lucky enough to view one like this!

A Show Of Hands

When you start researching hand poses, it's striking how much content there is on the web on the topic. There has been work since at least 2014 on creating fully articulated hands within the research, simulation, and gaming sphere:

 

jelooper_2-1613690550390.png

 

MSR throwing hands

There are dozens of handpose libraries already on GitHub:

 

There are many applications where tracking hands is a useful activity:

 

• Gaming
• Simulations / Training
• "Hands free" uses for remote interactions with things by moving the body
• Assistive technologies
• TikTok effects :trophy:
• Useful things like Accordion Hands apps

 

One of the more interesting new libraries, handsfree.js, offers an excellent array of demos in its effort to move to a hands free web experience:

 

jelooper_3-1613690550409.gif

 

Handsfree.js, a very promising project

As it turns out, hands are pretty complicated things. They each include 21 keypoints (vs PoseNet's 17 keypoints for an entire body). Building a model to support inference for such a complicated grouping of keypoints has provenn challenging.

 

jelooper_4-1613690550394.png

 

There are two main libraries available to the web developer when incorporating hand poses into an app: TensorFlow.js's handposes, and MediaPipe's. HandsFree.js uses both, to the extent that they expose APIs. As it turns out, neither TensorFlow.js nor MediaPipe's handposes are perfect for our project. We will have to compromise.

 

  • TensorFlow.js's handposes allow access to each hand keypoint and the ability to draw the hand to canvas as desired. HOWEVER, it only currently supports single hand poses, which is not optimal for good hand shadow shows.

  • MediaPipe's handpose models (which are used by TensorFlow.js) do allow for dual hands BUT its API does not allow for much styling of the keypoints so that drawing shadows using it is not obvious.

One other library, fingerposes, is optimized for finger spelling in a sign language context and is worth a look.

Since it's more important to use the Canvas API to draw custom shadows, we are obliged to use TensorFlow.js, hoping that either it will soon support multiple hands OR handsfree.js helps push the envelope to expose a more styleable hand.

 

Let's get to work to build this app.

Scaffold a Static Web App

As a Vue.js developer, I always use the Vue CLI to scaffold an app using vue create my-app and creating a standard app. I set up a basic app with two routes: Home and Show. Since this is going to be deployed as an Azure Static Web App, I follow my standard practice of including my app files in a folder named app and creating an api folder to include an Azure function to store a key (more on this in a minute).

 

In my package.json file, I import the important packages for using TensorFlow.js and the Cognitive Services Speech SDK in this app. Note that TensorFlow.js has divided its imports into individual packages:

 

"@tensorflow-models/handpose": "^0.0.6",
"@tensorflow/tfjs": "^2.7.0",
"@tensorflow/tfjs-backend-cpu": "^2.7.0",
"@tensorflow/tfjs-backend-webgl": "^2.7.0",
"@tensorflow/tfjs-converter": "^2.7.0",
"@tensorflow/tfjs-core": "^2.7.0",
...
"microsoft-cognitiveservices-speech-sdk": "^1.15.0",
 

Set up the View

We will draw an image of a hand, as detected by TensorFlow.js, onto a canvas, superimposed onto a video suppled by a webcam. In addition, we will redraw the hand to a second canvas (shadowCanvas), styled like shadows:

 

<div id="canvas-wrapper column is-half">
<canvas id="output" ref="output"></canvas>
    <video
        id="video"
        ref="video"
        playsinline
        style="
          -webkit-transform: scaleX(-1);
           transform: scaleX(-1);
           visibility: hidden;
           width: auto;
           height: auto;
           position: absolute;
         "
    ></video>
 </div>
 <div class="column is-half">
    <canvas
       class="has-background-black-bis"
       id="shadowCanvas"
       ref="shadowCanvas"
     >
    </canvas>
</div>
 

Load the Model, Start Keyframe Input

Working asynchronously, load the Handpose model. Once the backend is setup and the model is loaded, load the video via the webcam, and start watching the video's keyframes for hand poses. It's important at these steps to ensure error handling in case the model fails to load or there's no webcam available.

 

async mounted() {
    await tf.setBackend(this.backend);
    //async load model, then load video, then pass it to start landmarking
    this.model = await handpose.load();
    this.message = "Model is loaded! Now loading video";
    let webcam;
    try {
      webcam = await this.loadVideo();
    } catch (e) {
      this.message = e.message;
      throw e;
    }

    this.landmarksRealTime(webcam);
  },
 

Setup the Webcam

Still working asynchronously, set up the camera to provide a stream of images

 

async setupCamera() {
      if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
        throw new Error(
          "Browser API navigator.mediaDevices.getUserMedia not available"
        );
      }
      this.video = this.$refs.video;
      const stream = await navigator.mediaDevices.getUserMedia({
        video: {
          facingMode: "user",
          width: VIDEO_WIDTH,
          height: VIDEO_HEIGHT,
        },
      });

      return new Promise((resolve) => {
        this.video.srcObject = stream;
        this.video.onloadedmetadata = () => {
          resolve(this.video);
        };
      });
    },
 

Design a Hand to Mirror the Webcam's

Now the fun begins, as you can get creative in drawing the hand on top of the video. This landmarking function runs on every keyframe, watching for a hand to be detected and drawing lines onto the canvas - red on top of the video, and black on top of the shadowCanvas. Since the shadowCanvas background is white, the hand is drawn as white as well and the viewer only sees the offset shadow, in fuzzy black with rounded corners. The effect is rather spooky!

 

async landmarksRealTime(video) {
      //start showing landmarks
      this.videoWidth = video.videoWidth;
      this.videoHeight = video.videoHeight;

      //set up skeleton canvas
      this.canvas = this.$refs.output;
      ...

      //set up shadowCanvas
      this.shadowCanvas = this.$refs.shadowCanvas;
      ...

      this.ctx = this.canvas.getContext("2d");
      this.sctx = this.shadowCanvas.getContext("2d");

      ...

      //paint to main

      this.ctx.clearRect(0, 0, this.videoWidth, 
  this.videoHeight);
      this.ctx.strokeStyle = "red";
      this.ctx.fillStyle = "red";
      this.ctx.translate(this.shadowCanvas.width, 0);
      this.ctx.scale(-1, 1);

      //paint to shadow box

      this.sctx.clearRect(0, 0, this.videoWidth, this.videoHeight);
      this.sctx.shadowColor = "black";
      this.sctx.shadowBlur = 20;
      this.sctx.shadowOffsetX = 150;
      this.sctx.shadowOffsetY = 150;
      this.sctx.lineWidth = 20;
      this.sctx.lineCap = "round";
      this.sctx.fillStyle = "white";
      this.sctx.strokeStyle = "white";

      this.sctx.translate(this.shadowCanvas.width, 0);
      this.sctx.scale(-1, 1);

      //now you've set up the canvases, now you can frame its landmarks
      this.frameLandmarks();
    },
 

For Each Frame, Draw Keypoints

 

As the keyframes progress, the model predict new keypoints for each of the hand's elements, and both canvases are cleared and redrawn.

 

      const predictions = await this.model.estimateHands(this.video);

      if (predictions.length > 0) {
        const result = predictions[0].landmarks;
        this.drawKeypoints(
          this.ctx,
          this.sctx,
          result,
          predictions[0].annotations
        );
      }
      requestAnimationFrame(this.frameLandmarks);

 

Draw a Lifelike Hand

Since TensorFlow.js allows you direct access to the keypoints of the hand and the hand's coordinates, you can manipulate them to draw a more lifelike hand. Thus we can redraw the palm to be a polygon, rather than resembling a garden rake with points culminating in the wrist.

 

Re-identify the fingers and palm:

 

     fingerLookupIndices: {
        thumb: [0, 1, 2, 3, 4],
        indexFinger: [0, 5, 6, 7, 8],
        middleFinger: [0, 9, 10, 11, 12],
        ringFinger: [0, 13, 14, 15, 16],
        pinky: [0, 17, 18, 19, 20],
      },
      palmLookupIndices: {
        palm: [0, 1, 5, 9, 13, 17, 0, 1],
      },
 

...and draw them to screen:

 

    const fingers = Object.keys(this.fingerLookupIndices);
      for (let i = 0; i < fingers.length; i++) {
        const finger = fingers[i];
        const points = this.fingerLookupIndices[finger].map(
          (idx) => keypoints[idx]
        );
        this.drawPath(ctx, sctx, points, false);
      }
      const palmArea = Object.keys(this.palmLookupIndices);
      for (let i = 0; i < palmArea.length; i++) {
        const palm = palmArea[i];
        const points = this.palmLookupIndices[palm].map(
          (idx) => keypoints[idx]
        );
        this.drawPath(ctx, sctx, points, true);
      }
 

With the models and video loaded, keyframes tracked, and hands and shadows drawn to canvas, we can implement a speech-to-text SDK so that you can narrate and save your shadow story.

To do this, get a key from the Azure portal for Speech Services by creating a Service:

 

jelooper_5-1613690550393.png

 

You can connect to this service by importing the sdk:

 

import * as sdk from "microsoft-cognitiveservices-speech-sdk";

 

...and start audio transcription after obtaining an API key which is stored in an Azure function in the /api folder. This function gets the key stored in the Azure portal in the Azure Static Web App where the app is hosted.

 

async startAudioTranscription() {
      try {
        //get the key
        const response = await axios.get("/api/getKey");
        this.subKey = response.data;
        //sdk

        let speechConfig = sdk.SpeechConfig.fromSubscription(
          this.subKey,
          "eastus"
        );
        let audioConfig = sdk.AudioConfig.fromDefaultMicrophoneInput();
        this.recognizer = new sdk.SpeechRecognizer(speechConfig, audioConfig);

        this.recognizer.recognized = (s, e) => {
          this.text = e.result.text;
          this.story.push(this.text);
        };

        this.recognizer.startContinuousRecognitionAsync();
      } catch (error) {
        this.message = error;
      }
    },
 

In this function, the SpeechRecognizer gathers text in chunks that it recognizes and organizes into sentences. That text is printed into a message string and displayed on the front end.

Display the Story

In this last part, the output cast onto the shadowCanvas is saved as a stream and recorded using the MediaRecorder API:

 

const stream = this.shadowCanvas.captureStream(60); // 60 FPS recording
      this.recorder = new MediaRecorder(stream, {
        mimeType: "video/webm;codecs=vp9",
      });
      (this.recorder.ondataavailable = (e) => {
        this.chunks.push(e.data);
      }),
        this.recorder.start(500);
 

...and displayed below as a video with the storyline in a new div:

 

      const video = document.createElement("video");
      const fullBlob = new Blob(this.chunks);
      const downloadUrl = window.URL.createObjectURL(fullBlob);
      video.src = downloadUrl;
      document.getElementById("story").appendChild(video);
      video.autoplay = true;
      video.controls = true;
 

This app can be deployed as an Azure Static Web App using the excellent Azure plugin for Visual Studio Code. And once it's live, you can tell durable shadow stories!

 

jelooper_6-1613690550392.png

 

Try Ombromanie here. The codebase is available here

Take a look at Ombromanie in action:

 

 

Learn more about AI on Azure
Azure AI Essentials Video covering speech and language
Azure free account sign-up

 

%3CLINGO-SUB%20id%3D%22lingo-sub-1822815%22%20slang%3D%22en-US%22%3EOmbromanie%3A%20Creating%20Hand%20Shadow%20stories%20with%20Azure%20Speech%20and%20TensorFlow.js%20Handposes%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1822815%22%20slang%3D%22en-US%22%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EHave%20you%20ever%20tried%20to%20cast%20hand%20shadows%20on%20a%20wall%3F%20It%20is%20the%20easiest%20thing%20in%20the%20world%2C%20and%20yet%20to%20do%20it%20well%20requires%20practice%20and%20just%20the%20right%20setup.%20To%20cultivate%20your%20%23cottagecore%20aesthetic%2C%20try%20going%20into%20a%20completely%20dark%20room%20with%20just%20one%20lit%20candle%2C%20and%20casting%20hand%20shadows%20on%20a%20plain%20wall.%20The%20effect%20is%20startlingly%20dramatic.%20What%20fun!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jelooper_0-1613690550387.jpeg%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F255920iBE801D0624C8D1B8%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22jelooper_0-1613690550387.jpeg%22%20alt%3D%22jelooper_0-1613690550387.jpeg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3EEven%20a%20tea%20light%20suffices%20to%20create%20a%20great%20effect%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3EIn%202020%2C%20and%20now%20into%202021%2C%20many%20folks%20are%20reverting%20back%20to%20basics%20as%20they%20look%20around%20their%20houses%2C%20reopening%20dusty%20corners%20of%20attics%20and%20basements%20and%20remembering%20the%20simple%20crafts%20that%20they%20used%20to%20love.%20Papermaking%2C%20anyone%3F%20All%20you%20need%20is%20a%20few%20tools%20and%20torn%20up%2C%20recycled%20paper.%20Pressing%20flowers%3F%20All%20you%20need%20is%20newspaper%2C%20some%20heavy%20books%2C%20and%20patience.%20And%20hand%20shadows%3F%20Just%20a%20candle.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jelooper_1-1613690550389.jpeg%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F255921i2CEDDF41FB98B141%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22jelooper_1-1613690550389.jpeg%22%20alt%3D%22jelooper_1-1613690550389.jpeg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3EThis%20TikTok%20creator%20has%20thousands%20of%20views%20for%20their%20handshadow%20tutorials%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3EBut%20what's%20a%20developer%20to%20do%20when%20trying%20to%20capture%20that%20%23cottagecore%20vibe%20in%20a%20web%20app%3F%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--1214147920%22%20id%3D%22toc-hId--1214147952%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23high-tech-for-the-cottage%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22high-tech-for-the-cottage%22%3E%3C%2FA%3EHigh%20Tech%20for%20the%20Cottage%3C%2FH2%3E%0A%3CP%3EWhile%20exploring%20the%20art%20of%20hand%20shadows%2C%20I%20wondered%20whether%20some%20of%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjlooper%2Fposedance%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Erecent%20work%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3EI%20had%20done%20for%20body%20poses%20might%20be%20applicable%20to%20hand%20poses.%20What%20if%20you%20could%20tell%20a%20story%20on%20the%20web%20using%20your%20hands%2C%20and%20somehow%20save%20a%20video%20of%20the%20show%20and%20the%20narrative%20behind%20it%2C%20and%20send%20it%20to%20someone%20special%3F%20In%20lockdown%2C%20what%20could%20be%20more%20amusing%20than%20sharing%20shadow%20stories%20between%20friends%20or%20relatives%2C%20all%20virtually%3F%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22%20fluidvids%22%3E%3CIFRAME%20src%3D%22https%3A%2F%2Fwww.youtube.com%2Fembed%2FZWvZBEeS4qQ%22%20width%3D%22710%22%20height%3D%22399%22%20allowfullscreen%3D%22allowfullscreen%22%20class%3D%22%20fluidvids-elem%22%20loading%3D%22lazy%22%20data-mce-fragment%3D%221%22%3E%3C%2FIFRAME%3E%3C%2FDIV%3E%0A%3CP%3E%3CLI-WRAPPER%3E%3C%2FLI-WRAPPER%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3EHand%20shadow%20casting%20is%20a%20folk%20art%20probably%20originating%20in%20China%3B%20if%20you%20go%20to%20tea%20houses%20with%20stage%20shows%2C%20you%20might%20be%20lucky%20enough%20to%20view%20one%20like%20this!%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CH2%20id%3D%22toc-hId-1273364913%22%20id%3D%22toc-hId-1273364881%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23a-show-of-hands%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22a-show-of-hands%22%3E%3C%2FA%3EA%20Show%20Of%20Hands%3C%2FH2%3E%0A%3CP%3EWhen%20you%20start%20researching%20hand%20poses%2C%20it's%20striking%20how%20much%20content%20there%20is%20on%20the%20web%20on%20the%20topic.%20There%20has%20been%20work%20since%20at%20least%202014%20on%20creating%20fully%20articulated%20hands%20within%20the%20research%2C%20simulation%2C%20and%20gaming%20sphere%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jelooper_2-1613690550390.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F255922iC341945EDADA45EE%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22jelooper_2-1613690550390.png%22%20alt%3D%22jelooper_2-1613690550390.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3EMSR%20throwing%20hands%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3EThere%20are%20dozens%20of%20handpose%20libraries%20already%20on%20GitHub%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Ftopics%2Fhand-tracking%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EAn%20entire%20GitHub%20topic%20on%20hand%20tracking%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fxinghaochen%2Fawesome-hand-pose-estimation%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E'Awesome'%20list%20for%20hand%20tracking%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Fsites.google.com%2Fview%2Fhands2019%2Fchallenge%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3EChallenges%20and%20hackathons%3C%2FA%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3EThere%20are%20many%20applications%20where%20tracking%20hands%20is%20a%20useful%20activity%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%E2%80%A2%20Gaming%3CBR%20%2F%3E%E2%80%A2%20Simulations%20%2F%20Training%3CBR%20%2F%3E%E2%80%A2%20%22Hands%20free%22%20uses%20for%20remote%20interactions%20with%20things%20by%20moving%20the%20body%3CBR%20%2F%3E%E2%80%A2%20Assistive%20technologies%3CBR%20%2F%3E%E2%80%A2%20TikTok%20effects%20%3Atrophy%3A%3CBR%20%2F%3E%E2%80%A2%20Useful%20things%20like%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fmcclanahoochie.com%2Faccordionhands%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3EAccordion%20Hands%20apps%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOne%20of%20the%20more%20interesting%20new%20libraries%2C%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fdev.to%2Fmidiblocks%2Fintroducing-handsfree-js-integrate-hand-face-and-pose-gestures-to-your-frontend-4g3p%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3Ehandsfree.js%3C%2FA%3E%2C%20offers%20an%20excellent%20array%20of%20demos%20in%20its%20effort%20to%20move%20to%20a%20hands%20free%20web%20experience%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jelooper_3-1613690550409.gif%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F255925i68693FBE43C49072%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22jelooper_3-1613690550409.gif%22%20alt%3D%22jelooper_3-1613690550409.gif%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3EHandsfree.js%2C%20a%20very%20promising%20project%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3EAs%20it%20turns%20out%2C%20hands%20are%20pretty%20complicated%20things.%20They%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3Eeach%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Einclude%2021%20keypoints%20(vs%20PoseNet's%2017%20keypoints%20for%20an%20entire%20body).%20Building%20a%20model%20to%20support%20inference%20for%20such%20a%20complicated%20grouping%20of%20keypoints%20has%20provenn%20challenging.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jelooper_4-1613690550394.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F255924i16174859EC1DA772%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22jelooper_4-1613690550394.png%22%20alt%3D%22jelooper_4-1613690550394.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThere%20are%20two%20main%20libraries%20available%20to%20the%20web%20developer%20when%20incorporating%20hand%20poses%20into%20an%20app%3A%20TensorFlow.js's%20handposes%2C%20and%20MediaPipe's.%20HandsFree.js%20uses%20both%2C%20to%20the%20extent%20that%20they%20expose%20APIs.%20As%20it%20turns%20out%2C%20neither%20TensorFlow.js%20nor%20MediaPipe's%20handposes%20are%20perfect%20for%20our%20project.%20We%20will%20have%20to%20compromise.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Ftensorflow%2Ftfjs-models%2Ftree%2Fmaster%2Fhandpose%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3ETensorFlow.js's%20handposes%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eallow%20access%20to%20each%20hand%20keypoint%20and%20the%20ability%20to%20draw%20the%20hand%20to%20canvas%20as%20desired.%20HOWEVER%2C%20it%20only%20currently%20supports%20single%20hand%20poses%2C%20which%20is%20not%20optimal%20for%20good%20hand%20shadow%20shows.%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fgoogle.github.io%2Fmediapipe%2Fsolutions%2Fhands%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3EMediaPipe's%20handpose%20models%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E(which%20are%20used%20by%20TensorFlow.js)%20do%20allow%20for%20dual%20hands%20BUT%20its%20API%20does%20not%20allow%20for%20much%20styling%20of%20the%20keypoints%20so%20that%20drawing%20shadows%20using%20it%20is%20not%20obvious.%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3EOne%20other%20library%2C%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fandypotato%2Ffingerpose%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Efingerposes%3C%2FA%3E%2C%20is%20optimized%20for%20finger%20spelling%20in%20a%20sign%20language%20context%20and%20is%20worth%20a%20look.%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3ESince%20it's%20more%20important%20to%20use%20the%20Canvas%20API%20to%20draw%20custom%20shadows%2C%20we%20are%20obliged%20to%20use%20TensorFlow.js%2C%20hoping%20that%20either%20it%20will%20soon%20support%20multiple%20hands%20OR%20handsfree.js%20helps%20push%20the%20envelope%20to%20expose%20a%20more%20styleable%20hand.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ELet's%20get%20to%20work%20to%20build%20this%20app.%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--534089550%22%20id%3D%22toc-hId--534089582%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23scaffold-a-static-web-app%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22scaffold-a-static-web-app%22%3E%3C%2FA%3EScaffold%20a%20Static%20Web%20App%3C%2FH2%3E%0A%3CP%3EAs%20a%20Vue.js%20developer%2C%20I%20always%20use%20the%20Vue%20CLI%20to%20scaffold%20an%20app%20using%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%3Evue%20create%20my-app%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eand%20creating%20a%20standard%20app.%20I%20set%20up%20a%20basic%20app%20with%20two%20routes%3A%20Home%20and%20Show.%20Since%20this%20is%20going%20to%20be%20deployed%20as%20an%20Azure%20Static%20Web%20App%2C%20I%20follow%20my%20standard%20practice%20of%20including%20my%20app%20files%20in%20a%20folder%20named%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%3Eapp%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eand%20creating%20an%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%3Eapi%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Efolder%20to%20include%20an%20Azure%20function%20to%20store%20a%20key%20(more%20on%20this%20in%20a%20minute).%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20my%20package.json%20file%2C%20I%20import%20the%20important%20packages%20for%20using%20TensorFlow.js%20and%20the%20Cognitive%20Services%20Speech%20SDK%20in%20this%20app.%20Note%20that%20TensorFlow.js%20has%20divided%20its%20imports%20into%20individual%20packages%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%40tensorflow-models%2Fhandpose%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%5E0.0.6%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%40tensorflow%2Ftfjs%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%5E2.7.0%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%40tensorflow%2Ftfjs-backend-cpu%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%5E2.7.0%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%40tensorflow%2Ftfjs-backend-webgl%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%5E2.7.0%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%40tensorflow%2Ftfjs-converter%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%5E2.7.0%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%40tensorflow%2Ftfjs-core%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%5E2.7.0%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22p%22%3E...%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Emicrosoft-cognitiveservices-speech-sdk%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%5E1.15.0%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CH2%20id%3D%22toc-hId-1953423283%22%20id%3D%22toc-hId-1953423251%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23set-up-the-view%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22set-up-the-view%22%3E%3C%2FA%3ESet%20up%20the%20View%3C%2FH2%3E%0A%3CP%3EWe%20will%20draw%20an%20image%20of%20a%20hand%2C%20as%20detected%20by%20TensorFlow.js%2C%20onto%20a%20canvas%2C%20superimposed%20onto%20a%20video%20suppled%20by%20a%20webcam.%20In%20addition%2C%20we%20will%20redraw%20the%20hand%20to%20a%20second%20canvas%20(shadowCanvas)%2C%20styled%20like%20shadows%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20html%22%3E%3CCODE%3E%3CSPAN%20class%3D%22nt%22%3E%3CDIV%3E%3C%2FDIV%3E%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22na%22%3Eid%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22canvas-wrapper%20column%20is-half%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22nt%22%3E%26gt%3B%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22nt%22%3E%3CCANVAS%3E%3C%2FCANVAS%3E%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22na%22%3Eid%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22output%22%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22na%22%3Eref%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22output%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22nt%22%3E%26gt%3B%3C%2FSPAN%3E%3C%2FCODE%3E%3C%2FPRE%3E%3C%2FDIV%3E%3C%2FLINGO-BODY%3E%0A%20%20%20%20%3CSPAN%20class%3D%22nt%22%3E%3CVIDEO%3E%3C%2FVIDEO%3E%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eid%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22video%22%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eref%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22video%22%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eplaysinline%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Estyle%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22%0A%20%20%20%20%20%20%20%20%20%20-webkit-transform%3A%20scaleX(-1)%3B%0A%20%20%20%20%20%20%20%20%20%20%20transform%3A%20scaleX(-1)%3B%0A%20%20%20%20%20%20%20%20%20%20%20visibility%3A%20hidden%3B%0A%20%20%20%20%20%20%20%20%20%20%20width%3A%20auto%3B%0A%20%20%20%20%20%20%20%20%20%20%20height%3A%20auto%3B%0A%20%20%20%20%20%20%20%20%20%20%20position%3A%20absolute%3B%0A%20%20%20%20%20%20%20%20%20%22%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22nt%22%3E%26gt%3B%3C%2FSPAN%3E%0A%20%3CSPAN%20class%3D%22nt%22%3E%3C%2FSPAN%3E%0A%20%3CSPAN%20class%3D%22nt%22%3E%3CDIV%3E%3C%2FDIV%3E%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22na%22%3Eclass%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22column%20is-half%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22nt%22%3E%26gt%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22nt%22%3E%3CCANVAS%3E%3C%2FCANVAS%3E%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eclass%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22has-background-black-bis%22%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eid%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22shadowCanvas%22%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eref%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3E%22shadowCanvas%22%3C%2FSPAN%3E%0A%20%20%20%20%20%3CSPAN%20class%3D%22nt%22%3E%26gt%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22nt%22%3E%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22nt%22%3E%3C%2FSPAN%3E%0A%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%0A%3CH2%20id%3D%22toc-hId-145968820%22%20id%3D%22toc-hId-145968788%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23load-the-model-start-keyframe-input%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22load-the-model-start-keyframe-input%22%3E%3C%2FA%3ELoad%20the%20Model%2C%20Start%20Keyframe%20Input%3C%2FH2%3E%0A%3CP%3EWorking%20asynchronously%2C%20load%20the%20Handpose%20model.%20Once%20the%20backend%20is%20setup%20and%20the%20model%20is%20loaded%2C%20load%20the%20video%20via%20the%20webcam%2C%20and%20start%20watching%20the%20video's%20keyframes%20for%20hand%20poses.%20It's%20important%20at%20these%20steps%20to%20ensure%20error%20handling%20in%20case%20the%20model%20fails%20to%20load%20or%20there's%20no%20webcam%20available.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%3CSPAN%20class%3D%22k%22%3Easync%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Emounted%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22k%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Etf%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EsetBackend%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ebackend%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fasync%20load%20model%2C%20then%20load%20video%2C%20then%20pass%20it%20to%20start%20landmarking%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emodel%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ehandpose%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eload%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3EModel%20is%20loaded!%20Now%20loading%20video%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Elet%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ewebcam%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22k%22%3Etry%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Ewebcam%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EloadVideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ecatch%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ee%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ee%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emessage%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethrow%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ee%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%0A%0A%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3ElandmarksRealTime%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ewebcam%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%3CSPAN%20class%3D%22p%22%3E%7D%2C%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CH2%20id%3D%22toc-hId--1661485643%22%20id%3D%22toc-hId--1661485675%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23setup-the-webcam%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22setup-the-webcam%22%3E%3C%2FA%3ESetup%20the%20Webcam%3C%2FH2%3E%0A%3CP%3EStill%20working%20asynchronously%2C%20set%20up%20the%20camera%20to%20provide%20a%20stream%20of%20images%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%3CSPAN%20class%3D%22k%22%3Easync%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EsetupCamera%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Eif%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22o%22%3E!%3C%2FSPAN%3E%3CSPAN%20class%3D%22nb%22%3Enavigator%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EmediaDevices%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%7C%7C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E!%3C%2FSPAN%3E%3CSPAN%20class%3D%22nb%22%3Enavigator%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EmediaDevices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EgetUserMedia%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethrow%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nb%22%3EError%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3EBrowser%20API%20navigator.mediaDevices.getUserMedia%20not%20available%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3E%24refs%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Estream%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nb%22%3Enavigator%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EmediaDevices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EgetUserMedia%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3EfacingMode%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Euser%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Ewidth%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EVIDEO_WIDTH%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eheight%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EVIDEO_HEIGHT%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D)%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ereturn%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nb%22%3EPromise%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E((%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eresolve%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EsrcObject%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Estream%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eonloadedmetadata%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E()%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Eresolve%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D)%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%2C%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CH2%20id%3D%22toc-hId-826027190%22%20id%3D%22toc-hId-826027158%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23design-a-hand-to-mirror-the-webcams%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22design-a-hand-to-mirror-the-webcams%22%3E%3C%2FA%3EDesign%20a%20Hand%20to%20Mirror%20the%20Webcam's%3C%2FH2%3E%0A%3CP%3ENow%20the%20fun%20begins%2C%20as%20you%20can%20get%20creative%20in%20drawing%20the%20hand%20on%20top%20of%20the%20video.%20This%20landmarking%20function%20runs%20on%20every%20keyframe%2C%20watching%20for%20a%20hand%20to%20be%20detected%20and%20drawing%20lines%20onto%20the%20canvas%20-%20red%20on%20top%20of%20the%20video%2C%20and%20black%20on%20top%20of%20the%20shadowCanvas.%20Since%20the%20shadowCanvas%20background%20is%20white%2C%20the%20hand%20is%20drawn%20as%20white%20as%20well%20and%20the%20viewer%20only%20sees%20the%20offset%20shadow%2C%20in%20fuzzy%20black%20with%20rounded%20corners.%20The%20effect%20is%20rather%20spooky!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%3CSPAN%20class%3D%22k%22%3Easync%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3ElandmarksRealTime%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fstart%20showing%20landmarks%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoWidth%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoWidth%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoHeight%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoHeight%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fset%20up%20skeleton%20canvas%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ecanvas%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3E%24refs%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eoutput%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E...%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fset%20up%20shadowCanvas%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowCanvas%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3E%24refs%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowCanvas%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E...%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ecanvas%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EgetContext%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E2d%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowCanvas%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EgetContext%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E2d%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E...%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fpaint%20to%20main%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EclearRect%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoWidth%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%0A%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoHeight%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EstrokeStyle%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Ered%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EfillStyle%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Ered%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Etranslate%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowCanvas%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ewidth%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Escale%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22o%22%3E-%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E1%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E1%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fpaint%20to%20shadow%20box%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EclearRect%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoWidth%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EvideoHeight%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowColor%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Eblack%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowBlur%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E20%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowOffsetX%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E150%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowOffsetY%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E150%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3ElineWidth%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E20%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3ElineCap%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Eround%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EfillStyle%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Ewhite%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EstrokeStyle%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Ewhite%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Etranslate%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowCanvas%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ewidth%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Escale%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22o%22%3E-%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E1%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E1%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fnow%20you've%20set%20up%20the%20canvases%2C%20now%20you%20can%20frame%20its%20landmarks%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EframeLandmarks%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3B%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%2C%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CH2%20id%3D%22toc-hId--981427273%22%20id%3D%22toc-hId--981427305%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23for-each-frame-draw-keypoints%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22for-each-frame-draw-keypoints%22%3E%3C%2FA%3EFor%20Each%20Frame%2C%20Draw%20Keypoints%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAs%20the%20keyframes%20progress%2C%20the%20model%20predict%20new%20keypoints%20for%20each%20of%20the%20hand's%20elements%2C%20and%20both%20canvases%20are%20cleared%20and%20redrawn.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Epredictions%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emodel%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EestimateHands%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Eif%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Epredictions%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Elength%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Eresult%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Epredictions%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Elandmarks%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EdrawKeypoints%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Eresult%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Epredictions%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eannotations%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3ErequestAnimationFrame%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EframeLandmarks%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CH2%20id%3D%22toc-hId-1506085560%22%20id%3D%22toc-hId-1506085528%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23draw-a-lifelike-hand%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22draw-a-lifelike-hand%22%3E%3C%2FA%3EDraw%20a%20Lifelike%20Hand%3C%2FH2%3E%0A%3CP%3ESince%20TensorFlow.js%20allows%20you%20direct%20access%20to%20the%20keypoints%20of%20the%20hand%20and%20the%20hand's%20coordinates%2C%20you%20can%20manipulate%20them%20to%20draw%20a%20more%20lifelike%20hand.%20Thus%20we%20can%20redraw%20the%20palm%20to%20be%20a%20polygon%2C%20rather%20than%20resembling%20a%20garden%20rake%20with%20points%20culminating%20in%20the%20wrist.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ERe-identify%20the%20fingers%20and%20palm%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3EfingerLookupIndices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nl%22%3Ethumb%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E1%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E2%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E3%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E4%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3EindexFinger%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E5%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E6%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E7%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E8%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3EmiddleFinger%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E9%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E10%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E11%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E12%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3EringFinger%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E13%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E14%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E15%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E16%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Epinky%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E17%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E18%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E19%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E20%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3EpalmLookupIndices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22nl%22%3Epalm%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E1%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E5%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E9%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E13%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E17%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E1%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%2C%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CP%3E...and%20draw%20them%20to%20screen%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Efingers%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nb%22%3EObject%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ekeys%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EfingerLookupIndices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Efor%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22kd%22%3Elet%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%26lt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Efingers%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Elength%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%3CSPAN%20class%3D%22o%22%3E%2B%2B%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Efinger%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Efingers%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Epoints%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EfingerLookupIndices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Efinger%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emap%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eidx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ekeypoints%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eidx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EdrawPath%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Epoints%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22kc%22%3Efalse%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EpalmArea%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nb%22%3EObject%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ekeys%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EpalmLookupIndices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Efor%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22kd%22%3Elet%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22mi%22%3E0%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%26lt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EpalmArea%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Elength%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%3CSPAN%20class%3D%22o%22%3E%2B%2B%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Epalm%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EpalmArea%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ei%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Epoints%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EpalmLookupIndices%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Epalm%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emap%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eidx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ekeypoints%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eidx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%5D%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EdrawPath%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ectx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Esctx%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Epoints%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22kc%22%3Etrue%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CP%3EWith%20the%20models%20and%20video%20loaded%2C%20keyframes%20tracked%2C%20and%20hands%20and%20shadows%20drawn%20to%20canvas%2C%20we%20can%20implement%20a%20speech-to-text%20SDK%20so%20that%20you%20can%20narrate%20and%20save%20your%20shadow%20story.%3C%2FP%3E%0A%3CP%3ETo%20do%20this%2C%20get%20a%20key%20from%20the%20Azure%20portal%20for%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fcognitive-services%2Fspeech-service%2F%3FWT.mc_id%3Dacademic-14261-cxa%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3ESpeech%20Services%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eby%20creating%20a%20Service%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jelooper_5-1613690550393.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F255923iE817738507CDC464%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22jelooper_5-1613690550393.png%22%20alt%3D%22jelooper_5-1613690550393.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYou%20can%20connect%20to%20this%20service%20by%20importing%20the%20sdk%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CCODE%3Eimport%20*%20as%20sdk%20from%20%22microsoft-cognitiveservices-speech-sdk%22%3B%3C%2FCODE%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E...and%20start%20audio%20transcription%20after%20obtaining%20an%20API%20key%20which%20is%20stored%20in%20an%20Azure%20function%20in%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%3E%2Fapi%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Efolder.%20This%20function%20gets%20the%20key%20stored%20in%20the%20Azure%20portal%20in%20the%20Azure%20Static%20Web%20App%20where%20the%20app%20is%20hosted.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%3CSPAN%20class%3D%22k%22%3Easync%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EstartAudioTranscription%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Etry%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fget%20the%20key%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Eresponse%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Eaxios%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22kd%22%3Eget%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3E%2Fapi%2FgetKey%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EsubKey%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Eresponse%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Edata%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%2F%2Fsdk%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Elet%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EspeechConfig%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Esdk%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3ESpeechConfig%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EfromSubscription%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EsubKey%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Eeastus%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Elet%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EaudioConfig%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Esdk%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EAudioConfig%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EfromDefaultMicrophoneInput%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Erecognizer%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Esdk%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3ESpeechRecognizer%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EspeechConfig%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EaudioConfig%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Erecognizer%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Erecognized%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Es%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ee%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Etext%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Ee%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eresult%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Etext%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Estory%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Epush%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Etext%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3B%3C%2FSPAN%3E%0A%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Erecognizer%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EstartContinuousRecognitionAsync%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E()%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ecatch%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eerror%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Emessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Eerror%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D%2C%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CP%3EIn%20this%20function%2C%20the%20SpeechRecognizer%20gathers%20text%20in%20chunks%20that%20it%20recognizes%20and%20organizes%20into%20sentences.%20That%20text%20is%20printed%20into%20a%20message%20string%20and%20displayed%20on%20the%20front%20end.%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--301368903%22%20id%3D%22toc-hId--301368935%22%3E%3CA%20class%3D%22anchor%22%20href%3D%22https%3A%2F%2Fdev.to%2Fazure%2Fombromanie-playing-with-hand-shadows-with-tensorflow-js-199l-temp-slug-5854224%3Fpreview%3D4c3c69d5e60a2b25962c039bfb5da752d120c002d803cc8cba48b58139acf0beee9cfd5681297a3b3f4f605576b6756b270fd168e6d69a47dddc4936%23display-the-story%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20name%3D%22display-the-story%22%3E%3C%2FA%3EDisplay%20the%20Story%3C%2FH2%3E%0A%3CP%3EIn%20this%20last%20part%2C%20the%20output%20cast%20onto%20the%20shadowCanvas%20is%20saved%20as%20a%20stream%20and%20recorded%20using%20the%20MediaRecorder%20API%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Estream%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EshadowCanvas%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EcaptureStream%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E60%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22c1%22%3E%2F%2F%2060%20FPS%20recording%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Erecorder%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EMediaRecorder%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Estream%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3EmimeType%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Evideo%2Fwebm%3Bcodecs%3Dvp9%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Erecorder%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eondataavailable%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ee%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22p%22%3E%7B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Echunks%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Epush%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Ee%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Edata%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22p%22%3E%7D)%2C%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Erecorder%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Estart%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22mi%22%3E500%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CP%3E...and%20displayed%20below%20as%20a%20video%20with%20the%20storyline%20in%20a%20new%20div%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22highlight%20js-code-highlight%22%3E%0A%3CPRE%20class%3D%22highlight%20javascript%22%3E%3CCODE%3E%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nb%22%3Edocument%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EcreateElement%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EfullBlob%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22k%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EBlob%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22k%22%3Ethis%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Echunks%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22kd%22%3Econst%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EdownloadUrl%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nb%22%3Ewindow%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EURL%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EcreateObjectURL%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EfullBlob%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Esrc%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22nx%22%3EdownloadUrl%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22nb%22%3Edocument%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EgetElementById%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22s2%22%3Estory%3C%2FSPAN%3E%3CSPAN%20class%3D%22dl%22%3E%22%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E).%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3EappendChild%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E(%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E)%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Eautoplay%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22kc%22%3Etrue%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22nx%22%3Evideo%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E.%3C%2FSPAN%3E%3CSPAN%20class%3D%22nx%22%3Econtrols%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22o%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22kc%22%3Etrue%3C%2FSPAN%3E%3CSPAN%20class%3D%22p%22%3E%3B%3C%2FSPAN%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CDIV%20class%3D%22highlight__panel%20js-actions-panel%22%3E%0A%3CDIV%20class%3D%22highlight__panel-action%20js-fullscreen-code-action%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CP%3EThis%20app%20can%20be%20deployed%20as%20an%20Azure%20Static%20Web%20App%20using%20the%20excellent%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fmicrosoft%2Fvscode-azurestaticwebapps%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EAzure%20plugin%20for%20Visual%20Studio%20Code%3C%2FA%3E.%20And%20once%20it's%20live%2C%20you%20can%20tell%20durable%20shadow%20stories!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jelooper_6-1613690550392.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F255926i4747DEF9FF5D67A3%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22jelooper_6-1613690550392.png%22%20alt%3D%22jelooper_6-1613690550392.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3ETry%20Ombromanie%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Faka.ms%2Fombromanie%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%20The%20codebase%20is%20available%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Faka.ms%2Fombromanie-code%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehere%3C%2FA%3E%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3ETake%20a%20look%20at%20Ombromanie%20in%20action%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIFRAME%20src%3D%22https%3A%2F%2Fwww.youtube.com%2Fembed%2FHV__puO1Dco%22%20width%3D%22560%22%20height%3D%22315%22%20frameborder%3D%220%22%20allowfullscreen%3D%22allowfullscreen%22%20allow%3D%22accelerometer%3B%20autoplay%3B%20clipboard-write%3B%20encrypted-media%3B%20gyroscope%3B%20picture-in-picture%22%3E%3C%2FIFRAME%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fazure.microsoft.com%2Foverview%2Fai-platform%2Fdev-resources%2F%3FOCID%3DAID3029145%26amp%3BWT.mc_id%3Dca-14261-jelooper%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3ELearn%20more%20about%20AI%20on%20Azure%3C%2FA%3E%3CBR%20%2F%3E%3CA%20href%3D%22https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dh281NX568rU%26amp%3Blist%3DPLLasX02E8BPBkMW8mAyNcRxk4e3l-l_p0%26amp%3Bindex%3D4%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3EAzure%20AI%20Essentials%20Video%20covering%20speech%20and%20language%3C%2FA%3E%3CBR%20%2F%3E%3CA%20href%3D%22https%3A%2F%2Fazure.microsoft.com%2Fen-us%2Ffree%2F%3FOCID%3DAID3029145%26amp%3BWT.mc_id%3Dca-14261-jelooper%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EAzure%20free%20account%20sign-up%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1822815%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EThis%20is%20an%20article%20for%20all%20those%20big%20siblings%20who%20sneaked%20flashlights%20into%20their%20bedroom%20to%20cast%20scary%20shadows%20onto%20the%20wall%2C%20and%20for%20all%20the%20little%20kids%2C%20or%20the%20grownups%20who%20are%20still%20kids%20at%20heart%2C%20who%20were%20thus%20deliciously%20entertained.%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1822815%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3Eazure%20speech%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3Etensorflow.js%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Co-Authors
Version history
Last update:
‎Feb 19 2021 05:41 PM
Updated by: