imageviewerGamepad.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. let gamepads = [];
  2. window.addEventListener('gamepadconnected', (e) => {
  3. const index = e.gamepad.index;
  4. let isWaiting = false;
  5. gamepads[index] = setInterval(async() => {
  6. if (!opts.js_modal_lightbox_gamepad || isWaiting) return;
  7. const gamepad = navigator.getGamepads()[index];
  8. const xValue = gamepad.axes[0];
  9. if (xValue <= -0.3) {
  10. modalPrevImage(e);
  11. isWaiting = true;
  12. } else if (xValue >= 0.3) {
  13. modalNextImage(e);
  14. isWaiting = true;
  15. }
  16. if (isWaiting) {
  17. await sleepUntil(() => {
  18. const xValue = navigator.getGamepads()[index].axes[0];
  19. if (xValue < 0.3 && xValue > -0.3) {
  20. return true;
  21. }
  22. }, opts.js_modal_lightbox_gamepad_repeat);
  23. isWaiting = false;
  24. }
  25. }, 10);
  26. });
  27. window.addEventListener('gamepaddisconnected', (e) => {
  28. clearInterval(gamepads[e.gamepad.index]);
  29. });
  30. /*
  31. Primarily for vr controller type pointer devices.
  32. I use the wheel event because there's currently no way to do it properly with web xr.
  33. */
  34. let isScrolling = false;
  35. window.addEventListener('wheel', (e) => {
  36. if (!opts.js_modal_lightbox_gamepad || isScrolling) return;
  37. isScrolling = true;
  38. if (e.deltaX <= -0.6) {
  39. modalPrevImage(e);
  40. } else if (e.deltaX >= 0.6) {
  41. modalNextImage(e);
  42. }
  43. setTimeout(() => {
  44. isScrolling = false;
  45. }, opts.js_modal_lightbox_gamepad_repeat);
  46. });
  47. function sleepUntil(f, timeout) {
  48. return new Promise((resolve) => {
  49. const timeStart = new Date();
  50. const wait = setInterval(function() {
  51. if (f() || new Date() - timeStart > timeout) {
  52. clearInterval(wait);
  53. resolve();
  54. }
  55. }, 20);
  56. });
  57. }