Skip to content

Instantly share code, notes, and snippets.

@armincifuentes
Last active March 8, 2018 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save armincifuentes/f10fa99708136954d0786e631e7f6651 to your computer and use it in GitHub Desktop.
Save armincifuentes/f10fa99708136954d0786e631e7f6651 to your computer and use it in GitHub Desktop.
Swipe to event
/*
* Swipe Navigation
*/
const SwipeWatcher = function (element) {
// This & Public
let watcher = this;
watcher.direction = undefined;
watcher.element = element;
// Private Variables
let events = {
onDrag: new CustomEvent('onDrag'),
onDragLeft: new CustomEvent('onDragLeft'),
onDragRight: new CustomEvent('onDragRight'),
onDragUp: new CustomEvent('onDragUp'),
onDragDown: new CustomEvent('onDragDown'),
onDragStop: new CustomEvent('onDragStop'),
}
// Bindings
watcher.element.addEventListener('touchstart', touchStartHandler);
watcher.element.addEventListener('touchmove', touchMoveHandler);
watcher.element.addEventListener('touchend', touchEndHandler);
// Definitions
function touchStartHandler(ev) {
watcher.startX = ev.touches[0].clientX;
watcher.startY = ev.touches[0].clientY;
}
function touchMoveHandler(ev) {
let direction;
watcher.currentX = ev.touches[0].clientX;
watcher.currentY = ev.touches[0].clientY;
watcher.travelX = watcher.currentX - watcher.startX;
watcher.travelY = watcher.currentY - watcher.startY;
watcher.distanceX = Math.abs(watcher.travelX);
watcher.distanceY = Math.abs(watcher.travelY);
if (Math.abs(watcher.travelX) > Math.abs(watcher.travelY)) {
direction = watcher.travelX > 0 ? 'right' : 'left';
} else {
direction = watcher.travelY > 0 ? 'up' : 'down';
}
let event = events[`onDrag${ucfirst(direction)}`];
watcher.coordinates = {
startX: watcher.startX,
startY: watcher.startY,
currentX: watcher.currentX,
currentY: watcher.currentY,
travelX: watcher.travelX,
travelY: watcher.travelY,
distanceX: watcher.distanceX,
distanceY: watcher.distanceY,
direction,
};
event.coordinates = watcher.coordinates;
watcher.element.dispatchEvent(event);
}
function touchEndHandler(ev) {
let event = events.onDragStop;
event.coordinates = watcher.coordinates;
watcher.element.dispatchEvent(event);
}
function ucfirst(string) {
let first = string.substr(0, 1).toUpperCase();
let remainder = string.substr(1, string.length).toLowerCase();
return `${first}${remainder}`;
}
// Boot
return watcher;
}
const SwipeListener = function(element, watcher, options = {}) {
// This & Public
let listener = this;
listener.init = init;
listener.element = element;
// Private Variables
const defaults = {
direction: 'right',
threshold: 100,
onCommit: null,
onDrag: null,
onCancel: null,
onStop: null,
}
let events = {
didCommit: new CustomEvent('onDragCommit'),
didCancel: new CustomEvent('onDragCancel'),
didDrag: new CustomEvent('onDrag'),
didStop: new CustomEvent('onStop'),
}
// Boot
listener.init();
// Definitions
function init() {
buildSettings(options);
setupListeners();
setupCallbacks();
}
function setupListeners() {
watcher.element.addEventListener(`onDrag${ucfirst(listener.settings.direction)}`, watcherDidDrag);
watcher.element.addEventListener('onDragStop', watcherDidStop);
}
function setupCallbacks() {
if (isCallback(listener.settings.onCommit)) {
listener.element.addEventListener('onDragCommit', listener.settings.onCommit);
}
if (isCallback(listener.settings.onDrag)) {
listener.element.addEventListener('onDrag', listener.settings.onDrag);
}
if (isCallback(listener.settings.onCancel)) {
listener.element.addEventListener('onDragCancel', listener.settings.onCancel);
}
if (isCallback(listener.settings.onStop)) {
listener.element.addEventListener('onStop', listener.settings.onStop);
}
}
function isCallback(callback) {
return typeof callback === 'function';
}
function watcherDidDrag(event) {
let dispatchedEvent = events.didDrag;
dispatchedEvent.coordinates = event.coordinates;
listener.element.dispatchEvent(dispatchedEvent);
}
function watcherDidStop(event) {
let distance = listener.settings.direction === 'up' || 'down' ? 'distanceX' : 'distanceY';
let matchDirection = event.coordinates.direction === listener.settings.direction;
let commited = event.coordinates[distance] >= listener.settings.threshold;
if (matchDirection && commited) {
listener.element.dispatchEvent(events.didCommit);
} else if (matchDirection) {
listener.element.dispatchEvent(events.didCancel);
}
listener.element.dispatchEvent(events.didStop);
}
function bindListener(event, callback) {
watcher.element.addEventListener(`onDrag${ucfirst(direction)}`, callback);
}
function buildSettings(options) {
let params = Object.keys(defaults);
listener.settings = {};
params.forEach((param) => {
listener.settings[param] = typeof options[param] != 'undefined' ? options[param] : defaults[param];
});
}
function ucfirst(string) {
let first = string.substr(0, 1).toUpperCase();
let remainder = string.substr(1, string.length).toLowerCase();
return `${first}${remainder}`;
}
// Return
return listener;
}
$(document).ready(function() {
const watcher = new SwipeWatcher(document);
const swiperLeft = document.querySelector('.myad-bookmark__swipe--left');
const swiperRight = document.querySelector('.myad-bookmark__swipe--right');
let prevProject = new SwipeListener(swiperRight, watcher, {
direction: 'right',
onDrag(event) {
let distance = event.coordinates.travelX < 100 ? -100 + event.coordinates.travelX : 0;
$('.myad-bookmark__swipe--right')
.addClass('myad-bookmark__swipe--active')
.css({
transform: `translate(${distance}%, -50%)`,
});
},
onCommit(event) {
console.log('did swipe right', event);
},
onStop(event) {
$('.myad-bookmark__swipe--right')
.removeClass('myad-bookmark__swipe--active')
.css({ transform: "translate(-100%, -50%)" });
},
});
let nextProject = new SwipeListener(swiperLeft, watcher, {
direction: 'left',
onDrag(event) {
let distance = event.coordinates.travelX > -100 ? 100 - event.coordinates.distanceX : 0;
$('.myad-bookmark__swipe--left')
.addClass('myad-bookmark__swipe--active')
.css({
transform: `translate(${distance}%, -50%)`,
});
},
onCommit(event) {
console.log('did swipe left', event);
},
onStop(event) {
$('.myad-bookmark__swipe--left')
.removeClass('myad-bookmark__swipe--active')
.css({ transform: "translate(100%, -50%)" });
},
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment