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,
...