diff --git a/README.md b/README.md index 98cb6c5..262566e 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,9 @@ Executed before the menu begins to close - `onClose` (`callback`): Executed as soon as the menu has closed +- `onDrag` (`callback`): +Executed as the menu is being dragged; returns percentage completion + # Methods - `OSREC.superslide.open()` diff --git a/package.json b/package.json index a7250e8..f28fafb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superslide.js", - "version": "1.0.0", + "version": "1.0.1", "description": "A lightweight, slick sliding menu for your next PWA by OSREC Technologies (https://osrec.co.uk)", "main": "superslide-std.js", "scripts": { diff --git a/superslide-std.js b/superslide-std.js index 4e3f7a3..c6645c2 100755 --- a/superslide-std.js +++ b/superslide-std.js @@ -37,6 +37,7 @@ OSREC.superslide = function (p) { me.p.onOpen = typeof me.p.onOpen == 'function' ? me.p.onOpen : function () {}; me.p.beforeClose = typeof me.p.beforeClose == 'function' ? me.p.beforeClose : function () {}; me.p.onClose = typeof me.p.onClose == 'function' ? me.p.onClose : function () {}; + me.p.onDrag = typeof me.p.onDrag == 'function' ? me.p.onDrag : function () {}; me.body = document; me.p.isOpen = false; @@ -98,22 +99,34 @@ OSREC.superslide = function (p) { me.p.content.style.transition = 'none'; me.p.slider.style.transition = 'none'; - var sliderStartPosition = me.p.isOpen ? me.p.slider.offsetWidth : 0; + var sliderOffsetWidth = me.p.slider.offsetWidth; + var sliderStartPosition = me.p.isOpen ? sliderOffsetWidth : 0; var translation = 0; var delta = 0; + var completion = 0; var touchMoveFunction = function (e) { delta = e.changedTouches[0].clientX - startX; translation = sliderStartPosition + delta; - if (translation > me.p.slider.offsetWidth) { - translation = me.p.slider.offsetWidth; + if (translation > sliderOffsetWidth) { + translation = sliderOffsetWidth; } if (translation < 0) { translation = 0; } + if (delta >= sliderOffsetWidth) { + completion = 1; + } else if (delta <= 0) { + completion = 0; + } else { + completion = delta / sliderOffsetWidth; + } + + me.p.onDrag(completion); + me.p.slider.style.transform = `translate3d(${translation}px, 0, 0)`; if (me.p.slideContent) { me.p.content.style.transform = me.p.slider.style.transform; @@ -164,22 +177,34 @@ OSREC.superslide = function (p) { me.p.content.style.transition = 'none'; me.p.slider.style.transition = 'none'; - var sliderStartPosition = me.p.isOpen ? -me.p.slider.offsetWidth : 0; + var sliderOffsetWidth = me.p.slider.offsetWidth; + var sliderStartPosition = me.p.isOpen ? -sliderOffsetWidth : 0; var translation = 0; var delta = 0; + var completion = 0; var touchMoveFunction = function (e) { delta = e.changedTouches[0].clientX - startX; translation = sliderStartPosition + delta; - if (translation < -me.p.slider.offsetWidth) { - translation = -me.p.slider.offsetWidth; + if (translation < -sliderOffsetWidth) { + translation = -sliderOffsetWidth; } if (translation > 0) { translation = 0; } + if ((delta * -1) >= sliderOffsetWidth) { + completion = 1; + } else if ((delta * -1) <= 0) { + completion = 0; + } else { + completion = (delta * -1) / sliderOffsetWidth; + } + + me.p.onDrag(completion); + me.p.slider.style.transform = `translate3d(${translation}px, 0, 0)`; if (me.p.slideContent) { me.p.content.style.transform = me.p.slider.style.transform; @@ -401,4 +426,4 @@ if (hasDefine) { // Assign to the global object // This makes sure that the object really is assigned to the global scope root.OSREC = OSREC; -} \ No newline at end of file +} diff --git a/superslide-std.min.js b/superslide-std.min.js index 1e76562..b363abb 100644 --- a/superslide-std.min.js +++ b/superslide-std.min.js @@ -1 +1 @@ -"use strict";var OSREC=OSREC||{};OSREC.superslide=function(e){var t=this;t.p=e,t.p.animation=t.p.animation||"slideLeft",t.p.duration=t.p.duration||.5,t.p.allowDrag=void 0===t.p.allowDrag||t.p.allowDrag,t.p.slideContent=void 0===t.p.slideContent||t.p.slideContent,t.p.allowContentInteraction=void 0!==t.p.allowContentInteraction&&t.p.allowContentInteraction,t.p.closeOnBlur=void 0!==t.p.closeOnBlur&&t.p.closeOnBlur,t.p.width=t.p.width||"70vw",t.p.height=t.p.height||"100px",t.p.dragThreshold=t.p.dragThreshold||70,t.p.openThreshold=t.p.openThreshold||70,t.p.closeThreshold=t.p.closeThreshold||20,t.p.beforeOpen="function"==typeof t.p.beforeOpen?t.p.beforeOpen:function(){},t.p.onOpen="function"==typeof t.p.onOpen?t.p.onOpen:function(){},t.p.beforeClose="function"==typeof t.p.beforeClose?t.p.beforeClose:function(){},t.p.onClose="function"==typeof t.p.onClose?t.p.onClose:function(){},t.body=document,t.p.isOpen=!1;t.p.cssTransitionEndEvent=function(){var e,t=document.createElement("dummy"),n={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(e in n)if(void 0!==t.style[e])return n[e]}(),function(){function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),n}e.prototype=window.Event.prototype,window.CustomEvent=e}();var n=Math.max(document.documentElement.clientWidth,window.innerWidth||0);Math.max(document.documentElement.clientHeight,window.innerHeight||0);switch(t.p.sliderTransformClose="",t.p.contentTransformClose="",t.p.animation){case"slideLeft":t.p.slider.style.cssText=`position: fixed; overflow-y: auto; -webkit-overflow-scrolling: touch; width: ${t.p.width}; height: 100%; top: 0px; left: -${t.p.width};`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(${t.p.width},0,0)`,t.p.slider.parentNode.style.overflowX="hidden",t.p.contentTransform=`translate3d(${t.p.width},0,0)`,t.p.touchStartFunction=function(e){var n=e.changedTouches[0].clientX;if(t.p.isOpen||!(n>t.p.dragThreshold)){t.p.content.style.transition="none",t.p.slider.style.transition="none";var o=t.p.isOpen?t.p.slider.offsetWidth:0,i=0,s=0,r=function(e){s=e.changedTouches[0].clientX-n,(i=o+s)>t.p.slider.offsetWidth&&(i=t.p.slider.offsetWidth),i<0&&(i=0),t.p.slider.style.transform=`translate3d(${i}px, 0, 0)`,t.p.slideContent&&(t.p.content.style.transform=t.p.slider.style.transform),t.p.slider.style.opacity=.999},p=function(e){t.body.removeEventListener("touchmove",r),t.p.slider.style.transition=`${t.p.duration}s`,t.p.slideContent&&(t.p.content.style.transition=`${t.p.duration}s`),!t.p.isOpen&&s>=t.p.openThreshold?t.open(!0):t.p.isOpen&&s<-t.p.closeThreshold?t.close(!0):t.p.isOpen?t.open(!0):t.close(!0),t.body.removeEventListener("touchend",p)};t.body.addEventListener("touchend",p),t.body.addEventListener("touchmove",r)}};break;case"slideRight":t.p.slider.style.cssText=`position: fixed; overflow-y: auto; -webkit-overflow-scrolling: touch; width: ${t.p.width}; height: 100%; top: 0px; left: 100%;`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(-${t.p.width},0,0)`,t.p.slider.parentNode.style.overflowX="hidden",t.p.contentTransform=`translate3d(-${t.p.width},0,0)`,t.p.touchStartFunction=function(e){var o=e.changedTouches[0].clientX;if(t.p.isOpen||!(o0&&(s=0),t.p.slider.style.transform=`translate3d(${s}px, 0, 0)`,t.p.slideContent&&(t.p.content.style.transform=t.p.slider.style.transform),t.p.slider.style.opacity=.999},l=function(e){t.body.removeEventListener("touchmove",p),t.p.slider.style.transition=`${t.p.duration}s`,t.p.slideContent&&(t.p.content.style.transition=`${t.p.duration}s`),!t.p.isOpen&&r<=-t.p.openThreshold?t.open(!0):t.p.isOpen&&r>t.p.closeThreshold?t.close(!0):t.p.isOpen?t.open(!0):t.close(!0),t.body.removeEventListener("touchend",l)};t.body.addEventListener("touchend",l),t.body.addEventListener("touchmove",p)}};break;case"slideTop":t.p.slider.style.cssText=`position: fixed; overflow-x: auto; -webkit-overflow-scrolling: touch; width: 100%; height: ${t.p.height}; top: -${t.p.height}; left: 0;`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(0,${t.p.height},0)`,t.p.contentTransform=`translate3d(0,${t.p.height},0)`,t.p.allowDrag=!1,t.p.touchStartFunction=function(e){};break;case"slideBottom":t.p.slider.style.cssText=`position: fixed; overflow-x: auto; -webkit-overflow-scrolling: touch; width: 100%; height: ${t.p.height}; top: 100vh; left: 0;`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(0,-${t.p.height},0)`,t.p.slider.parentNode.style.overflowX="hidden",t.p.contentTransform=`translate3d(0,-${t.p.height},0)`,t.p.allowDrag=!1}return t.p.closeOnBlurFunction=function(e){e.preventDefault(),t.close.call(t)},t.p.slideContent&&(t.p.content.style.transition=`${t.p.duration}s`),t.p.allowDrag&&t.body.addEventListener("touchstart",t.p.touchStartFunction),t.p.allowContentInteraction?t.p.contentTouchStartFunction=function(e){}:t.p.contentTouchStartFunction=function(e){e.preventDefault()},t.p.slider.offsetHeight,t.p.slider.style.transition=`${t.p.duration}s`,t.p.content.style["-webkit-tap-highlight-color"]="transparent",t},OSREC.superslide.prototype.open=function(e){var t=this;return!e&&t.p.isOpen?Promise.resolve():new Promise(function(e,n){var o=function(n){(n.target||n.srcElement||n.originalTarget)==t.p.slider&&(t.p.onOpen(),t.p.isOpen=!0,t.p.slider.removeEventListener(t.p.cssTransitionEndEvent,o),t.p.content.addEventListener("touchstart",t.p.contentTouchStartFunction),t.p.closeOnBlur&&(t.body.removeEventListener("touchstart",t.p.touchStartFunction),t.p.content.addEventListener("touchstart",t.p.closeOnBlurFunction),t.p.content.addEventListener("click",t.p.closeOnBlurFunction)),e())};t.p.beforeOpen(),t.p.slider.addEventListener(t.p.cssTransitionEndEvent,o),t.p.slider.style.transform=t.p.sliderTransform,t.p.slider.style.opacity=1,t.p.slideContent&&(t.p.content.style.transform=t.p.contentTransform)})},OSREC.superslide.prototype.close=function(e){var t=this;return e||t.p.isOpen?new Promise(function(e,n){var o=function(n){(n.target||n.srcElement||n.originalTarget)==t.p.slider&&(t.p.onClose(),t.p.isOpen=!1,t.p.slider.removeEventListener(t.p.cssTransitionEndEvent,o),t.p.content.removeEventListener("touchstart",t.p.contentTouchStartFunction),t.p.closeOnBlur&&(t.body.addEventListener("touchstart",t.p.touchStartFunction),t.p.content.removeEventListener("touchstart",t.p.closeOnBlurFunction),t.p.content.removeEventListener("click",t.p.closeOnBlurFunction)),e())};t.p.beforeClose(),t.p.slider.addEventListener(t.p.cssTransitionEndEvent,o),t.p.slider.style.transform=t.p.sliderTransformClose,t.p.slider.style.opacity=1,t.p.slideContent&&(t.p.content.style.transform=t.p.contentTransformClose)}):Promise.resolve()},OSREC.superslide.prototype.toggle=function(){return this.p.isOpen?(console.log("close"),this.close()):(console.log("open"),this.open())},OSREC.superslide.prototype.isOpen=function(){return this.p.isOpen},OSREC.superslide.prototype.ready=function(){return this.p.readyPromise},OSREC.superslide.prototype.destroy=function(){var e=this;this.close().then(function(){e.body.removeEventListener("touchstart",e.p.touchStartFunction),e.body=null,e.p.content.removeEventListener("touchstart",e.p.closeOnBlurFunction),e.p.content.removeEventListener("click",e.p.closeOnBlurFunction),e.p.content=null,e.p.slider=null,e.p=null})};var hasDefine="function"==typeof define,hasExports="undefined"!=typeof module&&module.exports,root="undefined"==typeof window?global:window;hasDefine?define([],function(){return OSREC.superslide}):hasExports?module.exports=OSREC.superslide:root.OSREC=OSREC; \ No newline at end of file +"use strict";var OSREC=OSREC||{};OSREC.superslide=function(e){var t=this;t.p=e,t.p.animation=t.p.animation||"slideLeft",t.p.duration=t.p.duration||.5,t.p.allowDrag=void 0===t.p.allowDrag||t.p.allowDrag,t.p.slideContent=void 0===t.p.slideContent||t.p.slideContent,t.p.allowContentInteraction=void 0!==t.p.allowContentInteraction&&t.p.allowContentInteraction,t.p.closeOnBlur=void 0!==t.p.closeOnBlur&&t.p.closeOnBlur,t.p.width=t.p.width||"70vw",t.p.height=t.p.height||"100px",t.p.dragThreshold=t.p.dragThreshold||70,t.p.openThreshold=t.p.openThreshold||70,t.p.closeThreshold=t.p.closeThreshold||20,t.p.beforeOpen="function"==typeof t.p.beforeOpen?t.p.beforeOpen:function(){},t.p.onOpen="function"==typeof t.p.onOpen?t.p.onOpen:function(){},t.p.beforeClose="function"==typeof t.p.beforeClose?t.p.beforeClose:function(){},t.p.onClose="function"==typeof t.p.onClose?t.p.onClose:function(){},t.p.onDrag="function"==typeof t.p.onDrag?t.p.onDrag:function(){},t.body=document,t.p.isOpen=!1;t.p.cssTransitionEndEvent=function(){var e,t=document.createElement("dummy"),n={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(e in n)if(void 0!==t.style[e])return n[e]}(),function(){function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),n}e.prototype=window.Event.prototype,window.CustomEvent=e}();var n=Math.max(document.documentElement.clientWidth,window.innerWidth||0);Math.max(document.documentElement.clientHeight,window.innerHeight||0);switch(t.p.sliderTransformClose="",t.p.contentTransformClose="",t.p.animation){case"slideLeft":t.p.slider.style.cssText=`position: fixed; overflow-y: auto; -webkit-overflow-scrolling: touch; width: ${t.p.width}; height: 100%; top: 0px; left: -${t.p.width};`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(${t.p.width},0,0)`,t.p.slider.parentNode.style.overflowX="hidden",t.p.contentTransform=`translate3d(${t.p.width},0,0)`,t.p.touchStartFunction=function(e){var n=e.changedTouches[0].clientX;if(t.p.isOpen||!(n>t.p.dragThreshold)){t.p.content.style.transition="none",t.p.slider.style.transition="none";var o=t.p.slider.offsetWidth,i=t.p.isOpen?o:0,s=0,r=0,p=0,l=function(e){r=e.changedTouches[0].clientX-n,(s=i+r)>o&&(s=o),s<0&&(s=0),p=r>=o?1:r<=0?0:r/o,t.p.onDrag(p),t.p.slider.style.transform=`translate3d(${s}px, 0, 0)`,t.p.slideContent&&(t.p.content.style.transform=t.p.slider.style.transform),t.p.slider.style.opacity=.999},d=function(e){t.body.removeEventListener("touchmove",l),t.p.slider.style.transition=`${t.p.duration}s`,t.p.slideContent&&(t.p.content.style.transition=`${t.p.duration}s`),!t.p.isOpen&&r>=t.p.openThreshold?t.open(!0):t.p.isOpen&&r<-t.p.closeThreshold?t.close(!0):t.p.isOpen?t.open(!0):t.close(!0),t.body.removeEventListener("touchend",d)};t.body.addEventListener("touchend",d),t.body.addEventListener("touchmove",l)}};break;case"slideRight":t.p.slider.style.cssText=`position: fixed; overflow-y: auto; -webkit-overflow-scrolling: touch; width: ${t.p.width}; height: 100%; top: 0px; left: 100%;`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(-${t.p.width},0,0)`,t.p.slider.parentNode.style.overflowX="hidden",t.p.contentTransform=`translate3d(-${t.p.width},0,0)`,t.p.touchStartFunction=function(e){var o=e.changedTouches[0].clientX;if(t.p.isOpen||!(o0&&(r=0),l=-1*p>=i?1:-1*p<=0?0:-1*p/i,t.p.onDrag(l),t.p.slider.style.transform=`translate3d(${r}px, 0, 0)`,t.p.slideContent&&(t.p.content.style.transform=t.p.slider.style.transform),t.p.slider.style.opacity=.999},a=function(e){t.body.removeEventListener("touchmove",d),t.p.slider.style.transition=`${t.p.duration}s`,t.p.slideContent&&(t.p.content.style.transition=`${t.p.duration}s`),!t.p.isOpen&&p<=-t.p.openThreshold?t.open(!0):t.p.isOpen&&p>t.p.closeThreshold?t.close(!0):t.p.isOpen?t.open(!0):t.close(!0),t.body.removeEventListener("touchend",a)};t.body.addEventListener("touchend",a),t.body.addEventListener("touchmove",d)}};break;case"slideTop":t.p.slider.style.cssText=`position: fixed; overflow-x: auto; -webkit-overflow-scrolling: touch; width: 100%; height: ${t.p.height}; top: -${t.p.height}; left: 0;`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(0,${t.p.height},0)`,t.p.contentTransform=`translate3d(0,${t.p.height},0)`,t.p.allowDrag=!1,t.p.touchStartFunction=function(e){};break;case"slideBottom":t.p.slider.style.cssText=`position: fixed; overflow-x: auto; -webkit-overflow-scrolling: touch; width: 100%; height: ${t.p.height}; top: 100vh; left: 0;`,t.p.slider.style.transition=`${t.p.duration}s`,t.p.sliderTransform=`translate3d(0,-${t.p.height},0)`,t.p.slider.parentNode.style.overflowX="hidden",t.p.contentTransform=`translate3d(0,-${t.p.height},0)`,t.p.allowDrag=!1}return t.p.closeOnBlurFunction=function(e){e.preventDefault(),t.close.call(t)},t.p.slideContent&&(t.p.content.style.transition=`${t.p.duration}s`),t.p.allowDrag&&t.body.addEventListener("touchstart",t.p.touchStartFunction),t.p.allowContentInteraction?t.p.contentTouchStartFunction=function(e){}:t.p.contentTouchStartFunction=function(e){e.preventDefault()},t.p.slider.offsetHeight,t.p.slider.style.transition=`${t.p.duration}s`,t.p.content.style["-webkit-tap-highlight-color"]="transparent",t},OSREC.superslide.prototype.open=function(e){var t=this;return!e&&t.p.isOpen?Promise.resolve():new Promise(function(e,n){var o=function(n){(n.target||n.srcElement||n.originalTarget)==t.p.slider&&(t.p.onOpen(),t.p.isOpen=!0,t.p.slider.removeEventListener(t.p.cssTransitionEndEvent,o),t.p.content.addEventListener("touchstart",t.p.contentTouchStartFunction),t.p.closeOnBlur&&(t.body.removeEventListener("touchstart",t.p.touchStartFunction),t.p.content.addEventListener("touchstart",t.p.closeOnBlurFunction),t.p.content.addEventListener("click",t.p.closeOnBlurFunction)),e())};t.p.beforeOpen(),t.p.slider.addEventListener(t.p.cssTransitionEndEvent,o),t.p.slider.style.transform=t.p.sliderTransform,t.p.slider.style.opacity=1,t.p.slideContent&&(t.p.content.style.transform=t.p.contentTransform)})},OSREC.superslide.prototype.close=function(e){var t=this;return e||t.p.isOpen?new Promise(function(e,n){var o=function(n){(n.target||n.srcElement||n.originalTarget)==t.p.slider&&(t.p.onClose(),t.p.isOpen=!1,t.p.slider.removeEventListener(t.p.cssTransitionEndEvent,o),t.p.content.removeEventListener("touchstart",t.p.contentTouchStartFunction),t.p.closeOnBlur&&(t.body.addEventListener("touchstart",t.p.touchStartFunction),t.p.content.removeEventListener("touchstart",t.p.closeOnBlurFunction),t.p.content.removeEventListener("click",t.p.closeOnBlurFunction)),e())};t.p.beforeClose(),t.p.slider.addEventListener(t.p.cssTransitionEndEvent,o),t.p.slider.style.transform=t.p.sliderTransformClose,t.p.slider.style.opacity=1,t.p.slideContent&&(t.p.content.style.transform=t.p.contentTransformClose)}):Promise.resolve()},OSREC.superslide.prototype.toggle=function(){return this.p.isOpen?(console.log("close"),this.close()):(console.log("open"),this.open())},OSREC.superslide.prototype.isOpen=function(){return this.p.isOpen},OSREC.superslide.prototype.ready=function(){return this.p.readyPromise},OSREC.superslide.prototype.destroy=function(){var e=this;this.close().then(function(){e.body.removeEventListener("touchstart",e.p.touchStartFunction),e.body=null,e.p.content.removeEventListener("touchstart",e.p.closeOnBlurFunction),e.p.content.removeEventListener("click",e.p.closeOnBlurFunction),e.p.content=null,e.p.slider=null,e.p=null})};var hasDefine="function"==typeof define,hasExports="undefined"!=typeof module&&module.exports,root="undefined"==typeof window?global:window;hasDefine?define([],function(){return OSREC.superslide}):hasExports?module.exports=OSREC.superslide:root.OSREC=OSREC; \ No newline at end of file