thelounge/client/js/libs/slideout.js

104 lines
2.3 KiB
JavaScript
Raw Normal View History

"use strict";
2016-06-12 04:16:17 +02:00
/**
* Simple slideout menu implementation.
*/
module.exports = function slideoutMenu(viewport, menu) {
2018-01-11 12:33:36 +01:00
let touchStartPos = null;
let touchCurPos = null;
let touchStartTime = 0;
let menuWidth = 0;
let menuIsOpen = false;
let menuIsMoving = false;
2016-06-12 04:16:17 +02:00
function toggleMenu(state) {
menuIsOpen = state;
viewport.classList.toggle("menu-open", state);
}
function disableSlideout() {
viewport.removeEventListener("ontouchstart", onTouchStart);
}
function onTouchStart(e) {
if (e.touches.length !== 1) {
onTouchEnd();
2017-04-30 12:42:59 +02:00
return;
2016-06-12 04:16:17 +02:00
}
2018-01-11 12:33:36 +01:00
const touch = e.touches.item(0);
2016-06-12 04:16:17 +02:00
viewport.classList.toggle("menu-dragging", true);
menuWidth = parseFloat(window.getComputedStyle(menu).width);
2016-06-12 04:16:17 +02:00
if ((!menuIsOpen && touch.screenX < 50) || (menuIsOpen && touch.screenX > menuWidth)) {
touchStartPos = touch;
touchCurPos = touch;
touchStartTime = Date.now();
viewport.addEventListener("touchmove", onTouchMove);
2017-04-30 12:42:59 +02:00
viewport.addEventListener("touchend", onTouchEnd, {passive: true});
2016-06-12 04:16:17 +02:00
}
}
function onTouchMove(e) {
2018-01-11 12:33:36 +01:00
const touch = touchCurPos = e.touches.item(0);
let setX = touch.screenX - touchStartPos.screenX;
2016-06-12 04:16:17 +02:00
if (Math.abs(setX > 30)) {
menuIsMoving = true;
}
if (!menuIsMoving && Math.abs(touch.screenY - touchStartPos.screenY) > 30) {
onTouchEnd();
return;
}
if (menuIsOpen) {
setX += menuWidth;
}
if (setX > menuWidth) {
setX = menuWidth;
} else if (setX < 0) {
setX = 0;
}
viewport.style.transform = "translate3d(" + setX + "px, 0, 0)";
if (menuIsMoving) {
e.preventDefault();
e.stopPropagation();
}
}
function onTouchEnd() {
2018-01-11 12:33:36 +01:00
const diff = touchCurPos.screenX - touchStartPos.screenX;
const absDiff = Math.abs(diff);
2016-06-12 04:16:17 +02:00
if (absDiff > menuWidth / 2 || Date.now() - touchStartTime < 180 && absDiff > 50) {
toggleMenu(diff > 0);
}
viewport.removeEventListener("touchmove", onTouchMove);
viewport.removeEventListener("touchend", onTouchEnd);
viewport.classList.toggle("menu-dragging", false);
viewport.style.transform = null;
touchStartPos = null;
touchCurPos = null;
touchStartTime = 0;
menuIsMoving = false;
}
2017-04-30 12:42:59 +02:00
viewport.addEventListener("touchstart", onTouchStart, {passive: true});
2016-06-12 04:16:17 +02:00
return {
disable: disableSlideout,
toggle: toggleMenu,
isOpen: function() {
return menuIsOpen;
},
2016-06-12 04:16:17 +02:00
};
};