-
Notifications
You must be signed in to change notification settings - Fork 3
/
p5.joystick.min.js
1 lines (1 loc) · 8.11 KB
/
p5.joystick.min.js
1
p5.prototype.createJoystick=function(debug){var _this={name:"p5Joystick"};const DEBUG_CONTROL=debug,DEFAULT_WIDTH=440,DEFAULT_HEIGHT=200;var calibrating=!1,haveEvents="ongamepadconnected"in window,controllers={},buttonPressedHandlers=[],buttonReleasedHandlers=[],axesPressedHandlers=[],axesReleasedHandlers=[];_this.onButtonPressed=function(e){buttonPressedHandlers.push(e)},_this.onButtonReleased=function(e){buttonReleasedHandlers.push(e)},_this.onAxesPressed=function(e){axesPressedHandlers.push(e)},_this.onAxesReleased=function(e){axesReleasedHandlers.push(e)};var coordinates={},prevX,prevY,prevW,prevH;function calculateCoordinates(e,t,a,n){if(e==prevX&&t==prevY&&a==prevW&&n==prevH)return;prevX=e,prevY=t,prevW=a,prevH=n;const s=60*n/DEFAULT_HEIGHT,o=40*n/DEFAULT_HEIGHT;coordinates={sholderLeft:{x:e-a-s/2,y:t-n/2-s/4,w:s,h:s/3},sholderRight:{x:e+a-s/2,y:t-n/2-s/4,w:s,h:s/3},axesUp:{x:e-a-o/2,y:t-o/2*.6-o,w:o,h:o},axesDown:{x:e-a-o/2,y:t+o/2*.6,w:o,h:o},axesLeft:{x:e-a-o/2*.6-o,y:t-o/2,w:o,h:o},axesRight:{x:e-a+o/2*.6,y:t-o/2,w:o,h:o},buttonBlue:{x:e+a-.9*o-o/2,y:t-o/2,w:o,h:o},buttonYellow:{x:e+a-o/2,y:t-.9*o-o/2,w:o,h:o},buttonRed:{x:e+a+.9*o-o/2,y:t-o/2,w:o,h:o},buttonGreen:{x:e+a-o/2,y:t+.9*o-o/2,w:o,h:o},start:{x:e-1.1*o,y:t,w:o,h:o/2},select:{x:e+.1*o,y:t,w:o,h:o/2}},loadCalibration()}var calibration={};function connecthandler(e){addgamepad(e.gamepad)}function addgamepad(e){controllers[e.index]={gamepad:e,buttonPrevState:[],axesPrevState:[]};for(var t=0;t<e.buttons.length;t++)controllers[e.index].buttonPrevState[t]={value:e.buttons[t].value,pressed:e.buttons[t].pressed};for(t=0;t<e.axes.length;t++)controllers[e.index].axesPrevState[t]=round(e.axes[t]);if(DEBUG_CONTROL){var a=document.createElement("div");a.setAttribute("id","controller"+e.index),a.style.position="absolute",a.style.top="0px",a.style.left=190*e.index+"px",a.style.width="170px";var n=document.createElement("h3");n.appendChild(document.createTextNode("gamepad: "+e.id)),a.appendChild(n);var s=document.createElement("div");s.className="buttons",s.style.margin="10px 0px";for(t=0;t<e.buttons.length;t++){var o=document.createElement("span");o.className="button",o.style.float="left",o.style.width="20px",o.style.textAlign="center",o.style.border="1px solid blue",o.style.margin="1px",o.innerHTML=t,s.appendChild(o)}a.appendChild(s);var r=document.createElement("div");r.className="axes";for(t=0;t<e.axes.length;t++){var l=document.createElement("progress");l.className="axis",l.setAttribute("max","2"),l.setAttribute("value","1"),l.innerHTML=t,r.appendChild(l)}a.appendChild(r),document.body.appendChild(a)}requestAnimationFrame(updateStatus)}function disconnecthandler(e){removegamepad(e.gamepad)}function removegamepad(e){if(DEBUG_CONTROL){var t=document.getElementById("controller"+e.index);document.body.removeChild(t)}delete controllers[e.index]}function updateStatus(){haveEvents||scangamepads();var e,t=0;for(e in controllers){var a=controllers[e],n=a.gamepad,s=a.buttonPrevState;for(t=0;t<n.buttons.length;t++){var o=n.buttons[t];if(s[t].value!=o.value)if(s[t].value=o.value,""!=(i={gamepadName:n.id,gamepadIndex:n.index,value:o.value,index:t,pressed:o.pressed,type:"button",name:getCalibrationName(n.id,"b"+t)}).name&&coordinates[i.name]&&(coordinates[i.name].pressed=i.pressed),o.pressed){if(calibrating)for(const[e,a]of Object.entries(coordinates))a.selected&&i.pressed&&saveCalibration(e,n.id,"b"+t);buttonPressedHandlers.forEach(e=>e(i))}else buttonReleasedHandlers.forEach(e=>e(i))}var r=a.axesPrevState;for(t=0;t<n.axes.length;t++){var l=round(n.axes[t]);if(r[t]!=l){var i;if((i={gamepadName:n.id,gamepadIndex:n.index,value:l,index:t,pressed:abs(l)>.1,type:"axes"}).pressed?i.name=getCalibrationName(n.id,"a"+t+":"+l):i.name=getCalibrationName(n.id,"a"+t+":"+r[t]),""!=i.name&&coordinates[i.name]&&(coordinates[i.name].pressed=i.pressed),i.pressed){if(calibrating)for(const[e,a]of Object.entries(coordinates))a.selected&&saveCalibration(e,n.id,"a"+t+":"+l);axesPressedHandlers.forEach(e=>e(i))}else axesReleasedHandlers.forEach(e=>e(i));r[t]=l}}if(DEBUG_CONTROL){var d=document.getElementById("controller"+e),c=d.getElementsByClassName("button");for(t=0;t<n.buttons.length;t++){o=n.buttons[t];var u=Math.round(100*o.value)+"%";c[t].style.backgroundSize=u+" "+u,o.pressed?(c[t].style.backgroundColor="blue",c[t].style.color="white"):(c[t].style.backgroundColor="",c[t].style.color="")}var x=d.getElementsByClassName("axis");for(t=0;t<n.axes.length;t++){var b=x[t];b.innerHTML=t+": "+n.axes[t].toFixed(4),b.setAttribute("value",n.axes[t]+1)}}}requestAnimationFrame(updateStatus)}function scangamepads(){for(var e=navigator.getGamepads?navigator.getGamepads():navigator.webkitGetGamepads?navigator.webkitGetGamepads():[],t=0;t<e.length;t++)e[t]&&(e[t].index in controllers?controllers[e[t].index].gamepad=e[t]:addgamepad(e[t]))}return loadCalibration=function(){var e=localStorage.getItem("p5Joystick");if(e){calibration=JSON.parse(e);for(const[e,t]of Object.entries(calibration))for(const[e,a]of Object.entries(t))coordinates[a]&&(coordinates[a].button=e)}},loadCalibration(),saveCalibration=function(e,t,a){coordinates[e].button=a,t in calibration||(calibration[t]={}),calibration[t][a]=e,localStorage.setItem("p5Joystick",JSON.stringify(calibration))},getCalibrationName=function(e,t){return e in calibration&&t in calibration[e]?calibration[e][t]:""},_this.calibrated=function(){return Object.keys(calibration).length>0},_this.calibrate=function(e){calibrating=e},_this.getButtonPressedByName=function(e){return!(!coordinates[e]||!coordinates[e].pressed)&&coordinates[e].pressed},_this.getButtonPressedByIndex=function(e,t){return!(!controllers[e]||!controllers[e].gamepad.buttons[t])&&controllers[e].gamepad.buttons[t].pressed},_this.getAxesValueByIndex=function(e,t){return controllers[e]&&controllers[e].gamepad.axes[t]?controllers[e].gamepad.axes[t]:0},_this.draw=function(x,y,w,h){with(x&&y||console.error("p5joystick draw() function: parameters x and y are required"),w=w||DEFAULT_WIDTH,h=h||DEFAULT_HEIGHT,w-=h,w/=2,calculateCoordinates(x,y,w,h),coordinates)noStroke(),fill(sholderLeft.pressed?200:127),rect(sholderLeft.x,sholderLeft.y,sholderLeft.w,sholderLeft.h,sholderLeft.w/4,sholderLeft.w/4,0,0),fill(sholderRight.pressed?200:127),rect(sholderRight.x,sholderRight.y,sholderRight.w,sholderRight.h,sholderRight.w/4,sholderRight.w/4,0,0),fill(255),circle(x-w,y,h),circle(x+w,y,h),rect(x-w,y-h/2,2*w,.75*h),fill(axesUp.pressed?200:127),rect(axesUp.x,axesUp.y,axesUp.w,axesUp.h,axesUp.w/4,axesUp.w/4,axesUp.w/2,axesUp.w/2),fill(axesDown.pressed?200:127),rect(axesDown.x,axesDown.y,axesDown.w,axesDown.h,axesDown.w/2,axesDown.w/2,axesDown.w/4,axesDown.w/4),fill(axesLeft.pressed?200:127),rect(axesLeft.x,axesLeft.y,axesLeft.w,axesLeft.h,axesLeft.w/4,axesLeft.w/2,axesLeft.w/2,axesLeft.w/4),fill(axesRight.pressed?200:127),rect(axesRight.x,axesRight.y,axesRight.w,axesRight.h,axesRight.w/2,axesRight.w/4,axesRight.w/4,axesRight.w/2),fill(buttonYellow.pressed?color(255,255,127):color(255,255,0)),circle(buttonYellow.x+buttonYellow.w/2,buttonYellow.y+buttonYellow.h/2,buttonYellow.w),fill(buttonBlue.pressed?color(127,127,255):color(0,0,255)),circle(buttonBlue.x+buttonBlue.w/2,buttonBlue.y+buttonBlue.h/2,buttonBlue.w),fill(buttonRed.pressed?color(255,127,127):color(255,0,0)),circle(buttonRed.x+buttonRed.w/2,buttonRed.y+buttonRed.h/2,buttonRed.w),fill(buttonGreen.pressed?color(127,255,127):color(0,255,0)),circle(buttonGreen.x+buttonGreen.w/2,buttonGreen.y+buttonGreen.h/2,buttonGreen.w),fill(start.pressed?200:127),rect(start.x,start.y,start.w,start.h,start.w/4,start.w/4,start.w/4,start.w/4),fill(select.pressed?200:127),rect(select.x,select.y,select.w,select.h,select.w/4,select.w/4,select.w/4,select.w/4);if(calibrating)for(const[name,button]of Object.entries(coordinates))mouseIsPressed&&(coordinates[name].selected=mouseX>button.x&&mouseX<button.x+button.w&&mouseY>button.y&&mouseY<button.y+button.h),stroke(0),button.selected?fill(0,255,255,100):fill(0,100),rect(button.x,button.y,button.w,button.h),button.button&&(fill(0),noStroke(),text(button.button,button.x+button.w/2-10,button.y+button.h/2+2))},window.addEventListener("gamepadconnected",connecthandler),window.addEventListener("gamepaddisconnected",disconnecthandler),haveEvents||setInterval(scangamepads,500),_this};