137 lines
4.2 KiB
HTML
137 lines
4.2 KiB
HTML
|
<title>getUserMedia with canvas effects</title>
|
||
|
<style>
|
||
|
#source { -webkit-transform: rotateY(180deg) rotate3d(1, 0, 0, 0deg); display: block; margin: 20px 0; max-width: 100%; }
|
||
|
#strip { display: block; }
|
||
|
video, canvas { display: none; }
|
||
|
input { width: 360px ;}
|
||
|
output { display: inline-block; width: 16px; height: 16px; background: red; padding: 0; margin: 0;}
|
||
|
</style>
|
||
|
<article>
|
||
|
<label for="hue">Colour <input type="range" min="0" max="360" value="0" id="hue"></label> <output id="target"></output>
|
||
|
<video autoplay></video>
|
||
|
<canvas id="source"></canvas>
|
||
|
</article>
|
||
|
<script>
|
||
|
var video = document.querySelector('video'),
|
||
|
source = document.getElementById('source').getContext('2d'),
|
||
|
output = source, //document.getElementById('output').getContext('2d'),
|
||
|
slider = document.getElementById('hue'),
|
||
|
target = document.getElementById('target'),
|
||
|
tr = 255, tg = 0, tb = 0,
|
||
|
width = 160,
|
||
|
height = 120;
|
||
|
|
||
|
/**
|
||
|
* Converts an HSL color value to RGB. Conversion formula
|
||
|
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
|
||
|
* Assumes h, s, and l are contained in the set [0, 1] and
|
||
|
* returns r, g, and b in the set [0, 255].
|
||
|
*
|
||
|
* @param Number h The hue
|
||
|
* @param Number s The saturation
|
||
|
* @param Number l The lightness
|
||
|
* @return Array The RGB representation
|
||
|
*/
|
||
|
function hslToRgb(h, s, l){
|
||
|
var r, g, b;
|
||
|
|
||
|
if (s == 0) {
|
||
|
r = g = b = l; // achromatic
|
||
|
} else {
|
||
|
function hue2rgb(p, q, t) {
|
||
|
if(t < 0) t += 1;
|
||
|
if(t > 1) t -= 1;
|
||
|
if(t < 1/6) return p + (q - p) * 6 * t;
|
||
|
if(t < 1/2) return q;
|
||
|
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||
|
var p = 2 * l - q;
|
||
|
r = hue2rgb(p, q, h + 1/3);
|
||
|
g = hue2rgb(p, q, h);
|
||
|
b = hue2rgb(p, q, h - 1/3);
|
||
|
}
|
||
|
|
||
|
return [r * 255, g * 255, b * 255];
|
||
|
}
|
||
|
|
||
|
slider.oninput = slider.onchange = function () {
|
||
|
target.style.background = 'hsl(' + this.value + ', 100%, 50%)';
|
||
|
var rgb = hslToRgb(this.value/360, 1, 0.6);
|
||
|
tr = rgb[0];
|
||
|
tg = rgb[1];
|
||
|
tb = rgb[2];
|
||
|
// console.log(brightness / 256);
|
||
|
};
|
||
|
|
||
|
|
||
|
function init() {
|
||
|
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
|
||
|
if (navigator.getUserMedia) {
|
||
|
navigator.getUserMedia('video', successCallback, errorCallback);
|
||
|
// Below is the latest syntax. Using the old syntax for the time being for backwards compatibility.
|
||
|
//navigator.getUserMedia({video: true}, successCallback, errorCallback);
|
||
|
function successCallback(stream) {
|
||
|
window.stream = stream;
|
||
|
if (window.webkitURL) {
|
||
|
video.src = window.webkitURL.createObjectURL(stream);
|
||
|
} else {
|
||
|
video.src = stream;
|
||
|
}
|
||
|
}
|
||
|
function errorCallback(error) {
|
||
|
console.error('An error occurred: [CODE ' + error.code + ']');
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
video.addEventListener('loadedmetadata', function () {
|
||
|
// output.canvas.width = ;
|
||
|
source.canvas.width = video.videoWidth;
|
||
|
// output.canvas.height =
|
||
|
source.canvas.height = video.videoHeight;
|
||
|
// source.canvas.height = height;
|
||
|
// source.canvas.width = width;
|
||
|
draw();
|
||
|
});
|
||
|
|
||
|
|
||
|
function draw() {
|
||
|
requestAnimFrame(draw);
|
||
|
source.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, source.canvas.width, source.canvas.height);
|
||
|
var pixels = source.getImageData(0, 0, source.canvas.width, source.canvas.height),
|
||
|
i = 0,
|
||
|
brightness;
|
||
|
|
||
|
for (; i < pixels.data.length; i += 4) {
|
||
|
// grey = r*.3 + g*.59 + b*.11;
|
||
|
brightness = ((3*pixels.data[i]+4*pixels.data[i+1]+pixels.data[i+2])>>>3) / 256;
|
||
|
|
||
|
pixels.data[i] = ((tr * brightness)+0.5)>>0;
|
||
|
pixels.data[i+1] = ((tg * brightness)+0.5)>>0
|
||
|
pixels.data[i+2] = ((tb * brightness)+0.5)>>0
|
||
|
// pixels.data[i+2] = 0;
|
||
|
}
|
||
|
output.putImageData(pixels, 0, 0);
|
||
|
}
|
||
|
|
||
|
// shim layer with setTimeout fallback
|
||
|
window.requestAnimFrame = (function(){
|
||
|
return window.requestAnimationFrame ||
|
||
|
window.webkitRequestAnimationFrame ||
|
||
|
window.mozRequestAnimationFrame ||
|
||
|
window.oRequestAnimationFrame ||
|
||
|
window.msRequestAnimationFrame ||
|
||
|
function( callback ){
|
||
|
window.setTimeout(callback, 1000 / 60);
|
||
|
};
|
||
|
})();
|
||
|
|
||
|
|
||
|
init();
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|