/* * @name: gest.js * @description: gest.js is a webcam based gesture recognition library that helps developers make webpages more immersive * @version: 0.5.0 * @author: Hadi Michael (http://hadi.io) * @acknowledgements: gest.js is an extension of work started by William Wu (https://github.com/wvvvw) * @license: MIT License */ window.gest=function(e){"use strict";navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia;var t={framerate:25,videoCompressionRate:4,sensitivity:80,skinFilter:false,debug:{state:false,canvas:null,context:null}},n=false,r=false,i,s,o,u,a=function(){function t(){m.removeEventListener("DOMContentLoaded",document,t);m.removeEventListener("load",e,t);if(l()){n=true}if(r&&n){return e.gest.start()}return false}if(a.prototype._singletonInstance){return a.prototype._singletonInstance}a.prototype._singletonInstance=this;if(document.readyState==="complete"){t.call()}else{m.addEventListener("DOMContentLoaded",document,t);m.addEventListener("load",e,t)}return true},f=function(e){var t=m.createCustomEvent("gest",document);t.direction=e.direction||null;t.up=e.up||false;t.down=e.down||false;t.left=e.left||false;t.right=e.right||false;t.error=e.error||null;m.fireEvent(t)},l=function(){s=document.createElement("video");o=document.createElement("canvas");if(!!s.canPlayType&&!!(o.getContext&&o.getContext("2d"))&&!!navigator.getUserMedia){s.width=300;s.height=225;s.setAttribute("style","visibility: hidden;");document.body.appendChild(s);o.setAttribute("style","width: 300px; display: none;");document.body.appendChild(o);u=o.getContext("2d")}else{c(0);return false}return true},c=function(e,n){var r;switch(e){case 0:r={code:e,message:"gest.js can't run in your browser :("};break;case 1:r={code:e,message:"gest.js could not start."};break;case 2:r={code:e,message:"gest.js has already started."};break;case 10:r={code:e,message:"DEEENIED! gest.js needs webcam access.",obj:n};break;case 11:r={code:e,message:"A constraint specified is not supported by the web-browser.",obj:n};break;case 12:r={code:e,message:"No media tracks of the type specified in the constraints are found.",obj:n};break;case 13:r={code:e,message:"Couldn't get access to webcam.",obj:n};break;default:r=null;break}if(t.debug.state){console.error(r.message)}f({error:r})},h=function(e,n){try{u.drawImage(s,0,0,e,n);var r=u.getImageData(0,0,e,n);if(t.skinFilter){d.get(p.apply(r),t.sensitivity,e,n)}else{d.get(r,t.sensitivity,e,n)}}catch(i){if(i.name==="NS_ERROR_NOT_AVAILABLE"){return false}else{throw i}}},p={huemin:0,huemax:.1,satmin:.3,satmax:1,valmin:.4,valmax:1,rgb2hsv:function(e,t,n){e=e/255;t=t/255;n=n/255;var r=Math.max(e,t,n),i=Math.min(e,t,n),s,o,u=r,a=r-i;if(r===0){o=0}else{o=a/r}if(r==i){s=0}else{switch(r){case e:s=(t-n)/a+(tthis.huemin&&l[0].59&&l[0]<1)&&l[1]>this.satmin&&l[1]this.valmin&&l[2]=0){var p=Math.abs(e.data[c]-this.priorFrame.data[c])+Math.abs(e.data[c+1]-this.priorFrame.data[c+1])+Math.abs(e.data[c+2]-this.priorFrame.data[c+2]);if(p>h*Math.abs((n-100)/100)){s.data[c]=255;s.data[c+1]=0;s.data[c+2]=0;s.data[c+3]=255;f+=1;o+=c/4%s.width;a+=Math.floor(c/4/s.height)}else{s.data[c]=e.data[c];s.data[c+1]=e.data[c+1];s.data[c+2]=e.data[c+2];s.data[c+3]=e.data[c+3]}}}if(f>0){v.search({x:o,y:a,d:f});if(t.debug.state&&t.debug.context.putImageData){t.debug.canvas.width=r;t.debug.canvas.height=i;t.debug.context.putImageData(s,0,0)}}this.priorFrame=e}},v={prior:false,filteringFactor:.9,filteredTotal:0,minTotalChange:300,minDirChange:2,longDirChange:7,state:0,search:function(e){var t={x:e.x/e.d,y:e.y/e.d,d:e.d};this.filteredTotal=this.filteringFactor*this.filteredTotal+(1-this.filteringFactor)*t.d;var n=t.d-this.filteredTotal,r=n>this.minTotalChange;switch(this.state){case 0:if(r){this.state=1;v.prior=t}break;case 1:this.state=2;var i=t.x-v.prior.x,s=t.y-v.prior.y,o=Math.abs(s)this.minDirChange&&o){f({direction:"Left",left:true})}if(s>this.minDirChange&&!o){if(Math.abs(s)>this.longDirChange){f({direction:"Long down",down:true})}else{f({direction:"Down",down:true})}}else if(s<-this.minDirChange&&!o){if(Math.abs(s)>this.longDirChange){f({direction:"Long up",up:true})}else{f({direction:"Up",up:true})}}break;case 2:if(!r){this.state=0}break;default:break}}},m={htmlEvents:{onload:1,onunload:1,onblur:1,onchange:1,onfocus:1,onreset:1,onselect:1,onsubmit:1,onabort:1,onkeydown:1,onkeypress:1,onkeyup:1,onclick:1,ondblclick:1,onmousedown:1,onmousemove:1,onmouseout:1,onmouseover:1,onmouseup:1},addEventListener:function(e,t,n){if(t.addEventListener)t.addEventListener(e,n,false);else if(t.attachEvent&&this.htmlEvents["on"+e]){t.attachEvent("on"+e,n)}else{t["on"+e]=n}},removeEventListener:function(e,t,n){if(t.removeEventListener)t.removeEventListener(e,n,false);else if(t.detachEvent&&this.htmlEvents["on"+e]){t.detachEvent("on"+e,n)}else{t["on"+e]=null}},createCustomEvent:function(e,t){try{var n;if(t.createEvent){n=t.createEvent("Event");n.initEvent(e,true,true)}else if(t.createEventObject){n=t.createEventObject();n.eventType=e}n.evntName=e;n.evntElement=t;return n}catch(r){console.error(r);return false}},fireEvent:function(e){try{if(e.evntElement.dispatchEvent){e.evntElement.dispatchEvent(e)}else if(e.evntElement.fireEvent&&this.htmlEvents["on"+e.evntName]){e.evntElement.fireEvent("on"+e.eventType,e)}else if(e.evntElement[e.evntName]){e.evntElement[e.evntName]()}else if(e.evntElement["on"+e.evntName]){e.evntElement["on"+e.evntName]()}}catch(t){console.error(t)}}};a.prototype.start=function(){r=true;if(!n){return false}if(!s||!(s.paused||s.ended||s.seeking||s.readyState=100){t.sensitivity=100}else if(e<=0){t.sensitivity=0}else{t.sensitivity=e}},debug:function(e){t.debug.state=e;if(e){t.debug.canvas=document.createElement("canvas");t.debug.canvas.setAttribute("style","width: 100%; height: 100%; display: block; position: absolute; top: 0; left: 0;");document.body.appendChild(t.debug.canvas);t.debug.context=t.debug.canvas.getContext("2d")}else{t.debug.canvas.setAttribute("style","display: none;");t.debug.canvas.parentNode.removeChild(t.debug.canvas)}return t.debug},skinFilter:function(e){t.skinFilter=e}};return new a}(window)