JSFiddle - React, Tailwind, and code Playground

by PeeHaa

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>ScreenCast library demo</title>
    <link href='http://fonts.googleapis.com/css?family=Ranchers' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" href="style/style.css">
    <script>
      document.createElement('header');
      document.createElement('nav');
      document.createElement('section');
      document.createElement('article');
      document.createElement('aside');
      document.createElement('footer');
      document.createElement('time');
    </script>
  </head>
  <body>
    <header>
      <h1>ScreenCast</h1>
    </header>
    <div id="body">
      <video autoplay="autoplay"></video>
      <ul class="effects">
        <li><a href="#" class="button blue" data-effect="grayscale">Grayscale</a></li>
        <li><a href="#" class="button blue" data-effect="sepia">Sepia</a></li>
        <li><a href="#" class="button blue" data-effect="blur">Blur</a></li>
        <li><a href="#" class="button blue" data-effect="brightness">Brightness</a></li>
        <li><a href="#" class="button blue" data-effect="contrast">Contrast</a></li>
        <li><a href="#" class="button blue" data-effect="hue-rotate-90">Hue rotate (90°)</a></li>
        <li><a href="#" class="button blue" data-effect="hue-rotate-180">Hue rotate (180°)</a></li>
        <li><a href="#" class="button blue" data-effect="hue-rotate-270">Hue rotate (270°)</a></li>
        <li><a href="#" class="button blue" data-effect="saturate">Saturate</a></li>
        <li><a href="#" class="button blue" data-effect="invert">Invert</a></li>
      </ul>
    </div>
    <script src="js/ScreenCast/ScreenCast.js"></script>
    <script src="js/main.js"></script>
  </body>
</html>

CSS

body { font-family: Arial,Helvetica,sans-serif; font-size: 100%; background: #efefef; color: #444444; line-height: 1.5em; text-align: center; padding: 60px 0 0; margin: 0; }

header { position: fixed; width: 100%; height: 60px; background: white; top: 0; left: 0; -webkit-box-shadow: 0 0 5px #B4B4B4,transparent 0 0 0,transparent 0 0 0,transparent 0 0 0,transparent 0 0 0; -moz-box-shadow: 0 0 5px #b4b4b4,transparent 0 0 0,transparent 0 0 0,transparent 0 0 0,transparent 0 0 0; box-shadow: 0 0 5px #B4B4B4,transparent 0 0 0,transparent 0 0 0,transparent 0 0 0,transparent 0 0 0; z-index: 1000; }
header h1 { font-family: 'Ranchers', cursive; text-shadow: 0 1px 3px rgba(73,175,205,1); width: 980px; margin: 18px auto; text-align: left; }

#body { width: 980px; margin: 0 auto; }

.button.blue { background-color: #49AFCD; background-image: -ms-linear-gradient(top,#5BC0DE,#2F96B4); background-image: -webkit-gradient(linear,0 0,0 100%,from(#5BC0DE),to(#2F96B4)); background-image: -webkit-linear-gradient(top,#5BC0DE,#2F96B4); background-image: -o-linear-gradient(top,#5BC0DE,#2F96B4); background-image: -moz-linear-gradient(top,#5BC0DE,#2F96B4); background-image: linear-gradient(top,#5BC0DE,#2F96B4); background-repeat: repeat-x; border-color: #2F96B4 #2F96B4 #1F6377; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de',endColorstr='#2f96b4',GradientType=0); filter: progid:dximagetransform.microsoft.gradient(enabled=false); color: white; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); padding: 9px 14px; font-size: 15px; line-height: normal; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; float: left; text-align: center; vertical-align: middle; cursor: pointer; border: 1px solid #CCC; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05); box-shadow:...

JavaScript

'use strict';

function ScreenCast(element) {
    this.element = element;
    this.userMediaObject = null;
    this.stream = null;

    // should be refactored
    this.recorder = null;

    this.initialize();
}

ScreenCast.prototype.initialize = function() {
    if (!this.isSupported()) {
        console.log('Your browser doesn\'t support ScreenCast.');
        return;
    }

    this.setUserMediaObject();
};

ScreenCast.prototype.isSupported = function() {
    return !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
};

ScreenCast.prototype.setUserMediaObject = function() {
    this.userMediaObject = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
};

ScreenCast.prototype.start = function() {
    this.userMediaObject.call(navigator, {
        video: true,
        audio: true
    }, function(localMediaStream) {
        this.stream = localMediaStream;

        // should be separated from this class?
        this.element.src = window.URL.createObjectURL(localMediaStream);

        // Note: onloadedmetadata doesn't fire in Chrome when using it with getUserMedia.
        // See crbug.com/110938.
        this.element.onloadedmetadata = function(e) {
            console.log('Something happened. Do some stuff');
        };
    }.bind(this), function(e) {
        if (e.code === 1) {
          console.log('User declined permissions.');
        }
    });
};

HTMLElement.prototype.hasClass = function(className) {
    var pattern = new RegExp('\\b' + className + '\\b');

    return pattern.test(this.className);
};

NodeList.prototype.each = function(callback) {
    for (var i = 0, numberOfElements = this.length; i < numberOfElements; i++) {
        callback(this[i]);
    }
};

(function() {
    var videoElement = document.querySelector('video');
    var screenCast = new ScreenCast(videoElement);

    screenCast.start();

    var effectButtons =...