├── README.md ├── img └── demo.gif ├── index.html ├── js ├── MotionDetector │ ├── Core.js │ ├── ImageCompare.js │ └── WebCamCapture.js ├── global.js └── main.js └── styles └── main.css /README.md: -------------------------------------------------------------------------------- 1 | # Motion-Detector-HTML5 2 | 3 | 一个基于HTML5的体感追踪小demo _(:3 」∠)_ 4 | 5 | demo: 6 | ![demo](https://github.com/KivyGogh/Motion-Detector-HTML5/blob/master/img/demo.gif) 7 | -------------------------------------------------------------------------------- /img/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KivyGogh/Motion-Detector-HTML5/91b5465683ce93e773a760fb48aceaf244f51476/img/demo.gif -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Motion Detector 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /js/MotionDetector/Core.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Motion-Detector-HTML5 4 | * GAO 5 | * 6 | */ 7 | ;(function(App) { 8 | 9 | "use strict"; 10 | 11 | App.Core = function() { 12 | 13 | var rendering = false; 14 | 15 | var width = 64; 16 | var height = 48; 17 | 18 | var webCam = null; 19 | var imageCompare = null; 20 | 21 | var currentImage = null; 22 | var oldImage = null; 23 | 24 | var topLeft = [Infinity,Infinity]; 25 | var bottomRight = [0,0]; 26 | 27 | var raf = (function(){ 28 | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || 29 | function( callback ){ 30 | window.setTimeout(callback, 1000/60); 31 | }; 32 | })(); 33 | 34 | 35 | function initialize() { 36 | imageCompare = new App.ImageCompare(); 37 | webCam = new App.WebCamCapture(document.getElementById('webCamWindow')); 38 | 39 | rendering = true; 40 | 41 | main(); 42 | } 43 | 44 | 45 | function render() { 46 | oldImage = currentImage; 47 | currentImage = webCam.captureImage(false); 48 | 49 | if(!oldImage || !currentImage) { 50 | return; 51 | } 52 | 53 | var vals = imageCompare.compare(currentImage, oldImage, width, height); 54 | 55 | topLeft[0] = vals.topLeft[0] * 10; 56 | topLeft[1] = vals.topLeft[1] * 10; 57 | 58 | bottomRight[0] = vals.bottomRight[0] * 10; 59 | bottomRight[1] = vals.bottomRight[1] * 10; 60 | 61 | document.getElementById('movement').style.top = topLeft[1] + 'px'; 62 | document.getElementById('movement').style.left = topLeft[0] + 'px'; 63 | 64 | document.getElementById('movement').style.width = (bottomRight[0] - topLeft[0]) + 'px'; 65 | document.getElementById('movement').style.height = (bottomRight[1] - topLeft[1]) + 'px'; 66 | 67 | topLeft = [Infinity,Infinity]; 68 | bottomRight = [0,0] 69 | 70 | } 71 | 72 | function main() { 73 | try{ 74 | render(); 75 | } catch(e) { 76 | console.log(e); 77 | return; 78 | } 79 | 80 | if(rendering == true) { 81 | raf(main.bind(this)); 82 | } 83 | } 84 | 85 | initialize(); 86 | }; 87 | })(MotionDetector); -------------------------------------------------------------------------------- /js/MotionDetector/ImageCompare.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Motion-Detector-HTML5 4 | * GAO 5 | * 6 | */ 7 | ;(function(App) { 8 | 9 | "use strict"; 10 | 11 | // Compares to images and shows the difference starting from the top left to the bottom right. 12 | 13 | App.ImageCompare = function() { 14 | var sensitivity, temp1Canvas, temp1Context, temp2Canvas, temp2Context, topLeft, bottomRight; 15 | 16 | function initialize() { 17 | sensitivity = 40; 18 | 19 | if(!temp1Canvas) { 20 | temp1Canvas = document.createElement('canvas'); 21 | temp1Context = temp1Canvas.getContext("2d"); 22 | } 23 | 24 | if(!temp2Canvas) { 25 | temp2Canvas = document.createElement('canvas'); 26 | temp2Context = temp2Canvas.getContext("2d"); 27 | } 28 | 29 | topLeft = [Infinity,Infinity]; 30 | bottomRight = [0,0]; 31 | } 32 | 33 | // Compares to images. 34 | 35 | function compare(image1, image2, width, height) { 36 | initialize(); 37 | 38 | if(!image1 || !image2) { 39 | return; 40 | } 41 | 42 | temp1Context.clearRect(0,0,100000,100000); 43 | temp1Context.clearRect(0,0,100000,100000); 44 | 45 | temp1Context.drawImage(image1, 0, 0, width, height); 46 | temp2Context.drawImage(image2, 0, 0, width, height); 47 | 48 | 49 | for(var y = 0; y < height; y++) { 50 | for(var x = 0; x < width; x++) { 51 | var pixel1 = temp1Context.getImageData(x,y,1,1); 52 | var pixel1Data = pixel1.data; 53 | 54 | var pixel2 = temp2Context.getImageData(x,y,1,1); 55 | var pixel2Data = pixel2.data; 56 | 57 | if(comparePixel(pixel1Data, pixel2Data) == false) { 58 | setTopLeft(x,y); 59 | setBottomRight(x,y); 60 | } 61 | } 62 | } 63 | 64 | return { 65 | 'topLeft': topLeft, 66 | 'bottomRight': bottomRight 67 | } 68 | } 69 | 70 | function comparePixel(p1, p2) { 71 | var matches = true; 72 | 73 | for(var i = 0; i < p1.length; i++) { 74 | var t1 = Math.round(p1[i]/10)*10; 75 | var t2 = Math.round(p2[i]/10)*10; 76 | 77 | if(t1 != t2) { 78 | if((t1+sensitivity < t2 || t1-sensitivity > t2)) { 79 | matches = false; 80 | } 81 | } 82 | } 83 | 84 | return matches; 85 | } 86 | 87 | // Sets the top left pixel. 88 | 89 | function setTopLeft(x,y) { 90 | if(x < topLeft[0] ) { 91 | topLeft[0] = x; 92 | } 93 | if(y < topLeft[1]) { 94 | topLeft[1] = [y]; 95 | } 96 | } 97 | 98 | // Sets the bottom right pixel. 99 | 100 | function setBottomRight(x,y) { 101 | if(x > bottomRight[0]) { 102 | bottomRight[0] = [x]; 103 | } 104 | if(y > bottomRight[1]) { 105 | bottomRight[1] = [y]; 106 | } 107 | } 108 | 109 | // Initialize on creation. 110 | initialize(); 111 | 112 | // Return public interface. 113 | return { 114 | compare: compare 115 | } 116 | }; 117 | })(MotionDetector); 118 | -------------------------------------------------------------------------------- /js/MotionDetector/WebCamCapture.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Motion-Detector-HTML5 4 | * GAO 5 | * 6 | */ 7 | 8 | ;(function(App) { 9 | 10 | "use strict"; 11 | 12 | 13 | App.WebCamCapture = function(videoElement) { 14 | 15 | var webCamWindow = false; 16 | var width = 640; 17 | var height = 480; 18 | 19 | function initialize(videoElement) { 20 | if(typeof videoElement != 'object') { 21 | webCamWindow = document.getElementById(videoElement); 22 | } else { 23 | webCamWindow = videoElement; 24 | } 25 | 26 | if(hasSupport()) { 27 | if(webCamWindow) { 28 | webCamWindow.style.width = width + 'px'; 29 | webCamWindow.style.height = height + 'px'; 30 | startStream(); 31 | } 32 | 33 | } else { 34 | alert('No support found'); 35 | } 36 | } 37 | 38 | //Starts the streaming from the webcamera to the video element. 39 | function startStream() { 40 | (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia).call( 41 | navigator, 42 | {video: true}, 43 | function(localMediaStream) { 44 | if(webCamWindow) { 45 | var vendorURL = window.URL || window.webkitURL; 46 | 47 | if (navigator.mozGetUserMedia) { 48 | webCamWindow.mozSrcObject = localMediaStream; 49 | webCamWindow.play(); 50 | } else { 51 | webCamWindow.src = vendorURL.createObjectURL(localMediaStream); 52 | } 53 | } 54 | }, 55 | console.error 56 | ); 57 | } 58 | 59 | // Captures a still image from the video. 60 | function captureImage(append) { 61 | var canvas = document.createElement('canvas'); 62 | canvas.width = width; 63 | canvas.height = height; 64 | canvas.getContext('2d').drawImage(webCamWindow, 0, 0, width, height); 65 | 66 | var pngImage = canvas.toDataURL("image/png"); 67 | 68 | if(append) { 69 | append.appendChild(canvas); 70 | } 71 | 72 | return canvas; 73 | } 74 | 75 | function setSize(w, h) { 76 | width = w; 77 | height = h; 78 | } 79 | 80 | function hasSupport(){ 81 | return !!(navigator.getUserMedia || navigator.webkitGetUserMedia || 82 | navigator.mozGetUserMedia || navigator.msGetUserMedia); 83 | } 84 | 85 | // Initialize on creation. 86 | initialize(videoElement); 87 | 88 | // Return public interface. 89 | return { 90 | setSize: setSize, 91 | hasSupport: hasSupport, 92 | captureImage: captureImage 93 | }; 94 | 95 | } 96 | 97 | })(MotionDetector); -------------------------------------------------------------------------------- /js/global.js: -------------------------------------------------------------------------------- 1 | MotionDetector = {}; 2 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | var core = new MotionDetector.Core(); -------------------------------------------------------------------------------- /styles/main.css: -------------------------------------------------------------------------------- 1 | #webCamWindow { 2 | border: 1px solid #000; 3 | width: 640px; 4 | height: 480px; 5 | position: absolute; 6 | top: 0; 7 | opacity: 1; 8 | left: 0; 9 | } 10 | 11 | #canvas { 12 | position: absolute; 13 | opacity: 1; 14 | top: 0; 15 | left: 0; 16 | width: 640px; 17 | height: 480px; 18 | } 19 | 20 | #movement { 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | border: 1px solid #00EAFF; 25 | background: rgba(0,234,255,0.3); 26 | } --------------------------------------------------------------------------------