Glitchcam

Playing with glitching up webcam input

by mich

HTML

<video id="recording" autoplay></video>
<canvas id="output" width="640" height="480"></canvas>
<div id="controls">
    <div>
        <label><span>Red max random:</span> <input id="redrandom" type="number" min="0" max="128" value="100"/></label>
        <label><span>Green max random:</span> <input id="greenrandom" type="number" min="0" max="128" value="100"/></label>
        <label><span>Blue max random:</span> <input id="bluerandom" type="number" min="0" max="128" value="100"/></label>
    </div>
    <div>
        <label><span>Max columns:</span> <input id="maxcols" type="number" min="0" max="200" value="10"/></label>
        <label><span>Max rows:</span> <input id="maxrows" type="number" min="0" max="200" value="10"/></label>
    </div>
    <div>
        <label><span>Cell mixup attempt interval (ms):</span> <input id="shuffleinterval" type="number" min="50" max="10000" value="250" /></label>

        <label><span>Cell mixup unlikelihood:</span> <input id="shufflerandomindex" type="number" min="0" max="1000" value="20"/></label>
    </div>
</div>

CSS

body {
  font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
}
canvas, #controls {
    display: block;
    margin: 20px auto;
}
canvas {
    width: 640px;
    height: 480px;
    border: solid 2px #AAA;
}
video {
    position: fixed;
    width: 160px;
    height: 120px;
    top: 0;
    right: 0;
    opacity: 0.4;
    box-shadow: 0 0 4px 1px #000;
    transition: all 500ms ease;
}

video:hover {
    opacity: 1;
    width: 320px;
    height: 240px;
}
#controls {
    padding: 20px;
    background-color: #DDD;
    width: 350px;
}
#controls div {
  margin-bottom: 10px;
  padding-bottom: 10px;
}
#controls div:last-child {
    margin-bottom: 0;
    padding-bottom: 0;
}

label {
    display: block;
}

label span {
    display: inline-block;
    width: 250px;
}
label input {
    width: 75px;
}

JavaScript

function fisherYates(myArray) {
    var i = myArray.length,
        j, temp;
    if (i === 0) return false;
    while (--i) {
        j = Math.floor(Math.random() * (i + 1));
        temp = myArray[i];
        myArray[i] = myArray[j];
        myArray[j] = temp;
    }
}


(function () { // SET UP CAMERA, not part of fun effects
    var getUserMedia;

    function hasGetUserMedia() {
        return !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
    }

    getUserMedia = (function () {
        var vendorFunc = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
        return function () {
            return Function.prototype.apply.apply(vendorFunc, [navigator, arguments]);
        };
    }());

    if (!hasGetUserMedia()) {
        return alert('Yo, get a modern browser.');
    }

    getUserMedia({
        video: true
    }, function (localMediaStream) {
        document.getElementById('recording').src = window.URL.createObjectURL(localMediaStream);
    }, function () {
        alert('REJECTED.');
    });
}());

(function () { // FUN BEGINS HERE
    var
    vid = document.getElementById('recording'),
        cv = document.getElementById('output'),        
        ctx = cv.getContext('2d'),
        portionMix = [],
        shuffleTimeout = null,
        uiControls = {
            redrandom: document.getElementById('redrandom'),
            greenrandom: document.getElementById('greenrandom'),
            bluerandom: document.getElementById('bluerandom'),
            maxcols: document.getElementById('maxcols'),
            maxrows: document.getElementById('maxrows'),
            shuffleinterval: document.getElementById('shuffleinterval'),
            shufflerandomindex: document.getElementById('shufflerandomindex')            
        },
        settings = {
            redrandom: {
                min: 0,
                max: 128,
     ...