From 3cf5e17cc51593437b6cebd6f2ffba106201a97c Mon Sep 17 00:00:00 2001 From: Donald Jones Date: Mon, 21 Sep 2015 12:16:42 -0500 Subject: [PATCH] Simplified code, improved performance. --- index.html | 4 +- mirror_motion.js | 229 +++++++++++++++++++++++------------------------ 2 files changed, 115 insertions(+), 118 deletions(-) diff --git a/index.html b/index.html index b818a60..ecaeba4 100644 --- a/index.html +++ b/index.html @@ -60,9 +60,7 @@ \ No newline at end of file diff --git a/mirror_motion.js b/mirror_motion.js index 25d62b1..73a3b83 100644 --- a/mirror_motion.js +++ b/mirror_motion.js @@ -1,6 +1,16 @@ -var gui = global.window.nwDispatcher.requireNwGui(); -var guiWindow = gui.Window.get(); -var config = require('./config.json'); +var gui = global.window.nwDispatcher.requireNwGui(), + guiWindow = gui.Window.get(), + config = require('./config.json'), + buffers = [], + index = 0, + width = 0, + height = 0, + motionTimer = 0, + context, + canvas, + video, + win, + hideTimeout; var previousLocation = { x: 0, @@ -21,117 +31,106 @@ var showBody = function() { guiWindow.y = previousLocation.y; }; -var MirrorMotion = function() { - return { - buffers: [], - index: 0, - width: 0, - height: 0, - - initialize: function(videoElement, canvasElement) { - this.win = gui.Window.get(); - this.video = document.getElementById(videoElement); - this.canvas = document.getElementById(canvasElement); - this.context = this.canvas.getContext('2d'); - this.motionTimer = 0; - - this.width = this.canvas.width; - this.height = this.canvas.height; - - previousLocation.x = guiWindow.x; - previousLocation.y = guiWindow.y; - - for (var i = 0; i < 2; i++) { - this.buffers.push(new Uint8Array(this.width * this.height)); - } - - navigator.webkitGetUserMedia({ - video: true - }, this.start.bind(this), this.fail); - }, - - start: function(stream) { - this.video.src = URL.createObjectURL(stream); - this.video.play(); - - if (config.debug) { - this.canvas.style.visibility = 'visible'; - } - - requestAnimationFrame(this.analyzeFrame.bind(this)); - }, - - fail: function() { - alert('Failed to start video stream. Is something else using your camera?'); - }, - - getFrame: function() { - try { - this.context.drawImage(this.video, 0, 0, this.width, this.height); - } catch (e) { - return; - } - - return this.context.getImageData(0, 0, this.width, this.height); - }, - - analyzeFrame: function() { - var frame = this.getFrame(); - - if (frame) { - this.markFrame(frame.data); - this.drawFrame(frame); - } - - requestAnimationFrame(this.analyzeFrame.bind(this)); - }, - - drawFrame: function(frame) { - if (this.motionTimer < 50000) { - if (guiWindow.x < 0 || guiWindow.y < 0) { - showBody(); - } - - if (this.hideTimeout) { - window.clearTimeout(this.hideTimeout); - } - - this.hideTimeout = window.setTimeout(function() { - hideBody(); - }, config.timer); - } - this.context.putImageData(frame, 0, 0); - }, - - markFrame: function(data) { - var buffers = this.buffers; - - var buffer = buffers[this.index++ % buffers.length]; - - for (var i = 0, j = 0; i < buffer.length; i++, j += 4) { - var current = this.calulateLightnessValue(data[j], data[j + 1], data[j + 2]); - - data[j] = data[j + 1] = data[j + 2] = 255; - data[j + 3] = 255 * this.calculateLightnessDiff(i, current); - buffer[i] = current; - } - }, - - calulateLightnessValue(r, g, b) { - return (Math.min(r, g, b) + Math.max(r, g, b)) / 255 * 50; - }, - - calculateLightnessDiff(index, value) { - return this.buffers.some(function(buffer) { - var diff = Math.abs(value - buffer[index]) >= config.threshold; - this.motionTimer++; - - if (diff) { - this.motionTimer = 0; - } - - return diff; - }.bind(this)); +var initialize = function(videoElement, canvasElement) { + win = gui.Window.get(); + video = document.getElementById(videoElement); + canvas = document.getElementById(canvasElement); + context = canvas.getContext('2d'); + motionTimer = 0; + + width = canvas.width; + height = canvas.height; + + previousLocation.x = guiWindow.x; + previousLocation.y = guiWindow.y; + + for (var i = 0; i < 2; i++) { + buffers.push(new Uint8Array(width * height)); + } + + navigator.webkitGetUserMedia({ + video: true + }, start, fail); +}; + +var start = function(stream) { + video.src = URL.createObjectURL(stream); + video.play(); + + if (config.debug) { + canvas.style.visibility = 'visible'; + } + + requestAnimationFrame(analyzeFrame); +}; + +var fail = function() { + alert('Failed to start video stream. Is something else using your camera?'); +}; + +var getFrame = function() { + try { + context.drawImage(video, 0, 0, width, height); + } catch (e) { + return; + } + + return context.getImageData(0, 0, width, height); +}; + +var analyzeFrame = function() { + var frame = getFrame(); + + if (frame) { + markFrame(frame.data); + drawFrame(frame); + } + + requestAnimationFrame(analyzeFrame); +}; + +var drawFrame = function(frame) { + if (motionTimer < 50000) { + if (guiWindow.x < 0 || guiWindow.y < 0) { + showBody(); + } + + if (hideTimeout) { + window.clearTimeout(hideTimeout); } - }; + + hideTimeout = window.setTimeout(function() { + hideBody(); + }, config.timer); + } + context.putImageData(frame, 0, 0); +}; + +var markFrame = function(data) { + var buffer = buffers[index++ % buffers.length]; + + for (var i = 0, j = 0; i < buffer.length; i++, j += 4) { + var current = calulateLightnessValue(data[j], data[j + 1], data[j + 2]); + + data[j] = data[j + 1] = data[j + 2] = 255; + data[j + 3] = 255 * calculateLightnessDiff(i, current); + buffer[i] = current; + } +}; + +var calulateLightnessValue = function(r, g, b) { + return (Math.min(r, g, b) + Math.max(r, g, b)) / 255 * 50; +}; + +var calculateLightnessDiff = function(index, value) { + return buffers.some(function(buffer) { + var diff = Math.abs(value - buffer[index]) >= config.threshold; + motionTimer++; + + if (diff) { + motionTimer = 0; + } + + return diff; + }); }; \ No newline at end of file