Skip to content

Commit

Permalink
Previews: Add touch gesture support
Browse files Browse the repository at this point in the history
On devices with touch support, maps left and right swipes to moving to
the next and previous item, and double-taps to toggling fullscreen on
and off.
  • Loading branch information
mjpieters committed May 22, 2022
1 parent aa94de4 commit 1b1b6f1
Showing 1 changed file with 70 additions and 3 deletions.
73 changes: 70 additions & 3 deletions src/_h5ai/public/js/lib/ext/preview/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const allsettings = require('../../core/settings');
const store = require('../../core/store');

const win = global.window;
const doc = win.document;
const settings = Object.assign({
enabled: true
}, allsettings.preview);
Expand All @@ -27,11 +28,15 @@ const overlayTpl =
</div>`;
const storekey = 'ext/preview';

const TOUCH_MAX_DELAY = 250;
const TOUCH_GESTURE_DISTANCE = 40;

let isFullscreen = store.get(storekey) || false;
let userAliveTimeoutId = null;
let spinnerIsVisible = false;
let spinnerTimeoutId = null;
let session = null;
let touchState = {};

const centerContent = () => {
const $container = dom('#pv-container');
Expand All @@ -54,7 +59,7 @@ const centerContent = () => {
};

const updateGui = () => {
const docEl = win.document.documentElement;
const docEl = doc.documentElement;
const winWidth = docEl.clientWidth;
const winHeight = docEl.clientHeight;
const margin = isFullscreen ? 0 : 20;
Expand Down Expand Up @@ -149,17 +154,79 @@ const onKeydown = ev => {
}
};

const onTouchstart = ev => {
const now = Date.now();
const deltaT = now - (touchState.last || now);
const touch = ev.changedTouches;

touchState = {
x: touch[0].pageX,
y: touch[0].pageY,
last: now,
deltaX: 0,
deltaY: 0,
isHorizontal: null,
isDoubleTap: touch.length === 1 && deltaT > 0 && deltaT <= TOUCH_MAX_DELAY
};

dom(doc)
.on('touchmove', onTouchmove) // eslint-disable-line no-use-before-define
.on('touchend', onTouchend); // eslint-disable-line no-use-before-define
};

const onTouchmove = ev => {
const touch = ev.changedTouches;
if (touch && touch.length > 1 || ev.scale && ev.scale !== 1) {
return;
}

touchState.deltaX = touch[0].pageX - touchState.x;
touchState.deltaY = touch[0].pageY - touchState.y;

if (touchState.isHorizontal === null) {
touchState.isHorizontal = Math.abs(touchState.deltaX) >= Math.abs(touchState.deltaY);
}
dropEvent(ev);
};

const onTouchend = ev => {
const dX = Math.abs(touchState.deltaX);
const dY = Math.abs(touchState.deltaY);

if (touchState.isDoubleTap && dX <= TOUCH_GESTURE_DISTANCE && dY <= TOUCH_GESTURE_DISTANCE) {
dropEvent(ev);
toggleFullscreen();
} else if (touchState.isHorizontal && dX > TOUCH_GESTURE_DISTANCE && Date.now() - touchState.last < TOUCH_MAX_DELAY) {
switch (touchState.deltaX > 0) {
case true:
dropEvent(ev);
prev();
break;
default:
dropEvent(ev);
next();
}
}
dom(doc)
.off('touchmove', onTouchmove)
.off('touchend', onTouchend);
};

const enter = () => {
setLabels([]);
dom('#pv-container').clr();
dom('#pv-container')
.on('touchstart', onTouchstart)
.clr();
dom('#pv-overlay').show();
dom(win).on('keydown', onKeydown);
updateGui();
};

const exit = () => {
setLabels([]);
dom('#pv-container').clr();
dom('#pv-container')
.off('touchstart', onTouchstart)
.clr();
dom('#pv-overlay').hide();
dom(win).off('keydown', onKeydown);
};
Expand Down

0 comments on commit 1b1b6f1

Please sign in to comment.