Author: | Louis Hoebregts |
---|---|
Views Total: | 673 views |
Official Page: | Go to website |
Last Update: | May 7, 2018 |
License: | MIT |
Preview:

Description:
Makes use of JavaScript and HTML5 canvas to create a fancy halftone mask effect on your HTML5 video.
How to use it:
Embed an HTML5 video into the page.
<video src="sample.mp4" loop muted autoplay crossorigin="anonymous"></video>
Create an empty canvas on which you want to render the halftone effect.
<canvas class="scene"></canvas>
The main JavaScript to render the halftone effect on the HTML5 video.
const v = document.querySelector('video'); const canvas = document.querySelector('canvas.scene'); const ctx = canvas.getContext('2d'); let width = canvas.offsetWidth; let height = canvas.offsetHeight; canvas.width = width; canvas.height = height; window.addEventListener('resize', () => { width = canvas.offsetWidth; height = canvas.offsetHeight; fakeSize = Math.min(100, Math.ceil(window.innerWidth / 12)); pRatio = width / fakeSize; canvas.width = width; canvas.height = height; fakeCanvas.width = fakeSize; fakeCanvas.height = fakeSize; videoParameters(); createPoints(); }); const videoParameters = () => { v._opts = { left: 0, top: 0, width: 0, height: 0 }; v._opts.width = width; v._opts.ratio = (width / v.offsetWidth); v._opts.height = v.offsetHeight * v._opts.ratio; v._opts.left = (width - v._opts.width) /2; v._opts.top = (width - v._opts.height) /2; }; const fakeCanvas = document.createElement('canvas'); const fakeCtx = fakeCanvas.getContext('2d'); let fakeSize = Math.ceil(window.innerWidth / 12); let pRatio = width / fakeSize; fakeCanvas.width = fakeSize; fakeCanvas.height = fakeSize; const getPoints = () => { fakeCtx.clearRect(0, 0, fakeSize, fakeSize); fakeCtx.fillStyle = 'white'; fakeCtx.fillRect(0, 0, fakeSize, fakeSize); fakeCtx.drawImage(canvas, 0, 0, fakeSize, fakeSize); const canvasData = fakeCtx.getImageData(0, 0, fakeSize, fakeSize).data; for (let x = 0; x < fakeSize; x++) { for (let y = 0; y < fakeSize; y++) { const p = points[x * fakeSize + y]; const red = canvasData[(y * fakeSize + x) * 4 + 0] / 255; const green = canvasData[(y * fakeSize + x) * 4 + 1] / 255; const blue = canvasData[(y * fakeSize + x) * 4 + 2] / 255; const gray = (red * 0.2126 + green * 0.7152 + blue * 0.0722); const radius = 1 - gray; p.r += (radius * pRatio - p.r) * 0.1; } } }; let points = []; const createPoints = () => { points = []; for (let x = 0; x < fakeSize; x++) { for (let y = 0; y < fakeSize; y++) { const point = { x: x * pRatio, y: y * pRatio, r: 0 }; points.push(point); } } } const render = () => { window.requestAnimationFrame(render); ctx.clearRect(0, 0, width, height); ctx.drawImage(v, v._opts.left, v._opts.top, v._opts.width, v._opts.height); getPoints(); ctx.clearRect(0, 0, width, height); // Draw the points for (let i = 0; i < points.length; i++) { const p = points[i]; if (p.r > 0) { if (i%2 === 0) { ctx.fillRect(p.x - p.r, p.y - p.r, p.r, p.r); } else { ctx.fillRect(p.x - p.r + pRatio *0.5, p.y - p.r, p.r, p.r); } } } }; videoParameters(); v.addEventListener('canplay', () => { createPoints(); window.requestAnimationFrame(render); }, { once: true }); // Handle user webcam const startWebcam = (stream) => { v.src = window.URL.createObjectURL(stream); v.addEventListener('canplay', () => { videoParameters(); }, { once: true }); } navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; if (navigator.getUserMedia) { navigator.getUserMedia({video: true}, startWebcam, (error) => {console.log(error)}); }