100 lines
2.2 KiB
JavaScript
100 lines
2.2 KiB
JavaScript
/**
|
|
* Simple slideout menu implementation.
|
|
*/
|
|
export default function slideoutMenu(viewport, menu) {
|
|
var touchStartPos = null;
|
|
var touchCurPos = null;
|
|
var touchStartTime = 0;
|
|
var menuWidth = parseFloat(window.getComputedStyle(menu).width);
|
|
var menuIsOpen = false;
|
|
var menuIsMoving = false;
|
|
|
|
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();
|
|
return false;
|
|
}
|
|
|
|
var touch = e.touches.item(0);
|
|
viewport.classList.toggle("menu-dragging", true);
|
|
|
|
if ((!menuIsOpen && touch.screenX < 50) || (menuIsOpen && touch.screenX > menuWidth)) {
|
|
touchStartPos = touch;
|
|
touchCurPos = touch;
|
|
touchStartTime = Date.now();
|
|
|
|
viewport.addEventListener("touchmove", onTouchMove);
|
|
viewport.addEventListener("touchend", onTouchEnd);
|
|
}
|
|
}
|
|
|
|
function onTouchMove(e) {
|
|
var touch = touchCurPos = e.touches.item(0);
|
|
var setX = touch.screenX - touchStartPos.screenX;
|
|
|
|
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() {
|
|
var diff = touchCurPos.screenX - touchStartPos.screenX;
|
|
var absDiff = Math.abs(diff);
|
|
|
|
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;
|
|
}
|
|
|
|
viewport.addEventListener("touchstart", onTouchStart);
|
|
|
|
return {
|
|
disable: disableSlideout,
|
|
toggle: toggleMenu,
|
|
isOpen: function() {
|
|
return menuIsOpen;
|
|
}
|
|
};
|
|
}
|