2929 background-color : # f8d7da ;
3030 color : # 721c24 ;
3131 }
32- .gamepad-controls-grid {
33- display : grid;
34- grid-template-columns : 120px 1fr 100px 80px ; /* Added column for raw value */
35- gap : 10px ;
36- align-items : center;
32+ # gamepad-state {
33+ display : table;
34+ border-spacing : 1rem ;
35+ border-collapse : separate;
36+ }
37+ .gamepad-controls-row {
38+ display : table-row;
39+ margin-bottom : 5px ;
40+ }
41+ .gamepad-controls-cell {
42+ display : table-cell;
43+ margin : 10px ;
44+ vertical-align : middle;
3745 margin-bottom : 5px ;
3846 }
3947 .gamepad-slider-container {
4048 position : relative;
4149 height : 30px ;
4250 }
4351 .gamepad-slider {
44- width : 100 % ;
52+ width : 100 px ;
4553 height : 10px ;
4654 pointer-events : none;
4755 }
5159 border-radius : 50% ;
5260 background-color : # ccc ;
5361 }
54- . gamepad-buttons -container {
62+ # gamepad-button -container {
5563 margin-top : 20px ;
56- display : grid;
57- grid-template-columns : 1fr 1fr ;
64+ display : flex;
65+ flex-wrap : wrap;
66+ justify-content : center;
5867 gap : 10px ;
5968 }
6069 .gamepad-button {
8089 color : # 555 ; /* Slightly muted to distinguish from processed value */
8190 }
8291 .gamepad-mapping-button {
83- width : 100% ;
8492 }
8593 .gamepad-main-button {
8694 grid-column : span 2 ;
94102</ head >
95103< body >
96104 < template id ="gamepad-axis-template ">
97- < div class ="gamepad-controls-grid ">
98- < div class ="gamepad-controls-name "> </ div >
99- < div class ="gamepad-slider-container "> < input type ="range " class ="gamepad-slider " min ="-1 " max ="1 " value ="0 " step ="0.01 " disabled > </ div >
100- < div class ="gamepad-value-display "> 0.00</ div >
105+ < div class ="gamepad-controls-row ">
106+ < div class ="gamepad-controls-name gamepad-controls-cell "> </ div >
107+ < div class ="gamepad-slider-container gamepad-controls-cell "> < input type ="range " class ="gamepad-slider " min ="-1 " max ="1 " value ="0 " step ="0.01 " disabled > </ div >
108+ < div class ="gamepad-value-display gamepad-controls-cell "> 0.00</ div >
101109 </ div >
102110 </ template >
103111 < template id ="gamepad-button-template ">
104- < div class ="gamepad-controls-grid ">
105- < div class ="gamepad-controls-name "> </ div >
106- < div class ="gamepad-button-indicator "> </ div >
107- < div class ="gamepad-value-display "> Released</ div >
112+ < div class ="gamepad-controls-row ">
113+ < div class ="gamepad-controls-name gamepad-controls-cell "> </ div >
114+ < div class ="gamepad-controls-cell " > < div class =" gamepad- button-indicator "> </ div > </ div >
115+ < div class ="gamepad-value-display gamepad-controls-cell "> Released</ div >
108116 < div > </ div >
109117 </ div >
110118 </ template >
111119 < template id ="gamepad-template ">
112- < h1 > Quadrotor Gamepad Controller</ h1 >
113- < div id ="gamepad-status " class ="disconnected "> No gamepad connected</ div >
114- < div class ="gamepad-separator "> </ div >
115- < h2 > Control Outputs</ h2 >
120+ < div id ="gamepad-status " class ="gamepad-disconnected "> No gamepad connected</ div >
116121 < div id ="gamepad-state ">
117122
118123 </ div >
119- < div class ="gamepad-separator "> </ div >
120- < h2 > Control Mapping</ h2 >
121124 < div id ="gamepad-button-container ">
122125 </ div >
123126 </ template >
127+ < h1 > Quadrotor Gamepad Controller</ h1 >
124128 < script >
125129 /*
126130 mapping button
@@ -183,20 +187,14 @@ <h2>Control Mapping</h2>
183187 }
184188 // live_view
185189 const was_not_mapped = this . control_map [ this . name ] === undefined ;
186- if ( was_not_mapped ) {
187- this . control_map [ this . name ] = {
188- type : 'axis' ,
189- index : this . active ? this . index : this . live_index ,
190- invert : this . invert ,
191- base : this . base ,
192- max_deflection : this . max_deflection
193- } ;
194- }
195- else {
196- this . control_map [ this . name ] . index = this . live_index ;
197- this . control_map [ this . name ] . invert = this . invert ;
198- this . control_map [ this . name ] . max_deflection = this . max_deflection ;
199- }
190+ this . control_map [ this . name ] = {
191+ type : 'axis' ,
192+ index : this . active ? this . index : this . live_index ,
193+ invert : this . invert ,
194+ base : this . base ,
195+ max_deflection : this . max_deflection ,
196+ finished : this . finished
197+ } ;
200198 if ( this . finished ) {
201199 this . completion_handler ( ) ;
202200 }
@@ -231,14 +229,15 @@ <h2>Control Mapping</h2>
231229 this . control_map = { }
232230 this . callbacks = { }
233231 this . gamepad_index = null
234- window . addEventListener ( 'gamepadconnected' , ( ) => {
235- const gamepad_details = event . gamepad || event ;
236- const status_element = document . getElementById ( 'gamepad-status' ) ;
237- this . gamepad_index = gamepad_details . index ;
238- status_element . textContent = 'Gamepad connected: ' + gamepad_details . id ;
239- status_element . className = 'connected' ;
240- document . querySelectorAll ( '.gamepad-mapping-button' ) . forEach ( ( btn ) => { btn . disabled = false ; } ) ;
241- } ) ;
232+ this . gamepad_poller = null
233+ // window.addEventListener('gamepadconnected', () => {
234+ // const gamepad_details = event.gamepad || event;
235+ // const status_element = document.getElementById('gamepad-status');
236+ // this.gamepad_index = gamepad_details.index;
237+ // status_element.textContent = 'Gamepad connected: ' + gamepad_details.id;
238+ // status_element.className = 'gamepad-connected';
239+ // document.querySelectorAll('.gamepad-mapping-button').forEach((btn) => { btn.disabled = false; });
240+ // });
242241 for ( const channel in gamepad_interface ) {
243242 const details = gamepad_interface [ channel ] ;
244243 const button = document . createElement ( 'button' ) ;
@@ -249,7 +248,7 @@ <h2>Control Mapping</h2>
249248 button . textContent = default_text ;
250249 button . disabled = true ;
251250 button . onclick = ( ) => {
252- button . textContent = details . type === "button" ? 'Press Button' : `Move ${ details . positive_direction === 'up' ? 'Up/Forward' : 'Right' } ` ;
251+ button . textContent = details . type === "button" ? 'Press Button' : `Move ${ details . positive_direction } ` ;
253252 document . querySelectorAll ( '.gamepad-mapping-button' ) . forEach ( ( btn ) => { btn . disabled = true ; } ) ;
254253 button . disabled = false ;
255254 const gamepad = this . get_gamepad ( ) ;
@@ -268,6 +267,21 @@ <h2>Control Mapping</h2>
268267 this . poll ( )
269268 }
270269 get_gamepad ( ) {
270+ if ( this . gamepad_index === null ) {
271+ const gamepads = navigator . getGamepads ? navigator . getGamepads ( ) : [ ] ;
272+ let new_gamepad = null
273+ for ( let i = 0 ; i < gamepads . length ; i ++ ) {
274+ const gp = gamepads [ i ] ;
275+ if ( gp ) {
276+ this . gamepad_index = gp . index ;
277+ const status_element = document . getElementById ( 'gamepad-status' ) ;
278+ status_element . textContent = 'Gamepad connected: ' + gp . id ;
279+ status_element . className = 'gamepad-connected' ;
280+ document . querySelectorAll ( '.gamepad-mapping-button' ) . forEach ( ( btn ) => { btn . disabled = false ; } ) ;
281+ break ;
282+ }
283+ }
284+ }
271285 return this . gamepad_index !== null ? navigator . getGamepads ( ) [ this . gamepad_index ] : null ;
272286 }
273287 render_live_view ( ) {
@@ -327,24 +341,38 @@ <h2>Control Mapping</h2>
327341 }
328342 }
329343 }
330- const gamepaddd = new Gamepad ( document . body , {
331- "thrust" : {
332- type : "axis" ,
333- positive_direction : "up"
344+ function init ( ) {
345+ const gamepad = new Gamepad ( document . body , {
346+ "thrust" : {
347+ type : "axis" ,
348+ positive_direction : "Up"
349+ } ,
350+ "roll" : {
351+ type : "axis" ,
352+ positive_direction : "Right"
353+ } ,
354+ "pitch" : {
355+ type : "axis" ,
356+ positive_direction : "Forward"
357+ } ,
358+ "yaw" : {
359+ type : "axis" ,
360+ positive_direction : "Clockwise"
361+ } ,
362+ "reset" : {
363+ type : "button"
364+ } ,
365+ } )
366+ const saved = null ; //localStorage.getItem('quadrotorGamepadMap');
367+ if ( saved ) {
368+ try {
369+ const parsed = JSON . parse ( saved ) ;
370+ Object . assign ( controlMap , parsed ) ;
371+ } catch ( e ) { }
334372 }
335- } )
336- // function init() {
337- // const saved = null; //localStorage.getItem('quadrotorGamepadMap');
338- // if (saved) {
339- // try {
340- // const parsed = JSON.parse(saved);
341- // Object.assign(controlMap, parsed);
342- // } catch (e) {}
343- // }
344-
345- // }
373+ }
346374
347- // window.addEventListener('load', init);
375+ window . addEventListener ( 'load' , init ) ;
348376 </ script >
349377</ body >
350378</ html >
0 commit comments