UNPKG

sioux-offscreen

Version:

An off screen navigation item. Similar to the menu of the Facebook and Path app

402 lines (319 loc) 13.2 kB
;(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){ (function(){var $ = require('sioux-global'); window.$ = $; var Offscreen = require('../index.js'); window.onload = function () { var offscr = new Offscreen($('.offscreen'), $('.onscreen')); $('.menu').on('tap', function () { offscr.toggle(); }).on('click', function () { offscr.toggle(); }); }; })() },{"../index.js":5,"sioux-global":2}],2:[function(require,module,exports){ require('node-touch')(); function SiouxGlobal (selector, parentElement) { var self = this; if (!parentElement) parentElement = document; var elems = parentElement.querySelectorAll(selector); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; if (!elem.classList.contains('touch')) elem.classList.add('touch'); } self._elems = elems; self.element = elems.length === 1 ? elems[0] : elems; return self; } SiouxGlobal.prototype.on = function(eventName, handler) { var self = this; for (var i = 0; i < self._elems.length; i++) { self._elems[i].addEventListener(eventName, handler, false); } return self; }; SiouxGlobal.prototype.off = function(eventName, handler) { var self = this; for (var i = 0; i < self._elems.length; i++) { self._elems[i].removeEventListener(eventName, handler, false); } return self; }; SiouxGlobal.prototype.css = function(prop, val) { var self = this; if (val) { for (var i = 0; i < self._elems.length; i++) self._elems[i].style[prop] = val; return self; } for (var ix in prop) { for (var i = 0; i < self._elems.length; i++) self._elems[i].style[ix] = prop[ix]; } return self; }; function helper (selector, parentElement) { return (new SiouxGlobal(selector, parentElement)); } helper.isTouchDevice = !!('ontouchstart' in window); module.exports = helper; },{"node-touch":3}],3:[function(require,module,exports){ require('node-inserted')('touch'); var TAP_BOUND_X = 15; var TAP_BOUND_Y = 15; function isInBounds (touch, element) { var left = element.offsetLeft , top = element.offsetTop , right = left + element.offsetWidth , bottom = top + element.offsetHeight ; return (touch.pageX > left && touch.pageX < right && touch.pageY > top && touch.pageY < bottom); } if (!window.isTouchDevice) window.isTouchDevice = !!('ontouchstart' in window); module.exports = function () { document.addEventListener('inserted', function (event) { if (event.animationName !== 'touchNodeInserted') return; var elem = event.inserted; var _tapStartTouch = { pageX: undefined, pageY: undefined }; if (!window.isTouchDevice) { elem.addEventListener('mouseover', function (event) { this.classList.add('hover'); }, false); elem.addEventListener('mouseout', function (event) { this.classList.remove('hover'); }, false); return; } var handler = function (event) { event.preventDefault(); }; elem.addEventListener('mouseenter', handler, false); elem.addEventListener('mousemove', handler, false); elem.addEventListener('mouseleave', handler, false); elem.addEventListener('touchstart', function (event) { this.classList.add('hover'); _tapStartTouch.pageX = event.changedTouches[0].pageX; _tapStartTouch.pageY = event.changedTouches[0].pageY; }, false); elem.addEventListener('touchend', function (event) { this.classList.remove('hover'); if (!_tapStartTouch.pageX && !_tapStartTouch.pageY) return; var x = Math.abs(event.changedTouches[0].pageX - _tapStartTouch.pageX); var y = Math.abs(event.changedTouches[0].pageY - _tapStartTouch.pageY); if (x < TAP_BOUND_X && y < TAP_BOUND_Y) { var tapEvent = new Event('tap'); tapEvent.initEvent('tap', true, true); elem.dispatchEvent(tapEvent); } _tapStartTouch.pageX = undefined; _tapStartTouch.pageY = undefined; }, false); // Touch leave event var touchleaveHandler = function (event) { var touch = event.touches[0] || event.changedTouches[0]; if (!isInBounds(touch, elem)) { var leaveEvent = new Event('touchleave'); leaveEvent.initEvent('touchleave', true, true); elem.dispatchEvent(leaveEvent); elem.removeEventListener('touchmove', touchleaveHandler, false); } }; elem.addEventListener('touchmove', touchleaveHandler, false); elem.addEventListener('touchend', function (event) { elem.addEventListener('touchmove', touchleaveHandler, false); }, false); // Tap event elem.addEventListener('touchleave', function (event) { _tapStartTouch.pageX = undefined; _tapStartTouch.pageY = undefined; }, false); // Swipe event var swipeStarted = false; var startTouch, prevTouch; var startX = 0, startY = 0; var direction = ''; var d = 0; elem.addEventListener('touchstart', function (event) { startX = event.changedTouches[0].clientX; startY = event.changedTouches[0].clientY; startTouch = event.changedTouches[0]; }, false); elem.addEventListener('touchmove', function (event) { var dx = event.changedTouches[0].clientX - startX; var dy = event.changedTouches[0].clientY - startY; var swipeEvent = new Event('swipe'); if (swipeStarted) { swipeEvent.initEvent('swipemove', true, true); swipeEvent.startTouch = startTouch; swipeEvent.prevTouch = prevTouch; swipeEvent.changedTouch = event.changedTouches[0]; prevTouch = event.changedTouches[0]; if (direction === 'RIGHT' || direction === 'LEFT') { if (dx !== d) { swipeEvent.direction = direction; swipeEvent.delta = direction === 'RIGHT' ? dx : -dx; d = dx; elem.dispatchEvent(swipeEvent); } } else { if (dy !== d) { swipeEvent.direction = direction; swipeEvent.delta = direction === 'DOWN' ? dy : -dy; d = dy; elem.dispatchEvent(swipeEvent); } } return; } swipeStarted = true; swipeEvent.initEvent('swipestart', true, true); swipeEvent.startTouch = startTouch; swipeEvent.changedTouch = event.changedTouches[0]; prevTouch = event.changedTouches[0]; if (Math.abs(dx) > Math.abs(dy)) { direction = dx > 0 ? 'RIGHT' : 'LEFT'; swipeEvent.delta = dx > 0 ? dx : -dx; d = dx; } else { direction = dy > 0 ? 'DOWN' : 'UP'; swipeEvent.delta = dy > 0 ? dy : -dy; d = dy; } swipeEvent.direction = direction; elem.dispatchEvent(swipeEvent); }, false); elem.addEventListener('touchend', function (event) { if (!swipeStarted) return; var swipeEvent = new Event('swipeend'); swipeEvent.initEvent('swipeend', true, true); swipeEvent.startTouch = startTouch; swipeEvent.prevTouch = prevTouch; swipeEvent.changedTouch = event.changedTouches[0]; swipeEvent.direction = direction; swipeEvent.delta = Math.abs(d); elem.dispatchEvent(swipeEvent); swipeStarted = false; }, false); }, false); }; },{"node-inserted":4}],4:[function(require,module,exports){ module.exports = function (className) { if (!className) className = 'inserted'; var css = '@keyframes ' + className + 'NodeInserted { from { clip: rect(1px, auto, auto, auto); } to { clip: rect(0px, auto, auto, to); } } @-moz-keyframes ' + className + 'NodeInserted { from { clip: rect(1px, auto, auto, auto); } to { clip: rect(0px, auto, auto, auto); } } @-webkit-keyframes ' + className + 'NodeInserted { from { clip: rect(1px, auto, auto, auto); } to { clip: rect(0px, auto, auto, auto); } } @-ms-keyframes ' + className + 'NodeInserted { from { clip: rect(1px, auto, auto, auto); } to { clip: rect(0px, auto, auto, auto); } } @-o-keyframes ' + className + 'NodeInserted { from { clip: rect(1px, auto, auto, auto); } to { clip: rect(0px, auto, auto, auto); } } .' + className + ' { animation-duration: 0.001s; -o-animation-duration: 0.001s; -ms-animation-duration: 0.001s; -moz-animation-duration: 0.001s; -webkit-animation-duration: 0.001s; animation-name: ' + className + 'NodeInserted; -o-animation-name: ' + className + 'NodeInserted; -ms-animation-name: ' + className + 'NodeInserted; -moz-animation-name: ' + className + 'NodeInserted; -webkit-animation-name: ' + className + 'NodeInserted;}'; var elem = document.createElement('style'); var text = document.createTextNode(css); elem.appendChild(text); if (document.head.childNodes.length) document.head.insertBefore(elem, document.head.childNodes[0]); else document.head.appendChild(elem); insertListener = function (event) { if (event.animationName !== className +'NodeInserted') return; var insertEvent = new Event('inserted'); insertEvent.initEvent('inserted', false, true); insertEvent.inserted = event.target; insertEvent.animationName = event.animationName; if (event.target.parentNode) event.target.parentNode.dispatchEvent(insertEvent); document.dispatchEvent(insertEvent); }; document.addEventListener("animationstart", insertListener, false); document.addEventListener("MSAnimationStart", insertListener, false); document.addEventListener("webkitAnimationStart", insertListener, false); }; },{}],5:[function(require,module,exports){ var preventDefault = function (e) { e.preventDefault(); }; function Offscreen (offscreen, onscreen) { var self = this; if (!offscreen) self.offscreen = document.querySelector('.offscreen'); else self.offscreen = offscreen._elems ? offscreen.element : offscreen; if (!onscreen) self.onscreen = document.querySelector('.onscreen'); else self.onscreen = onscreen._elems ? onscreen.element : onscreen; self.hidden = true; var onscr = self.onscreen; var duration = ''; var translateX = 0; var translate = function (left, right, delta) { var d = translateX + (right ? delta : -delta); if (d < 0) d = 0; else if (d > self.offscreen.offsetWidth) d = self.offscreen.offsetWidth; onscr.style.webkitTransform = 'translateX(' + d + 'px)'; }; onscr.addEventListener('swipestart', function (event) { var left = !self.hidden && event.direction === 'LEFT'; var right = self.hidden && event.direction === 'RIGHT'; if (!(left ^ right)) return; onscr.ontouchmove = preventDefault; duration = getComputedStyle(onscr).webkitTransitionDuration; onscr.style.webkitTransitionDuration = '0s'; onscr.style.webkitOverflowScrolling = 'auto'; onscr.style.overflow = 'hidden'; var s = self.onscreen.style.webkitTransform.match(/\d+/); translateX = Number(s ? s[0] : 0); translate(left, right, event.delta); }, false); onscr.addEventListener('swipemove', function (event) { var left = !self.hidden && event.direction === 'LEFT'; var right = self.hidden && event.direction === 'RIGHT'; if (!(left ^ right)) return; translate(left, right, event.delta); }, false); onscr.addEventListener('swipeend', function (event) { var left = !self.hidden && event.direction === 'LEFT'; var right = self.hidden && event.direction === 'RIGHT'; if (!(left ^ right)) return; onscr.style.webkitOverflowScrolling = 'touch'; onscr.style.overflow = 'auto'; onscr.style.webkitTransitionDuration = duration; var enough = event.delta > 35; if ((right && enough) || (left && !enough)) self.show(); if ((left && enough) || (right && !enough)) self.hide(); }, false); } Offscreen.prototype.show = function (cb) { var self = this; self.onscreen.ontouchmove = preventDefault; var s = self.onscreen.style.webkitTransform.match(/\d+/); var translate = Number(s ? s[0] : 0); if (translate === this.offscreen.offsetWidth) { self.hidden = false; if (cb) cb(); return; } self.onscreen.style.webkitTransform = 'translateX(' + this.offscreen.offsetWidth + 'px)'; var handler = function (event) { if (event.propertyName !== '-webkit-transform') return; self.hidden = false; if (cb) cb(); this.removeEventListener('webkitTransitionEnd', handler, false); }; self.onscreen.addEventListener('webkitTransitionEnd', handler, false); }; Offscreen.prototype.hide = function (cb) { var self = this; self.onscreen.ontouchmove = null; var s = self.onscreen.style.webkitTransform.match(/\d+/); var translate = Number(s ? s[0] : 0); if (translate === 0) { self.hidden = true; if (cb) cb(); return; } self.onscreen.style.webkitTransform = 'translateX(0)'; var handler = function (event) { if (event.propertyName !== '-webkit-transform') return; self.hidden = true; if (cb) cb(); this.removeEventListener('webkitTransitionEnd', handler, false); }; self.onscreen.addEventListener('webkitTransitionEnd', handler, false); return this; }; Offscreen.prototype.toggle = function(cb) { if (this.hidden) this.show(cb); else this.hide(cb); return this; }; module.exports = Offscreen; },{}]},{},[1]) ;