JSFiddle - React, Tailwind, and code Playground

by PhilQ

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsfeat/0.0.8/jsfeat-min.js"></script>
<script src="https://inspirit.github.io/jsfeat/js/compatibility.js"></script>
<script src="https://inspirit.github.io/jsfeat/js/profiler.js"></script>
<script src="https://inspirit.github.io/jsfeat/js/dat.gui.min.js"></script>
<video id="webcam" width="640" height="480" style="display:none;"></video>
<canvas id="canvas" width="640" height="480"></canvas>
<canvas id="canvas2" width="640" height="480"></canvas>
<div id="no_rtc" class="alert alert-error" style="display:none;"></div>
<div id="log" class="alert alert-info"></div>

CSS

canvas {
  width: 100%;
  height: auto;
}
#canvas2 {
  image-rendering: optimizeSpeed;             /* STOP SMOOTHING, GIVE ME SPEED  */
  image-rendering: -moz-crisp-edges;          /* Firefox                        */
  image-rendering: -o-crisp-edges;            /* Opera                          */
  image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
  image-rendering: pixelated; /* Chrome */
  image-rendering: optimize-contrast;         /* CSS3 Proposed                  */
  -ms-interpolation-mode: nearest-neighbor;   /* IE8+                           */
}

JavaScript

$(window).load(function() {
  "use strict";

  // lets do some fun
  var video = document.getElementById('webcam');
  var canvas = document.getElementById('canvas');
  var canvas2 = document.getElementById('canvas2');
  try {
    var attempts = 0;
    var readyListener = function(event) {
      findVideoSize();
    };
    var findVideoSize = function() {
      if (video.videoWidth > 0 && video.videoHeight > 0) {
        video.removeEventListener('loadeddata', readyListener);
        onDimensionsReady(video.videoWidth, video.videoHeight);
      } else {
        if (attempts < 10) {
          attempts++;
          setTimeout(findVideoSize, 200);
        } else {
          onDimensionsReady(640, 480);
        }
      }
    };
    var onDimensionsReady = function(width, height) {
      demo_app(width, height);
      compatibility.requestAnimationFrame(tick);
    };

    video.addEventListener('loadeddata', readyListener);

    compatibility.getUserMedia({ video: true }, function(stream) {
      if ('srcObject' in video) {
        video.srcObject = stream;
      } else {
        video.src = window.URL.createObjectURL(stream);
      }
      setTimeout(function() {
        video.play();
      }, 500);
    }, function(error) {
      $('#canvas').hide();
      $('#log').hide();
      $('#no_rtc').html('<h4>WebRTC not available.</h4>');
      $('#no_rtc').show();
    });
  } catch (error) {
    $('#canvas').hide();
    $('#log').hide();
    $('#no_rtc').html('<h4>Something goes wrong...</h4>');
    $('#no_rtc').show();
  }

  var stat = new profiler();

  var gui, options, ctx, ctx2, canvasWidth, canvasHeight;
  var img_u8;
  var img2_u8;
  var ar_sum, ar_sqsum, ar_tilted;
  var do_once = 1;
  const g = 20;

  var demo_opt = function() {
    this.blur_radius = 2;
    this.low_threshold = 20;
    this.high_threshold = 50;
  }

  function demo_app(videoWidth, videoHeight) {
    canvasWidth = canvas.width;
    canvasHeight = canvas.height;
		canvas2.width =...