Day 19: JavaScript Challenge
In this challenge we have our video piped in from our webcam and we put that in a canvas element.
After it is in a canvas element, we are able to manipulate the element to take pictures and add cool effects.
We add the effects by manipulating the array of colour values taken from the getImageData() function from the Canvas Api.
This was really fun. Check out the demo!
Code snippets shown below:
const video = document.querySelector('.player');
const canvas = document.querySelector('.photo');
const ctx = canvas.getContext('2d');
const strip = document.querySelector('.strip');
const snap = document.querySelector('.snap');
function getVideo() {
navigator.mediaDevices
.getUserMedia({ video: true, audio: false })
.then(localMediaStream => {
console.log(localMediaStream);
video.srcObject = localMediaStream;
video.play();
})
.catch(err => {
console.log('Oh No! ' + err);
});
}
function paintToCanvas() {
const width = video.videoWidth;
const height = video.videoHeight;
canvas.width = width;
canvas.height = height;
return setInterval(() => {
ctx.drawImage(video, 0, 0, width, height);
// take the pixels out
let pixels = ctx.getImageData(0, 0, width, height);
// mess with them
// pixels = redEffect(pixels);
// pixels = rgbSplit(pixels);
pixels = greenScreen(pixels);
ctx.globalAlpha = 0.5;
// put them back
ctx.putImageData(pixels, 0, 0);
}, 16);
}
function takePhoto() {
// play sound
snap.currentTime = 0;
snap.play();
// take the data out of the canvas
const data = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = data;
link.setAttribute('download', 'handsome');
link.innerHTML = `<img src="${data}" alt="Handsome Man" />`;
strip.insertBefore(link, strip.firstChild);
}
function redEffect(pixels) {
for (let i = 0; i < pixels.data.length; i += 4) {
pixels.data[i + 0] = pixels.data[i + 0] + 100; // red
pixels.data[i + 1] = pixels.data[i + 1] - 50; // green
pixels.data[i + 2] = pixels.data[i + 2] * 0.5; // blue
}
return pixels;
}
function rgbSplit(pixels) {
for (let i = 0; i < pixels.data.length; i += 4) {
pixels.data[i - 150] = pixels.data[i + 0]; // RED
pixels.data[i + 500] = pixels.data[i + 1]; // GREEN
pixels.data[i - 550] = pixels.data[i + 2]; // Blue
}
return pixels;
}
function greenScreen(pixels) {
const levels = {};
document.querySelectorAll('.rgb input').forEach(input => {
levels[input.name] = input.value;
});
for (i = 0; i < pixels.data.length; i = i + 4) {
red = pixels.data[i + 0];
green = pixels.data[i + 1];
blue = pixels.data[i + 2];
alpha = pixels.data[i + 3];
if (
red >= levels.rmin &&
green >= levels.gmin &&
blue >= levels.bmin &&
red <= levels.rmax &&
green <= levels.gmax &&
blue <= levels.bmax
) {
// take it out!
pixels.data[i + 3] = 0;
}
}
return pixels;
}
getVideo();
video.addEventListener('canplay', paintToCanvas);