[{"data":1,"prerenderedAt":314},["ShallowReactive",2],{"DefaultLayouten":3,"language-blog-slug-navigating-the-web-with-a-gamepad-i18n-slugs":134,"language-blog-slug-en-navigating-the-web-with-a-gamepad":138},{"app":4,"menu":31,"footer":66},{"githubUrl":5,"youtubeUrl":6,"linkedinUrl":7,"phoneNumber":8,"emailAddress":9,"legal":10,"addresses":20},"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002F","https:\u002F\u002Fwww.youtube.com\u002Fchannel\u002FUCzHuhQVYFRixtQN2-swcuGg","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fde-voorhoede","+31 20 2610 954","post@voorhoede.nl",[11,14,17],{"title":12,"value":13},"KvK","56017235",{"title":15,"value":16},"BTW","NL851944620B01",{"title":18,"value":19},"IBAN","NL14TRIO0320142078",[21,26],{"address":22,"city":23,"googleMapsLink":24,"postalCode":25},"Koivistokade 70","Amsterdam","https:\u002F\u002Fwww.google.com\u002Fmaps\u002Fplace\u002FDe+Voorhoede+%7C+Front-end+Development\u002F@52.396847,4.8700823,17z\u002Fdata=!3m1!4b1!4m5!3m4!1s0x47c5e21d502d2d59:0xbf570944a96ebf45!8m2!3d52.347647!4d4.8502154","1013 BB",{"address":27,"city":28,"googleMapsLink":29,"postalCode":30},"Koornmarkt 22","Delft","https:\u002F\u002Fwww.google.nl\u002Fmaps\u002Fplace\u002FKoornmarkt+22,+2611+EG+Delft\u002F@52.0093477,4.3573054,17z\u002F","2611 EG",{"title":32,"callToActions":33,"links":39},"Site Menu",[34],{"id":35,"title":36,"link":37},"163140902","Contact",{"__typename":38},"ContactRecord",[40,46,51,56,61],{"id":41,"title":42,"link":43},"163140904","Impact",{"__typename":44,"slug":45},"PageRecord","impact",{"id":47,"title":48,"link":49},"163140905","Services",{"__typename":50},"ServiceOverviewRecord",{"id":52,"title":53,"link":54},"163140906","Cases",{"__typename":55},"CaseOverviewRecord",{"id":57,"title":58,"link":59},"163140908","About us",{"__typename":44,"slug":60},"about-us",{"id":62,"title":63,"link":64},"d6WdFJq2SOuc3dWtpibbXQ","Work at",{"__typename":44,"slug":65},"work-at",{"links":67,"copyrightTitle":93,"copyrightLabel":94,"copyrightLink":95,"privacyTitle":96,"privacyLabel":97,"privacyLink":98,"certificatesGrid":99},[68,71,74,77,82,85,88],{"id":69,"title":42,"link":70},"144185264",{"__typename":44,"slug":45},{"id":72,"title":48,"link":73},"144185265",{"__typename":50},{"id":75,"title":53,"link":76},"144185266",{"__typename":55},{"id":78,"title":79,"link":80},"144185267","Blog",{"__typename":81},"BlogPostOverviewRecord",{"id":83,"title":58,"link":84},"144185268",{"__typename":44,"slug":60},{"id":86,"title":36,"link":87},"144185269",{"__typename":38},{"id":89,"title":90,"link":91},"144185270","FAQ",{"__typename":44,"slug":92},"faq","Creative Commons licence and disclaimer","CC BY 4.0","https:\u002F\u002Fcreativecommons.org\u002Flicenses\u002Fby\u002F4.0\u002F","De Voorhoede privacy statement (pdf)","Privacy statement","https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1763455455-vh-isms-006-privacy-statement-de-voorhoede-en.pdf",[100,112,123],{"id":101,"image":102,"link":107},"Xq4bBfg_TZ6Fkjax9mkbLQ",{"url":103,"alt":104,"width":105,"height":106},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353463-b-corp-logo-black-rgb.png","B Corp logo",404,680,{"__typename":108,"id":109,"title":110,"url":111},"ExternalLinkRecord","fGW1ak8XQYaYDLkBSyncog","B Corp","https:\u002F\u002Fwww.bcorporation.net\u002Fen-us\u002Ffind-a-b-corp\u002Fcompany\u002Fde-voorhoede\u002F",{"id":113,"image":114,"link":119},"c5mCXRTiSraRIB25fw1p7Q",{"url":115,"alt":116,"width":117,"height":118},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353461-dda-boxlogo-black.png","Dutch Digital Agencies logo",627,480,{"__typename":108,"id":120,"title":121,"url":122},"P6Jh7B0cTv2cKyNEeKVWVQ","Dutch Digital Agencies","https:\u002F\u002Fdutchdigitalagencies.com\u002Fleden\u002Fde-voorhoede\u002F",{"id":124,"image":125,"link":129},"MT5SCyNxSTSr_v5eeATMZw",{"url":126,"alt":127,"width":128,"height":128},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1775730283-dnv.png","DNV logo",518,{"id":130,"title":131,"link":132},"BRtNB5HnT5i-7HkA8IYzBw","DIV",{"__typename":44,"slug":133},"impact\u002Fdigitale-producten-privacy-by-design",[135],{"locale":136,"value":137},"en","navigating-the-web-with-a-gamepad",{"page":139},{"slug":137,"i18nSlugs":140,"social":142,"title":143,"subtitle":79,"isArchived":147,"headerIllustration":148,"date":149,"authors":150,"introTitle":144,"items":159,"pivots":301,"relatedBlogPosts":312,"tags":313,"onMountedScript":153,"onUnmountedScript":153},[141],{"locale":136,"value":137},{"title":143,"description":144,"image":145},"Navigating the web with a gamepad","We typically use a mouse, a keyboard or touch to navigate the web. What if you could use your gamepad?",{"url":146},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1578650374-gamepad-api-button-layout.svg",false,null,"2020-01-09T01:00:00.000+01:00",[151],{"name":152,"lastName":153,"slug":154,"image":155},"Mark","","mark",{"url":156,"alt":148,"width":157,"height":158},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1683534636-placeholder.jpg",1235,1646,[160,171,175,179,183,188,191,201,205,211,215,218,221,224,228,231,234,238,241,244,251,255,258,261,265,270,273,276,283,286,293,297],{"__typename":161,"id":162,"mute":147,"loop":147,"autoplay":147,"caption":153,"video":163,"gif":148},"ResponsiveVideoRecord","2092672",{"url":164,"title":165,"height":166,"width":167,"provider":168,"providerUid":169,"thumbnailUrl":170},"https:\u002F\u002Fvimeo.com\u002F380002616","Navigate the web with a gamepad - Click function",240,426,"vimeo","380002616","https:\u002F\u002Fi.vimeocdn.com\u002Fvideo\u002F840226766-4f357d41de4198212c647ff9aa5d965663865c54f72baf0380c95beee0413515-d_295x166",{"__typename":172,"id":173,"title":153,"body":174},"TextSectionRecord","2092673","\u003Cp data-line=\"9\" class=\"code-line\">You could be using a trackpad because you are sitting on your couch with your laptop or maybe you use a drawing tablet. Maybe you are an early adopter and you are using Leap Motion to control your computer with hand gestures. There are many ways to browse the web and control your computer. Your gamepad may be one of them.\u003C\u002Fp>\u003Cp data-line=\"11\" class=\"code-line\">In this article I&rsquo;ll share how to:\u003C\u002Fp>\u003Cul>\u003Cli data-line=\"13\" class=\"code-line\">connect your gamepad in a browser\u003C\u002Fli>\u003Cli data-line=\"14\" class=\"code-line\">listen to gamepad button presses\u003C\u002Fli>\u003Cli data-line=\"15\" class=\"code-line\">control focus on a web page using your gamepad\u003C\u002Fli>\u003Cli data-line=\"16\" class=\"code-line\">add feedback by creating vibrations on a gamepad\u003C\u002Fli>\u003C\u002Ful>\u003Cp data-line=\"18\" class=\"code-line\">So plug in your gamepad (or use Bluetooth) and let&rsquo;s get started.\u003C\u002Fp>",{"__typename":172,"id":176,"title":177,"body":178},"2092674"," The Gamepad API","\u003Cp data-line=\"22\" class=\"code-line\">The\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FGamepad_API\" data-href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FGamepad_API\" title=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FGamepad_API\">Gamepad API\u003C\u002Fa>\u003Cspan>&nbsp;\u003C\u002Fspan>is introduced as part of HTML5. The API allows you to use a gamepad inside the browser. In combination with the\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ccode>&lt;canvas&gt;\u003C\u002Fcode>\u003Cspan>&nbsp;\u003C\u002Fspan>element, developers can create HTML5 games with gamepad support for better user experiences while playing games in the browser. Creating games is not the only use case for the Gamepad API. A gamepad could also be used as an input device and in this article I&rsquo;ll explain how.\u003C\u002Fp>\u003Cp data-line=\"24\" class=\"code-line\">Side note: the\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fdev.caniuse.com\u002Fgamepad\" data-href=\"https:\u002F\u002Fdev.caniuse.com\u002Fgamepad\" title=\"https:\u002F\u002Fdev.caniuse.com\u002Fgamepad\">Gamepad API is well supported\u003C\u002Fa>, but it&rsquo;s still a working draft, things may change, be removed or be added in the future.\u003C\u002Fp>",{"__typename":172,"id":180,"title":181,"body":182},"2092675"," Connect your gamepad","\u003Cp>\u003Cspan>When you connect your gamepad to your computer using USB or Bluetooth, we can start listening to the gamepad API connect and disconnect events:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":184,"id":185,"language":186,"body":187},"CodeBlockRecord","2092717","javascript","window.addEventListener('gamepadconnected', function(event) {\n  \u002F\u002F Do something on connect\n  console.log(event) \u002F\u002F see output below\n});\n\nwindow.addEventListener('gamepaddisconnected', function(event) {\n  \u002F\u002F Do something on disconnect\n});",{"__typename":172,"id":189,"title":153,"body":190},"2092718","\u003Cp data-line=\"41\" class=\"code-line\">The gamepad only can be interacted with after a button is pressed. This is a browser security\u002Fprivacy feature. Therefore a &lsquo;press a button to start&rsquo; feature should be implemented in your project.\u003C\u002Fp>\u003Cp data-line=\"43\" class=\"code-line\">The &lsquo;\u003Cem>Gamepad Event\u003C\u002Fem>&rsquo; object looks like this when it is logged to the console:\u003C\u002Fp>",{"__typename":192,"id":193,"image":194,"caption":199,"fullWidth":147,"captionPosition":200},"ImageRecord","2092852",{"url":195,"alt":196,"width":197,"height":198},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1578581631-gamepadobj.png","Code showing Gamepad object",1340,1246,"Gamepad object","bottom",{"__typename":172,"id":202,"title":203,"body":204},"2092720"," Gamepad layout: axes and buttons","\u003Cp>\u003Cspan>The log shows a whole list of axes (0 - 3) and buttons (0 - 16). How do we know which axis or button belongs to which part of our actual gamepad? Gamepad layouts vary between brands. We&rsquo;re connecting an Xbox One gamepad which has the following layout:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":192,"id":206,"image":207,"caption":208,"fullWidth":147,"captionPosition":200},"2092721",{"url":146,"alt":208,"width":209,"height":210},"Xbox One gamepad button layout",1280,760,{"__typename":172,"id":212,"title":213,"body":214},"2092722"," Listening to button presses","\u003Cp>\u003Cspan>When developing an interface with buttons the&nbsp;\u003C\u002Fspan>\u003Ccode>.addEventListener()\u003C\u002Fcode>\u003Cspan>&nbsp;can be used to listen to the state of buttons and\u002For links. This isn&rsquo;t the case when working with a gamepad. The button state has to be checked manually since the gamepad buttons do not emit events. We can do this by checking the&nbsp;\u003C\u002Fspan>\u003Ccode>pressed\u003C\u002Fcode>\u003Cspan>&nbsp;state (Boolean):\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":184,"id":216,"language":186,"body":217},"2092723","const xBoxButtonB = gamepad.buttons[1]\nif (xBoxButtonB.pressed) {\n  doSomethingOnButtonPress();\n}",{"__typename":172,"id":219,"title":153,"body":220},"2092724","\u003Cp>\u003Cspan>Since we want to do this continuously we need to check this inside a continuous loop, for instance using&nbsp;\u003C\u002Fspan>\u003Ccode>requestAnimationFrame\u003C\u002Fcode>\u003Cspan>:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":184,"id":222,"language":186,"body":223},"2092725","const rAF = window.mozRequestAnimationFrame || window.requestAnimationFrame; \n\nwindow.addEventListener('gamepadconnected', function() {\n  updateLoop();\n}); \n\nfunction updateLoop() {\n  \u002F\u002F check button states\n  rAF(updateLoop);\n}",{"__typename":172,"id":225,"title":226,"body":227},"2092726"," Navigating between focusable elements","\u003Cp data-line=\"78\" class=\"code-line\">In order to use the gamepad as a way to navigate through a web page, the functionality of the keyboard keys need to be simulated. But first all of the focusable items on a page need to be collected.\u003C\u002Fp>\u003Cp data-line=\"80\" class=\"code-line\">With the following selector all elements which should be focusable on a web page by default can be selected:\u003C\u002Fp>",{"__typename":184,"id":229,"language":186,"body":230},"2092727","const focusableElements = document.querySelectorAll(\n  'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n);",{"__typename":172,"id":232,"title":153,"body":233},"2092728","\u003Cp data-line=\"87\" class=\"code-line code-active-line\">There are more elements you can include in the selector, but this is a good baseline to start with.\u003C\u002Fp>",{"__typename":172,"id":235,"title":236,"body":237},"2092729"," Moving the focus programmatically","\u003Cp data-line=\"91\" class=\"code-line\">Now in order to place the focus on an element we loop through the NodeList and place focus on the current item by using the\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ccode>element.focus()\u003C\u002Fcode>\u003Cspan>&nbsp;\u003C\u002Fspan>method.\u003C\u002Fp>\u003Cp data-line=\"93\" class=\"code-line\">Once the focusable elements are stored, they can be looped through and the focus can be placed on the current element.\u003C\u002Fp>\u003Cp data-line=\"95\" class=\"code-line\">The following example show how to move the focus from element to element.\u003C\u002Fp>",{"__typename":184,"id":239,"language":186,"body":240},"2092769","let current;\n\nfunction updateLoop() {\n  const gamepad = navigator.getGamepads()[0]\n  const gamepadBumperL = gamepad.buttons[4]\n  const gamepadBumperR = gamepad.buttons[5]\n  \n  if (gamepadBumperL.pressed) { prevItem(current) }\n  if (gamepadBumperR.pressed) { nextItem(current) }\n  \n  setTimeout(() => rAF(updateLoop), 100)\n}\n\nfunction prevItem(index) {\n  current = (index - 1) % focusableElements.length\n  focusableElements[current].focus()\n}\n\nfunction nextItem(index) {\n  current = (index + 1) % focusableElements.length\n  focusableElements[current].focus()\n}",{"__typename":172,"id":242,"title":153,"body":243},"2092770","\u003Cp>\u003Cspan>Note: there&rsquo;s a&nbsp;\u003C\u002Fspan>\u003Ccode>setTimeout\u003C\u002Fcode>\u003Cspan>&nbsp;function set to throttle the&nbsp;\u003C\u002Fspan>\u003Ccode>requestAnimationFrame\u003C\u002Fcode>\u003Cspan> with 100 milliseconds. Without this, a single button press can be registered multiple times because it is physically impossible to press and release a button within a millisecond.\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":161,"id":245,"mute":147,"loop":147,"autoplay":147,"caption":153,"video":246,"gif":148},"2092771",{"url":247,"title":248,"height":166,"width":167,"provider":168,"providerUid":249,"thumbnailUrl":250},"https:\u002F\u002Fvimeo.com\u002F379999743","Navigating the web with a gamepad - Moving focus","379999743","https:\u002F\u002Fi.vimeocdn.com\u002Fvideo\u002F845291303-45e438e6bf493ee2148ddc419fbedf6743ebb31abf6e0811e83c5819f57ac700-d_295x166",{"__typename":172,"id":252,"title":253,"body":254},"2092772","Clickable elements","\u003Cp data-line=\"131\" class=\"code-line\">If the element is clickable, because it is a link or a button, then a function is needed to do something with those elements. This can be done with the\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ccode>click()\u003C\u002Fcode>\u003Cspan>&nbsp;\u003C\u002Fspan>method.\u003C\u002Fp>",{"__typename":184,"id":256,"language":186,"body":257},"2092773","clickItem(index) {\n  focusableElements[index].click();\n}",{"__typename":172,"id":259,"title":153,"body":260},"2092774","\u003Cp>\u003Cspan>Keyboard, mouse etc. events have a read only&nbsp;\u003C\u002Fspan>\u003Ccode>isTrusted\u003C\u002Fcode>\u003Cspan>&nbsp;property. This is done so that those events cannot be fired programmatically. Because of this the literal function of a key needs to be translated in Javascript.\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":172,"id":262,"title":263,"body":264},"2092775"," Adding feedback with vibrations","\u003Cp>\u003Cspan>Modern gamepads can vibrate. These vibrations can be used to enhance the overall experience of video games. When navigating the web we can also use these vibrations to provide feedback. Modern gamepads are equipped with several Electric Rotation Motors (ERM's) to create vibrations:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":192,"id":266,"image":267,"caption":269,"fullWidth":147,"captionPosition":200},"2092776",{"url":268,"alt":269,"width":209,"height":210},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1578650390-gamepad-api-erm-layout.svg","Xbox One gamepad electric rotation motor layout",{"__typename":172,"id":271,"title":153,"body":272},"2092777","\u003Cp data-line=\"147\" class=\"code-line\">We can control the ERMs in the browser using the Gamepad\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ccode>vibrationActuator\u003C\u002Fcode>\u003Cspan>&nbsp;\u003C\u002Fspan>API. This contains the type of &lsquo;rumble&rsquo; the gamepad has. Modern Xbox and Playstation controllers have a type that is called\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ccode>dual-rumble\u003C\u002Fcode>. If the browser can't find any motors to work with, then the object will contain\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ccode>null\u003C\u002Fcode>.\u003C\u002Fp>\u003Cp data-line=\"149\" class=\"code-line\">To create a vibration we use the\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ccode>playEffect()\u003C\u002Fcode>\u003Cspan>&nbsp;\u003C\u002Fspan>method:\u003C\u002Fp>",{"__typename":184,"id":274,"language":186,"body":275},"2092778","gamepad.vibrationActuator.playEffect('dual-rumble', {\n  startDelay: 0, \u002F\u002F Add a delay in milliseconds\n  duration: 1000, \u002F\u002F Total duration in milliseconds\n  weakMagnitude: 0.5, \u002F\u002F intensity (0-1) of the small ERM \n  strongMagnitude: 1 \u002F\u002F intesity (0-1) of the bigger ERM\n});",{"__typename":161,"id":277,"mute":147,"loop":147,"autoplay":147,"caption":153,"video":278,"gif":148},"2092792",{"url":279,"title":280,"height":166,"width":167,"provider":168,"providerUid":281,"thumbnailUrl":282},"https:\u002F\u002Fvimeo.com\u002F383736009","Navigate the web with a gamepad - Vibration","383736009","https:\u002F\u002Fi.vimeocdn.com\u002Fvideo\u002F845260308-a73e801d8a95d389938e530e05c67c295a3ff942f9176f3117ac89597b58861f-d_295x166",{"__typename":172,"id":284,"title":153,"body":285},"2092793","\u003Cp>\u003Cspan>When using the vibration motors, be aware that the bigger motor takes longer to get up to speed. When you need fast and instant vibrations then you should use the smaller motor instead.\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":192,"id":287,"image":288,"caption":290,"fullWidth":147,"captionPosition":200},"2092794",{"url":289,"alt":290,"width":291,"height":292},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1578650403-gamepad-api-vibration-graph.svg","Vibration pattern graph",1000,540,{"__typename":172,"id":294,"title":295,"body":296},"2092795","Recap","\u003Cp data-line=\"171\" class=\"code-line\">This example shows how to create basic functions to make a web page navigable with a gamepad. With these steps you&rsquo;ll achieve this:\u003C\u002Fp>\u003Col>\u003Cli data-line=\"174\" class=\"code-line\">Find focusable elements and store them\u003C\u002Fli>\u003Cli data-line=\"175\" class=\"code-line\">Use the buttons on a gamepad\u003C\u002Fli>\u003Cli data-line=\"176\" class=\"code-line\">Create functions to move the focus around\u003C\u002Fli>\u003Cli data-line=\"177\" class=\"code-line\">Create function to open or activate links and buttons\u003C\u002Fli>\u003Cli data-line=\"178\" class=\"code-line\">Add extra feedback using vibrations\u003C\u002Fli>\u003C\u002Fol>\u003Cp data-line=\"180\" class=\"code-line\">You can find the\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002Fdemo-navigate-with-gamepad\" data-href=\"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002Fdemo-navigate-with-gamepad\" title=\"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002Fdemo-navigate-with-gamepad\">code on GitHub\u003C\u002Fa>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002Fdemo-navigate-with-gamepad\" data-href=\"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002Fdemo-navigate-with-gamepad\" title=\"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002Fdemo-navigate-with-gamepad\">\u003C\u002Fa>\u003Cspan>&nbsp;\u003C\u002Fspan>and\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fdemo-navigate-with-gamepad.netlify.com\u002F\" data-href=\"https:\u002F\u002Fdemo-navigate-with-gamepad.netlify.com\u002F\" title=\"https:\u002F\u002Fdemo-navigate-with-gamepad.netlify.com\u002F\">view a live demo\u003C\u002Fa>\u003Cspan>&nbsp;\u003C\u002Fspan>here. Do you have more ideas for using a gamepad on the web? We&rsquo;d love to hear about it! You can find us\u003Cspan>&nbsp;\u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Ftwitter.com\u002Fdevoorhoede\" data-href=\"https:\u002F\u002Ftwitter.com\u002Fdevoorhoede\" title=\"https:\u002F\u002Ftwitter.com\u002Fdevoorhoede\">@devoorhoede\u003C\u002Fa>.\u003C\u002Fp>",{"__typename":172,"id":298,"title":299,"body":300},"2092796","Extra links","\u003Cul class=\"listtype-bullet listindent1 list-bullet1\">\u003Cli data-line=\"183\" class=\"code-line\">\u003Ca href=\"https:\u002F\u002Fhtml5gamepad.com\u002F\" data-href=\"https:\u002F\u002Fhtml5gamepad.com\" title=\"https:\u002F\u002Fhtml5gamepad.com\">html5gamepad.com\u003C\u002Fa>: tool to check which buttons and other options your gamepad has.\u003C\u002Fli>\u003Cli data-line=\"184\" class=\"code-line\">\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FGamepad_API\" data-href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FGamepad_API\" title=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FGamepad_API\">Gamepad API on MDN\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>",[302],{"title":303,"body":304,"links":305,"mailchimpValue":153,"mailchimpName":153,"mailchimpId":153,"formType":153,"contactPerson":148},"Also in love with the web?","\u003Cp>For us, that’s about technology and user experience. Fast, available for all, enjoyable to use. And fun to build. This is how our team bands together, adhering to the same values, to make sure we achieve a solid result for clients both large and small. Does that fit you?\u003C\u002Fp>\n",[306],{"__typename":307,"id":308,"title":309,"link":310},"InternalLinkRecord","163140992","Join our team",{"__typename":44,"slug":311},"jobs",[],[],1776256150334]