parameters handling general improvment
This commit is contained in:
parent
1b595fe939
commit
65c06edd1a
@ -100,6 +100,8 @@ body {
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
min-width: 400px;
|
min-width: 400px;
|
||||||
width: 600px;
|
width: 600px;
|
||||||
|
max-height: 100vh;
|
||||||
|
overflow-y: auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
@ -165,7 +167,7 @@ kbd {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
index.html
12
index.html
@ -112,19 +112,23 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th><kbd>+</kbd></th>
|
<th><kbd>+</kbd></th>
|
||||||
<td>Zoom gamepad in</td>
|
<td>Zoom in</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><kbd>-</kbd></th>
|
<th><kbd>-</kbd></th>
|
||||||
<td>Zoom gamepad out</td>
|
<td>Zoom out</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><kbd>0</kbd></th>
|
<th><kbd>0</kbd></th>
|
||||||
<td>Reset gamepad zoom</td>
|
<td>Reset zoom to 100%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><kbd>5</kbd></th>
|
||||||
|
<td>Adjust zoom automatically to window</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><kbd>B</kbd></th>
|
<th><kbd>B</kbd></th>
|
||||||
<td>Change background color</td>
|
<td>Change background style</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><kbd>C</kbd></th>
|
<th><kbd>C</kbd></th>
|
||||||
|
191
js/gamepad.js
191
js/gamepad.js
@ -88,7 +88,7 @@ class Gamepad {
|
|||||||
this.colorIndex = null;
|
this.colorIndex = null;
|
||||||
this.colorName = null;
|
this.colorName = null;
|
||||||
this.triggersMeter = false;
|
this.triggersMeter = false;
|
||||||
this.zoomMode = "manual";
|
this.zoomMode = "auto";
|
||||||
this.zoomLevel = 1;
|
this.zoomLevel = 1;
|
||||||
this.mapping = {
|
this.mapping = {
|
||||||
buttons: [],
|
buttons: [],
|
||||||
@ -121,26 +121,19 @@ class Gamepad {
|
|||||||
// bind a gamepads scan
|
// bind a gamepads scan
|
||||||
window.setInterval(this.scan.bind(this), this.scanDelay);
|
window.setInterval(this.scan.bind(this), this.scanDelay);
|
||||||
|
|
||||||
// read URI for display parameters to initalize
|
|
||||||
this.params = {
|
|
||||||
background: this.getUrlParam("background") || null,
|
|
||||||
color: this.getUrlParam("color") || null,
|
|
||||||
type: this.getUrlParam("type") || null,
|
|
||||||
demo: this.getUrlParam("demo") || null,
|
|
||||||
zoom: this.getUrlParam("zoom") || null,
|
|
||||||
};
|
|
||||||
|
|
||||||
// change the background is specified
|
// change the background is specified
|
||||||
if (this.params.background) {
|
const background = this.getUrlParam("background");
|
||||||
|
if (background) {
|
||||||
let backgroundStyleIndex;
|
let backgroundStyleIndex;
|
||||||
for (let i = 0; i < this.backgroundStyle.length; i++) {
|
for (let i = 0; i < this.backgroundStyle.length; i++) {
|
||||||
if (this.params.background === this.backgroundStyle[i]) {
|
if (background === this.backgroundStyle[i]) {
|
||||||
backgroundStyleIndex = i;
|
backgroundStyleIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backgroundStyleIndex) this.changeBackgroundStyle(backgroundStyleIndex);
|
if (backgroundStyleIndex)
|
||||||
|
this.changeBackgroundStyle(backgroundStyleIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// by default, enqueue a delayed display of the instructions animation
|
// by default, enqueue a delayed display of the instructions animation
|
||||||
@ -251,6 +244,9 @@ class Gamepad {
|
|||||||
case "KeyD":
|
case "KeyD":
|
||||||
this.toggleDebug();
|
this.toggleDebug();
|
||||||
break;
|
break;
|
||||||
|
case "KeyG":
|
||||||
|
this.toggleGamepadType();
|
||||||
|
break;
|
||||||
case "KeyH":
|
case "KeyH":
|
||||||
this.toggleHelp();
|
this.toggleHelp();
|
||||||
break;
|
break;
|
||||||
@ -265,12 +261,13 @@ class Gamepad {
|
|||||||
case "Minus":
|
case "Minus":
|
||||||
this.changeZoom("-");
|
this.changeZoom("-");
|
||||||
break;
|
break;
|
||||||
case "NumpadDecimal":
|
case "Numpad5":
|
||||||
this.adjustZoom(1);
|
case "Digit5":
|
||||||
|
this.changeZoom("auto");
|
||||||
break;
|
break;
|
||||||
case "Numpad0":
|
case "Numpad0":
|
||||||
case "Digit0":
|
case "Digit0":
|
||||||
this.changeZoom("0");
|
this.changeZoom(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,7 +278,7 @@ class Gamepad {
|
|||||||
* @param {WindowEvent} e
|
* @param {WindowEvent} e
|
||||||
*/
|
*/
|
||||||
onResize(e) {
|
onResize(e) {
|
||||||
if (this.zoomMode === "auto") this.adjustZoom(1);
|
if (this.zoomMode === "auto") this.changeZoom("auto");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -342,22 +339,26 @@ class Gamepad {
|
|||||||
* @param {object} gamepad
|
* @param {object} gamepad
|
||||||
*/
|
*/
|
||||||
getType(gamepad) {
|
getType(gamepad) {
|
||||||
|
const type = this.getUrlParam("type");
|
||||||
|
|
||||||
|
// if the debug option is active, use the associated template
|
||||||
|
if (type === "debug") this.debug = true;
|
||||||
if (this.debug) {
|
if (this.debug) {
|
||||||
// if the debug option is active, use the associated template
|
|
||||||
return "debug";
|
return "debug";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.params.type) {
|
// if the gamepad type is set through params, apply it
|
||||||
// if the gamepad type is set through params, apply it
|
if (type) {
|
||||||
return this.params.type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// else, determine the template to use from the gamepad identifier
|
// else, determine the template to use from the gamepad identifier and update settings
|
||||||
for (let gamepadType in this.identifiers) {
|
for (let gamepadType in this.identifiers) {
|
||||||
if (this.identifiers[gamepadType].id.test(gamepad.id)) {
|
if (this.identifiers[gamepadType].id.test(gamepad.id)) {
|
||||||
return gamepadType;
|
return gamepadType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "xbox-one";
|
return "xbox-one";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,16 +422,13 @@ class Gamepad {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine gamepad type
|
// ensure a valid gamepad type is used
|
||||||
this.type = this.getType(gamepad);
|
this.type = this.getType(gamepad);
|
||||||
|
|
||||||
// ensure a valid gamepad type was discovered
|
|
||||||
if (!this.type) return;
|
if (!this.type) return;
|
||||||
|
this.updateSettings({ type: this.type });
|
||||||
|
|
||||||
// initial setup of the gamepad
|
// initial setup of the gamepad
|
||||||
this.identifier = this.identifiers[this.type];
|
this.identifier = this.identifiers[this.type];
|
||||||
this.colorIndex = 0;
|
|
||||||
this.changeGamepadColor(this.identifier.colors[this.colorIndex]);
|
|
||||||
|
|
||||||
// load the HTML template file
|
// load the HTML template file
|
||||||
this.loadTemplate(gamepad);
|
this.loadTemplate(gamepad);
|
||||||
@ -478,6 +476,7 @@ class Gamepad {
|
|||||||
this.colorName = null;
|
this.colorName = null;
|
||||||
this.zoomLevel = 1;
|
this.zoomLevel = 1;
|
||||||
this.$gamepad.empty();
|
this.$gamepad.empty();
|
||||||
|
this.updateSettings({ type: undefined, color: undefined });
|
||||||
}
|
}
|
||||||
|
|
||||||
// enqueue a display of the instructions animation
|
// enqueue a display of the instructions animation
|
||||||
@ -494,19 +493,20 @@ class Gamepad {
|
|||||||
$.ajax(`templates/${this.type}/template.html`).done((template) => {
|
$.ajax(`templates/${this.type}/template.html`).done((template) => {
|
||||||
// inject the template HTML
|
// inject the template HTML
|
||||||
this.$gamepad.html(template);
|
this.$gamepad.html(template);
|
||||||
window.setTimeout(() => {
|
|
||||||
this.adjustZoom(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// read for parameters to apply:
|
// read for parameters to apply:
|
||||||
// - color
|
// - color
|
||||||
if (this.params.color) {
|
this.changeGamepadColor(this.getUrlParam("color"));
|
||||||
this.changeGamepadColor(this.params.color);
|
// - triggers mode
|
||||||
}
|
this.toggleTriggersMeter(this.getUrlParam("triggers") === "meter");
|
||||||
// - zoom
|
// - zoom$
|
||||||
if (this.params.zoom) {
|
window.setTimeout(() =>
|
||||||
this.changeZoom(this.params.zoom);
|
this.changeZoom(
|
||||||
}
|
this.type === "debug"
|
||||||
|
? 0
|
||||||
|
: this.getUrlParam("zoom") || "auto"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// save the buttons mapping of this template
|
// save the buttons mapping of this template
|
||||||
this.mapping.buttons = [];
|
this.mapping.buttons = [];
|
||||||
@ -533,7 +533,7 @@ class Gamepad {
|
|||||||
*/
|
*/
|
||||||
updateStatus() {
|
updateStatus() {
|
||||||
// ensure that a gamepad is currently active
|
// ensure that a gamepad is currently active
|
||||||
if (null === this.index) return;
|
if (this.index === null) return;
|
||||||
|
|
||||||
// enqueue the next refresh right away
|
// enqueue the next refresh right away
|
||||||
window.requestAnimationFrame(this.updateStatus.bind(this));
|
window.requestAnimationFrame(this.updateStatus.bind(this));
|
||||||
@ -666,7 +666,7 @@ class Gamepad {
|
|||||||
*/
|
*/
|
||||||
changeGamepadColor(color) {
|
changeGamepadColor(color) {
|
||||||
// ensure that a gamepad is currently active
|
// ensure that a gamepad is currently active
|
||||||
if (null === this.index) return;
|
if (this.index === null) return;
|
||||||
|
|
||||||
if ("undefined" === typeof color) {
|
if ("undefined" === typeof color) {
|
||||||
// no color was specified, load the next one in list
|
// no color was specified, load the next one in list
|
||||||
@ -674,28 +674,22 @@ class Gamepad {
|
|||||||
if (this.colorIndex > this.identifier.colors.length - 1) {
|
if (this.colorIndex > this.identifier.colors.length - 1) {
|
||||||
this.colorIndex = 0;
|
this.colorIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.colorName = this.identifier.colors[this.colorIndex];
|
|
||||||
} else {
|
} else {
|
||||||
if (!isNaN(parseInt(color))) {
|
if (!isNaN(parseInt(color))) {
|
||||||
// the color is a number, load it by its index
|
// the color is a number, load it by its index
|
||||||
this.colorIndex = color;
|
this.colorIndex = color;
|
||||||
this.colorName = this.identifier.colors[this.colorIndex];
|
|
||||||
} else {
|
} else {
|
||||||
// the color is a string, load it by its name
|
// the color is a string, load it by its name
|
||||||
this.colorName = color;
|
|
||||||
this.colorIndex = 0;
|
this.colorIndex = 0;
|
||||||
for (let gamepadColorIndex in this.identifier.colors) {
|
for (let gamepadColorIndex in this.identifier.colors) {
|
||||||
if (
|
if (color === this.identifier.colors[gamepadColorIndex]) {
|
||||||
this.colorName ===
|
this.colorIndex = gamepadColorIndex;
|
||||||
this.identifier.colors[gamepadColorIndex]
|
|
||||||
) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.colorIndex++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.colorName = this.identifier.colors[this.colorIndex];
|
||||||
|
|
||||||
// update the DOM with the color value
|
// update the DOM with the color value
|
||||||
this.$gamepad.attr("data-color", this.colorName);
|
this.$gamepad.attr("data-color", this.colorName);
|
||||||
@ -714,46 +708,35 @@ class Gamepad {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjusts the zoom level to the available space
|
|
||||||
*/
|
|
||||||
adjustZoom(maxZoom = null) {
|
|
||||||
// let the browser the time to paint
|
|
||||||
const smallerRatio = Math.min(
|
|
||||||
window.innerWidth / (this.$gamepad.width() / this.zoomLevel),
|
|
||||||
window.innerHeight / (this.$gamepad.height() / this.zoomLevel)
|
|
||||||
);
|
|
||||||
this.changeZoom(
|
|
||||||
maxZoom !== null && smallerRatio >= maxZoom
|
|
||||||
? maxZoom
|
|
||||||
: Math.floor(smallerRatio * 100) / 100,
|
|
||||||
"auto"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the active gamepad zoom level
|
* Changes the active gamepad zoom level
|
||||||
*
|
*
|
||||||
* @param {any} level
|
* @param {any} level
|
||||||
*/
|
*/
|
||||||
changeZoom(level, mode = "manual") {
|
changeZoom(level) {
|
||||||
// ensure that a gamepad is currently active
|
// ensure that a gamepad is currently active
|
||||||
if (null === this.index) return;
|
if (this.index === null) return;
|
||||||
|
|
||||||
// ensure we have some data to process
|
// ensure we have some data to process
|
||||||
if ("undefined" === typeof level) return;
|
if (typeof level === "undefined") return;
|
||||||
|
|
||||||
this.zoomMode = mode;
|
this.zoomMode = level === "auto" ? "auto" : "manual";
|
||||||
|
|
||||||
if ("0" === level) {
|
if (level === "auto") {
|
||||||
// "0" means a zoom reset
|
// "auto" means a "contained" in frame zoom
|
||||||
|
this.zoomLevel = Math.min(
|
||||||
|
window.innerWidth / this.$gamepad.width(),
|
||||||
|
window.innerHeight / this.$gamepad.height()
|
||||||
|
);
|
||||||
|
} else if (level === 0) {
|
||||||
|
// 0 means a zoom reset
|
||||||
this.zoomLevel = 1;
|
this.zoomLevel = 1;
|
||||||
} else if ("+" === level && this.zoomLevel < 2) {
|
} else if (level === "+" && this.zoomLevel < 2) {
|
||||||
// "+" means a zoom in if we still can
|
// "+" means a zoom in if we still can
|
||||||
this.zoomLevel += 0.1;
|
this.zoomLevel *= 1.1;
|
||||||
} else if ("-" === level && this.zoomLevel > 0.2) {
|
} else if (level === "-" && this.zoomLevel > 0.2) {
|
||||||
// "-" means a zoom out if we still can
|
// "-" means a zoom out if we still can
|
||||||
this.zoomLevel -= 0.1;
|
this.zoomLevel /= 1.1;
|
||||||
} else if (!isNaN((level = parseFloat(level)))) {
|
} else if (!isNaN((level = parseFloat(level)))) {
|
||||||
// an integer value means a value-based zoom
|
// an integer value means a value-based zoom
|
||||||
this.zoomLevel = level;
|
this.zoomLevel = level;
|
||||||
@ -768,6 +751,11 @@ class Gamepad {
|
|||||||
`translate(-50%, -50%) scale(${this.zoomLevel}, ${this.zoomLevel})`
|
`translate(-50%, -50%) scale(${this.zoomLevel}, ${this.zoomLevel})`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// update current settings
|
||||||
|
this.updateSettings({
|
||||||
|
zoom: this.zoomMode === "auto" ? undefined : this.zoomLevel,
|
||||||
|
});
|
||||||
|
|
||||||
// save statistics
|
// save statistics
|
||||||
if (!!window.ga) {
|
if (!!window.ga) {
|
||||||
ga("send", "event", {
|
ga("send", "event", {
|
||||||
@ -779,12 +767,48 @@ class Gamepad {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the debug template for the active gamepad, if any
|
||||||
|
*/
|
||||||
|
toggleGamepadType() {
|
||||||
|
// ensure that a gamepad is currently active
|
||||||
|
if (this.index === null || this.type === null) return;
|
||||||
|
|
||||||
|
// toggle debug off
|
||||||
|
this.debug = false;
|
||||||
|
|
||||||
|
// compute next type
|
||||||
|
const types = Object.keys(this.identifiers).filter(
|
||||||
|
(i) => i !== "debug"
|
||||||
|
);
|
||||||
|
let typeIndex = types.reduce((typeIndex, type, index) => {
|
||||||
|
return type === this.type ? index : typeIndex;
|
||||||
|
}, 0);
|
||||||
|
this.type = types[++typeIndex >= types.length ? 0 : typeIndex];
|
||||||
|
|
||||||
|
// save statistics
|
||||||
|
if (!!window.ga) {
|
||||||
|
ga("send", "event", {
|
||||||
|
eventCategory: "Gamepad",
|
||||||
|
eventAction: "toggle-type",
|
||||||
|
eventLabel: "Toggle Type",
|
||||||
|
eventValue: this.type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// update current settings
|
||||||
|
this.updateSettings({ type: this.type });
|
||||||
|
|
||||||
|
// remap current gamepad
|
||||||
|
this.map(this.index);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the debug template for the active gamepad, if any
|
* Toggles the debug template for the active gamepad, if any
|
||||||
*/
|
*/
|
||||||
toggleDebug() {
|
toggleDebug() {
|
||||||
// ensure that a gamepad is currently active
|
// ensure that a gamepad is currently active
|
||||||
if (null === this.index) return;
|
if (this.index === null) return;
|
||||||
|
|
||||||
// update debug value
|
// update debug value
|
||||||
this.debug = !this.debug;
|
this.debug = !this.debug;
|
||||||
@ -799,6 +823,9 @@ class Gamepad {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update current settings
|
||||||
|
this.updateSettings({ type: this.debug ? "debug" : undefined });
|
||||||
|
|
||||||
// remap current gamepad
|
// remap current gamepad
|
||||||
this.map(this.index);
|
this.map(this.index);
|
||||||
}
|
}
|
||||||
@ -823,11 +850,17 @@ class Gamepad {
|
|||||||
/**
|
/**
|
||||||
* Toggles the triggers meter display
|
* Toggles the triggers meter display
|
||||||
*/
|
*/
|
||||||
toggleTriggersMeter() {
|
toggleTriggersMeter(useMeter) {
|
||||||
this.triggersMeter = !this.triggersMeter;
|
this.triggersMeter =
|
||||||
|
useMeter !== undefined ? useMeter : !this.triggersMeter;
|
||||||
this.$gamepad[this.triggersMeter ? "addClass" : "removeClass"](
|
this.$gamepad[this.triggersMeter ? "addClass" : "removeClass"](
|
||||||
"triggers-meter"
|
"triggers-meter"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// update current settings
|
||||||
|
this.updateSettings({
|
||||||
|
triggers: this.triggersMeter ? "meter" : undefined,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -841,11 +874,11 @@ class Gamepad {
|
|||||||
.replace("?", "")
|
.replace("?", "")
|
||||||
.split("&")
|
.split("&")
|
||||||
.map((param) => param.split("="))
|
.map((param) => param.split("="))
|
||||||
.filter(([k, v]) => v !== null && v !== undefined)
|
|
||||||
),
|
),
|
||||||
newSettings
|
newSettings
|
||||||
);
|
);
|
||||||
const query = Object.entries(settings)
|
const query = Object.entries(settings)
|
||||||
|
.filter(([, value]) => value !== undefined)
|
||||||
.map(([key, value]) => `${key}=${value}`)
|
.map(([key, value]) => `${key}=${value}`)
|
||||||
.join("&");
|
.join("&");
|
||||||
window.history.replaceState({}, document.title, `/?${query}`);
|
window.history.replaceState({}, document.title, `/?${query}`);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user