### Summary
Since the W3C gamepad API exists, I was curious enough to put together a small prototype to visualize the inputs on my steering wheel. It's missing the gear stick but at least it shows the wheel's rotation and the pressure on the pedals.
[Using the Gamepad API (MDN web docs)][1]
### Video demo
<center><iframe width="480" height="270" src="https://www.youtube.com/embed/JkMWs_NOwUQ" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></center>
### The code
`wheel.js`
````
/*******************************************************************************
pc steering wheel animated viewer
firefox/chrome
based on a logitech g920
/******************************************************************************/
let device;
let dataDisplay;
let axisIndexWheel = 0;
let axisIndexThrottle = 1;
let axisIndexBrake = 2;
let axisIndexClutch = 3;
let axisIndexClutchAlt = 5;
let elemWheel;
let elemThrottle;
let elemBrake;
let elemClutch;
let axisWheelFullRotation = 900; // degrees
window.addEventListener('DOMContentLoaded', function(e) {
console.log('loaded');
dataDisplay = document.getElementById('dataDisplay');
elemWheel = document.getElementById('wheel');
elemThrottle = document.querySelector('#throttle > span');
elemBrake = document.querySelector('#brake > span');
elemClutch = document.querySelector('#clutch > span');
gameLoop();
});
function gameLoop() {
wheelDevice = null;
let gps = navigator.getGamepads();
for(let gp of gps) {
if(gp.id.match(/g920.*wheel/i)) {
wheelDevice = gp;
break;
}
}
if(wheelDevice) {
let axisValueWheel = wheelDevice.axes[axisIndexWheel];
let axisValueThrottle = wheelDevice.axes[axisIndexThrottle];
let axisValueBrake = wheelDevice.axes[axisIndexBrake];
let axisValueClutch = wheelDevice.axes[axisIndexClutch] || wheelDevice.axes[axisIndexClutchAlt];
// convert wheel axis to angle
axisValueWheel = Math.round(axisWheelFullRotation / 2 * axisValueWheel * 1000) / 1000;
// normalize pedals axes to range 0-1
axisValueThrottle = (axisValueThrottle * -1 + 1) / 2;
axisValueBrake = (axisValueBrake * -1 + 1) / 2;
axisValueClutch = (axisValueClutch * -1 + 1) / 2;
dataDisplay.innerHTML = '<div>wheel: '+axisValueWheel+'deg</div>';
dataDisplay.innerHTML += '<div>thottle: '+axisValueThrottle+'</div>';
dataDisplay.innerHTML += '<div>brake: '+axisValueBrake +'</div>';
dataDisplay.innerHTML += '<div>clutch: '+axisValueClutch +'</div>';
elemWheel.style.transform = 'rotate('+axisValueWheel+'deg)';
elemThrottle.style.height = (100 - axisValueThrottle * 100)+'%';
elemBrake.style.height = (100 - axisValueBrake * 100)+'%';
elemClutch.style.height = (100 - axisValueClutch * 100)+'%';
}
requestAnimationFrame(gameLoop);
}
````
`wheel.html`
````
<!DOCTYPE html>
<html>
<head>
<title>Wheel</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="wheel.js" type="text/javascript"></script>
<link href="wheel.css" rel="stylesheet" type="text/css" />
</head>
<body class="index">
<div id="viewer">
<img id="wheel"
src="wheel-500.png"
alt="wheel">
<span id="clutch" class="pedal"><span></span></span>
<span id="brake" class="pedal"><span></span></span>
<span id="throttle" class="pedal"><span></span></span>
</div>
<div id="dataDisplay">-</div>
</body>
</html>
````
`wheel.css`
````
body {
background-color:#888;
margin:0;
padding:0;
}
#viewer {
border-bottom:4px red solid;
padding:10px;
}
#wheel {
display:inline-block;
vertical-align:bottom;
border:5px solid transparent;
max-height:200px;
margin:10px;
transform-origin:center center;
}
.pedal {
display:inline-block;
vertical-align:bottom;
border:5px solid black;
width:40px;
height:200px;
margin:10px;
background-color:#AAA;
}
.pedal > span {
display:inline-block;
width:100%;
height:100%;
background-color:#AAA;
vertical-align:top;
}
#wheel {}
#throttle {
background-color:#0A0;
}
#brake {
background-color:#C00;
}
#clutch {
background-color:#FA0;
}
````
`wheel-500.png`
![wheel-500.png][wheel-500.png]
[1]: https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
[wheel-500.png]: http://spenibus.net/f/g/cq/wheel-500.png