html5demos/demos/gum-canvas.html

159 lines
4.8 KiB
HTML

<title>getUserMedia with canvas effects</title>
<style>
#gum {
background: #c00;
color: #fff;
padding: 10px;
}
/* I'm using CSS3 to translate the video on the X axis to give it a mirror effect */
#source {
display: block;
margin: 20px 0;
max-width: 100%;
}
.supported #source { -webkit-transform: rotateY(180deg) rotate3d(1, 0, 0, 0deg);
-o-transform: rotateY(180deg) rotate3d(1, 0, 0, 0deg);
-moz-transform: rotateY(180deg) rotate3d(1, 0, 0, 0deg);
-ms-transform: rotateY(180deg) rotate3d(1, 0, 0, 0deg);
transform: rotateY(180deg) rotate3d(1, 0, 0, 0deg);
}
video, canvas { display: none; }
input { width: 360px; }
</style>
<article>
<label for="hue">Colour <input type="range" min="0" max="360" value="0" id="hue"></label> <output id="target"></output>
<video id="video" muted loop autoplay>
<source src="/assets/remy-and-ellis2.mp4"></source>
<source src="/assets/remy-and-ellis2.webm"></source>
</video>
<canvas id="source"></canvas>
<p id="gum">getUserMeda either not supported or not allowed - so instead here's me and my son headbanging.</p>
</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];
};
function init() {
// from HTML5 Doctor article: http://html5doctor.com/getusermedia/
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 () {
source.canvas.width = video.videoWidth;
source.canvas.height = video.videoHeight;
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) {
// brightness code from Tab Atkins' canvas demos
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
}
output.putImageData(pixels, 0, 0);
}
// shim layer with setTimeout fallback - from Paul Irish
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var article = video.parentNode,
gum = document.getElementById('gum');
if (navigator.getUserMedia || navigator.webkitGetUserMedia) {
article.removeChild(gum);
article.className = 'supported';
init();
}
</script>
</body>
</html>