diff --git a/README.md b/README.md index 2aa2494..fa66b84 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ If you want to use this library in IE, you need to include a CustomEvent polyfil gyroscopeMaxAngleX: 45, // This is the top limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the right border of the element; gyroscopeMinAngleY: -45, // This is the bottom limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the top border of the element; gyroscopeMaxAngleY: 45, // This is the top limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the bottom border of the element; + gyroscopeSamples: 10 // How many gyroscope moves to decide the starting position. } ``` @@ -87,10 +88,6 @@ Also available on npm https://www.npmjs.com/package/vanilla-tilt npm install vanilla-tilt ``` -#### Typings - -Typings were out of date in the previous version, so I've rolled a copy directly into the application for you would be Typescript junkies! - ### Credits Original library: [Tilt.js](http://gijsroge.github.io/tilt.js/) diff --git a/dist/vanilla-tilt.babel.js b/dist/vanilla-tilt.babel.js index 36744c0..8db4909 100644 --- a/dist/vanilla-tilt.babel.js +++ b/dist/vanilla-tilt.babel.js @@ -11,7 +11,7 @@ var classCallCheck = function (instance, Constructor) { * Created by Șandor Sergiu (micku7zu) on 1/27/2017. * Original idea: https://github.com/gijsroge/tilt.js * MIT License. - * Version 1.6.1 + * Version 1.6.2 */ var VanillaTilt = function () { @@ -27,6 +27,12 @@ var VanillaTilt = function () { this.height = null; this.left = null; this.top = null; + + this.gammazero = null; + this.betazero = null; + this.lastgammazero = null; + this.lastbetazero = null; + this.transitionTimeout = null; this.updateCall = null; @@ -43,6 +49,7 @@ var VanillaTilt = function () { this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]); this.fullPageListening = this.isSettingTrue(this.settings["full-page-listening"]); this.gyroscope = this.isSettingTrue(this.settings.gyroscope); + this.gyroscopeSamples = this.settings.gyroscopeSamples; if (this.glare) { this.prepareGlare(); @@ -156,14 +163,29 @@ var VanillaTilt = function () { this.updateElementPosition(); + if (this.gyroscopeSamples > 0) { + this.lastgammazero = this.gammazero; + this.lastbetazero = this.betazero; + + if (this.gammazero === null) { + this.gammazero = event.gamma; + this.betazero = event.beta; + } else { + this.gammazero = (event.gamma + this.lastgammazero) / 2; + this.betazero = (event.beta + this.lastbetazero) / 2; + } + + this.gyroscopeSamples -= 1; + } + var totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX; var totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY; var degreesPerPixelX = totalAngleX / this.width; var degreesPerPixelY = totalAngleY / this.height; - var angleX = event.gamma - this.settings.gyroscopeMinAngleX; - var angleY = event.beta - this.settings.gyroscopeMinAngleY; + var angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero); + var angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero); var posX = angleX / degreesPerPixelX; var posY = angleY / degreesPerPixelY; @@ -224,12 +246,15 @@ var VanillaTilt = function () { }; VanillaTilt.prototype.getValues = function getValues() { + var x = void 0, + y = void 0; + if (this.fullPageListening) { - var x = this.event.clientX / document.body.clientWidth; - var y = this.event.clientY / document.body.clientHeight; + x = this.event.clientX / document.body.clientWidth; + y = this.event.clientY / document.body.clientHeight; } else { - var x = (this.event.clientX - this.left) / this.width; - var y = (this.event.clientY - this.top) / this.height; + x = (this.event.clientX - this.left) / this.width; + y = (this.event.clientY - this.top) / this.height; } x = Math.min(Math.max(x, 0), 1); @@ -364,10 +389,12 @@ var VanillaTilt = function () { * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%) * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise + * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc.. + * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position. */ @@ -391,7 +418,8 @@ var VanillaTilt = function () { gyroscopeMinAngleX: -45, gyroscopeMaxAngleX: 45, gyroscopeMinAngleY: -45, - gyroscopeMaxAngleY: 45 + gyroscopeMaxAngleY: 45, + gyroscopeSamples: 10 }; var newSettings = {}; diff --git a/dist/vanilla-tilt.babel.min.js b/dist/vanilla-tilt.babel.min.js index 261a3f4..aca9e19 100644 --- a/dist/vanilla-tilt.babel.min.js +++ b/dist/vanilla-tilt.babel.min.js @@ -1 +1 @@ -var VanillaTilt=function(){"use strict";var e=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},t=function(){function t(i){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(e(this,t),!(i instanceof Node))throw"Can't initialize VanillaTilt because "+i+" is not a Node.";this.width=null,this.height=null,this.left=null,this.top=null,this.transitionTimeout=null,this.updateCall=null,this.updateBind=this.update.bind(this),this.resetBind=this.reset.bind(this),this.element=i,this.settings=this.extendSettings(n),this.elementListener=this.getElementListener(),this.reverse=this.settings.reverse?-1:1,this.glare=this.isSettingTrue(this.settings.glare),this.glarePrerender=this.isSettingTrue(this.settings["glare-prerender"]),this.fullPageListening=this.isSettingTrue(this.settings["full-page-listening"]),this.gyroscope=this.isSettingTrue(this.settings.gyroscope),this.glare&&this.prepareGlare(),this.addEventListeners()}return t.prototype.isSettingTrue=function(e){return""===e||!0===e||1===e},t.prototype.getElementListener=function(){if(!this.settings||!this.settings["mouse-event-element"])return this.element;if("string"==typeof this.settings["mouse-event-element"]){var e=document.querySelector(this.settings["mouse-event-element"]);if(e)return e}return this.settings["mouse-event-element"]instanceof Node?this.settings["mouse-event-element"]:void 0},t.prototype.addEventListeners=function(){this.onMouseEnterBind=this.onMouseEnter.bind(this),this.onMouseMoveBind=this.onMouseMove.bind(this),this.onMouseLeaveBind=this.onMouseLeave.bind(this),this.onWindowResizeBind=this.onWindowResize.bind(this),this.onDeviceOrientationBind=this.onDeviceOrientation.bind(this),this.elementListener.addEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.addEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.addEventListener("mousemove",this.onMouseMoveBind):this.elementListener.addEventListener("mousemove",this.onMouseMoveBind),this.glare&&window.addEventListener("resize",this.onWindowResizeBind),this.gyroscope&&window.addEventListener("deviceorientation",this.onDeviceOrientationBind)},t.prototype.removeEventListeners=function(){this.elementListener.removeEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.removeEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.removeEventListener("mousemove",this.onMouseMoveBind):this.elementListener.removeEventListener("mousemove",this.onMouseMoveBind),this.gyroscope&&window.removeEventListener("deviceorientation",this.onDeviceOrientationBind),this.glare&&window.removeEventListener("resize",this.onWindowResizeBind)},t.prototype.destroy=function(){clearTimeout(this.transitionTimeout),null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.reset(),this.removeEventListeners(),this.element.vanillaTilt=null,delete this.element.vanillaTilt,this.element=null},t.prototype.onDeviceOrientation=function(e){if(null!==e.gamma&&null!==e.beta){this.updateElementPosition();var t=this.settings.gyroscopeMaxAngleX-this.settings.gyroscopeMinAngleX,i=this.settings.gyroscopeMaxAngleY-this.settings.gyroscopeMinAngleY,n=t/this.width,s=i/this.height,o=(e.gamma-this.settings.gyroscopeMinAngleX)/n,l=(e.beta-this.settings.gyroscopeMinAngleY)/s;null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event={clientX:o+this.left,clientY:l+this.top},this.updateCall=requestAnimationFrame(this.updateBind)}},t.prototype.onMouseEnter=function(){this.updateElementPosition(),this.element.style.willChange="transform",this.setTransition()},t.prototype.onMouseMove=function(e){null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event=e,this.updateCall=requestAnimationFrame(this.updateBind)},t.prototype.onMouseLeave=function(){this.fullPageListening||(this.setTransition(),this.settings.reset&&requestAnimationFrame(this.resetBind))},t.prototype.reset=function(){this.event={pageX:this.left+this.width/2,pageY:this.top+this.height/2},this.element&&this.element.style&&(this.element.style.transform="perspective("+this.settings.perspective+"px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)"),this.glare&&(this.glareElement.style.transform="rotate(180deg) translate(-50%, -50%)",this.glareElement.style.opacity="0")},t.prototype.getValues=function(){if(this.fullPageListening)var e=this.event.clientX/document.body.clientWidth,t=this.event.clientY/document.body.clientHeight;else e=(this.event.clientX-this.left)/this.width,t=(this.event.clientY-this.top)/this.height;return e=Math.min(Math.max(e,0),1),t=Math.min(Math.max(t,0),1),{tiltX:(this.reverse*(this.settings.max/2-e*this.settings.max)).toFixed(2),tiltY:(this.reverse*(t*this.settings.max-this.settings.max/2)).toFixed(2),percentageX:100*e,percentageY:100*t,angle:Math.atan2(this.event.clientX-(this.left+this.width/2),-(this.event.clientY-(this.top+this.height/2)))*(180/Math.PI)}},t.prototype.updateElementPosition=function(){var e=this.element.getBoundingClientRect();this.width=this.element.offsetWidth,this.height=this.element.offsetHeight,this.left=e.left,this.top=e.top},t.prototype.update=function(){var e=this.getValues();this.element.style.transform="perspective("+this.settings.perspective+"px) rotateX("+("x"===this.settings.axis?0:e.tiltY)+"deg) rotateY("+("y"===this.settings.axis?0:e.tiltX)+"deg) scale3d("+this.settings.scale+", "+this.settings.scale+", "+this.settings.scale+")",this.glare&&(this.glareElement.style.transform="rotate("+e.angle+"deg) translate(-50%, -50%)",this.glareElement.style.opacity=""+e.percentageY*this.settings["max-glare"]/100),this.element.dispatchEvent(new CustomEvent("tiltChange",{detail:e})),this.updateCall=null},t.prototype.prepareGlare=function(){if(!this.glarePrerender){var e=document.createElement("div");e.classList.add("js-tilt-glare");var t=document.createElement("div");t.classList.add("js-tilt-glare-inner"),e.appendChild(t),this.element.appendChild(e)}this.glareElementWrapper=this.element.querySelector(".js-tilt-glare"),this.glareElement=this.element.querySelector(".js-tilt-glare-inner"),this.glarePrerender||(Object.assign(this.glareElementWrapper.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden","pointer-events":"none"}),Object.assign(this.glareElement.style,{position:"absolute",top:"50%",left:"50%","pointer-events":"none","background-image":"linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)",width:2*this.element.offsetWidth+"px",height:2*this.element.offsetWidth+"px",transform:"rotate(180deg) translate(-50%, -50%)","transform-origin":"0% 0%",opacity:"0"}))},t.prototype.updateGlareSize=function(){Object.assign(this.glareElement.style,{width:""+2*this.element.offsetWidth,height:""+2*this.element.offsetWidth})},t.prototype.onWindowResize=function(){this.updateGlareSize()},t.prototype.setTransition=function(){var e=this;clearTimeout(this.transitionTimeout),this.element.style.transition=this.settings.speed+"ms "+this.settings.easing,this.glare&&(this.glareElement.style.transition="opacity "+this.settings.speed+"ms "+this.settings.easing),this.transitionTimeout=setTimeout(function(){e.element.style.transition="",e.glare&&(e.glareElement.style.transition="")},this.settings.speed)},t.prototype.extendSettings=function(e){var t={reverse:!1,max:35,perspective:1e3,easing:"cubic-bezier(.03,.98,.52,.99)",scale:1,speed:300,transition:!0,axis:null,glare:!1,"max-glare":1,"glare-prerender":!1,"full-page-listening":!1,"mouse-event-element":null,reset:!0,gyroscope:!0,gyroscopeMinAngleX:-45,gyroscopeMaxAngleX:45,gyroscopeMinAngleY:-45,gyroscopeMaxAngleY:45},i={};for(var n in t)if(n in e)i[n]=e[n];else if(this.element.hasAttribute("data-tilt-"+n)){var s=this.element.getAttribute("data-tilt-"+n);try{i[n]=JSON.parse(s)}catch(e){i[n]=s}}else i[n]=t[n];return i},t.init=function(e,i){e instanceof Node&&(e=[e]),e instanceof NodeList&&(e=[].slice.call(e)),e instanceof Array&&e.forEach(function(e){"vanillaTilt"in e||(e.vanillaTilt=new t(e,i))})},t}();return"undefined"!=typeof document&&(window.VanillaTilt=t,t.init(document.querySelectorAll("[data-tilt]"))),t}(); \ No newline at end of file +var VanillaTilt=function(){"use strict";var e=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},t=function(){function t(i){var s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(e(this,t),!(i instanceof Node))throw"Can't initialize VanillaTilt because "+i+" is not a Node.";this.width=null,this.height=null,this.left=null,this.top=null,this.gammazero=null,this.betazero=null,this.lastgammazero=null,this.lastbetazero=null,this.transitionTimeout=null,this.updateCall=null,this.updateBind=this.update.bind(this),this.resetBind=this.reset.bind(this),this.element=i,this.settings=this.extendSettings(s),this.elementListener=this.getElementListener(),this.reverse=this.settings.reverse?-1:1,this.glare=this.isSettingTrue(this.settings.glare),this.glarePrerender=this.isSettingTrue(this.settings["glare-prerender"]),this.fullPageListening=this.isSettingTrue(this.settings["full-page-listening"]),this.gyroscope=this.isSettingTrue(this.settings.gyroscope),this.gyroscopeSamples=this.settings.gyroscopeSamples,this.glare&&this.prepareGlare(),this.addEventListeners()}return t.prototype.isSettingTrue=function(e){return""===e||!0===e||1===e},t.prototype.getElementListener=function(){if(!this.settings||!this.settings["mouse-event-element"])return this.element;if("string"==typeof this.settings["mouse-event-element"]){var e=document.querySelector(this.settings["mouse-event-element"]);if(e)return e}return this.settings["mouse-event-element"]instanceof Node?this.settings["mouse-event-element"]:void 0},t.prototype.addEventListeners=function(){this.onMouseEnterBind=this.onMouseEnter.bind(this),this.onMouseMoveBind=this.onMouseMove.bind(this),this.onMouseLeaveBind=this.onMouseLeave.bind(this),this.onWindowResizeBind=this.onWindowResize.bind(this),this.onDeviceOrientationBind=this.onDeviceOrientation.bind(this),this.elementListener.addEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.addEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.addEventListener("mousemove",this.onMouseMoveBind):this.elementListener.addEventListener("mousemove",this.onMouseMoveBind),this.glare&&window.addEventListener("resize",this.onWindowResizeBind),this.gyroscope&&window.addEventListener("deviceorientation",this.onDeviceOrientationBind)},t.prototype.removeEventListeners=function(){this.elementListener.removeEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.removeEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.removeEventListener("mousemove",this.onMouseMoveBind):this.elementListener.removeEventListener("mousemove",this.onMouseMoveBind),this.gyroscope&&window.removeEventListener("deviceorientation",this.onDeviceOrientationBind),this.glare&&window.removeEventListener("resize",this.onWindowResizeBind)},t.prototype.destroy=function(){clearTimeout(this.transitionTimeout),null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.reset(),this.removeEventListeners(),this.element.vanillaTilt=null,delete this.element.vanillaTilt,this.element=null},t.prototype.onDeviceOrientation=function(e){if(null!==e.gamma&&null!==e.beta){this.updateElementPosition(),this.gyroscopeSamples>0&&(this.lastgammazero=this.gammazero,this.lastbetazero=this.betazero,null===this.gammazero?(this.gammazero=e.gamma,this.betazero=e.beta):(this.gammazero=(e.gamma+this.lastgammazero)/2,this.betazero=(e.beta+this.lastbetazero)/2),this.gyroscopeSamples-=1);var t=this.settings.gyroscopeMaxAngleX-this.settings.gyroscopeMinAngleX,i=this.settings.gyroscopeMaxAngleY-this.settings.gyroscopeMinAngleY,s=t/this.width,n=i/this.height,o=(e.gamma-(this.settings.gyroscopeMinAngleX+this.gammazero))/s,a=(e.beta-(this.settings.gyroscopeMinAngleY+this.betazero))/n;null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event={clientX:o+this.left,clientY:a+this.top},this.updateCall=requestAnimationFrame(this.updateBind)}},t.prototype.onMouseEnter=function(){this.updateElementPosition(),this.element.style.willChange="transform",this.setTransition()},t.prototype.onMouseMove=function(e){null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event=e,this.updateCall=requestAnimationFrame(this.updateBind)},t.prototype.onMouseLeave=function(){this.fullPageListening||(this.setTransition(),this.settings.reset&&requestAnimationFrame(this.resetBind))},t.prototype.reset=function(){this.event={pageX:this.left+this.width/2,pageY:this.top+this.height/2},this.element&&this.element.style&&(this.element.style.transform="perspective("+this.settings.perspective+"px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)"),this.glare&&(this.glareElement.style.transform="rotate(180deg) translate(-50%, -50%)",this.glareElement.style.opacity="0")},t.prototype.getValues=function(){var e=void 0,t=void 0;return this.fullPageListening?(e=this.event.clientX/document.body.clientWidth,t=this.event.clientY/document.body.clientHeight):(e=(this.event.clientX-this.left)/this.width,t=(this.event.clientY-this.top)/this.height),e=Math.min(Math.max(e,0),1),t=Math.min(Math.max(t,0),1),{tiltX:(this.reverse*(this.settings.max/2-e*this.settings.max)).toFixed(2),tiltY:(this.reverse*(t*this.settings.max-this.settings.max/2)).toFixed(2),percentageX:100*e,percentageY:100*t,angle:Math.atan2(this.event.clientX-(this.left+this.width/2),-(this.event.clientY-(this.top+this.height/2)))*(180/Math.PI)}},t.prototype.updateElementPosition=function(){var e=this.element.getBoundingClientRect();this.width=this.element.offsetWidth,this.height=this.element.offsetHeight,this.left=e.left,this.top=e.top},t.prototype.update=function(){var e=this.getValues();this.element.style.transform="perspective("+this.settings.perspective+"px) rotateX("+("x"===this.settings.axis?0:e.tiltY)+"deg) rotateY("+("y"===this.settings.axis?0:e.tiltX)+"deg) scale3d("+this.settings.scale+", "+this.settings.scale+", "+this.settings.scale+")",this.glare&&(this.glareElement.style.transform="rotate("+e.angle+"deg) translate(-50%, -50%)",this.glareElement.style.opacity=""+e.percentageY*this.settings["max-glare"]/100),this.element.dispatchEvent(new CustomEvent("tiltChange",{detail:e})),this.updateCall=null},t.prototype.prepareGlare=function(){if(!this.glarePrerender){var e=document.createElement("div");e.classList.add("js-tilt-glare");var t=document.createElement("div");t.classList.add("js-tilt-glare-inner"),e.appendChild(t),this.element.appendChild(e)}this.glareElementWrapper=this.element.querySelector(".js-tilt-glare"),this.glareElement=this.element.querySelector(".js-tilt-glare-inner"),this.glarePrerender||(Object.assign(this.glareElementWrapper.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden","pointer-events":"none"}),Object.assign(this.glareElement.style,{position:"absolute",top:"50%",left:"50%","pointer-events":"none","background-image":"linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)",width:2*this.element.offsetWidth+"px",height:2*this.element.offsetWidth+"px",transform:"rotate(180deg) translate(-50%, -50%)","transform-origin":"0% 0%",opacity:"0"}))},t.prototype.updateGlareSize=function(){Object.assign(this.glareElement.style,{width:""+2*this.element.offsetWidth,height:""+2*this.element.offsetWidth})},t.prototype.onWindowResize=function(){this.updateGlareSize()},t.prototype.setTransition=function(){var e=this;clearTimeout(this.transitionTimeout),this.element.style.transition=this.settings.speed+"ms "+this.settings.easing,this.glare&&(this.glareElement.style.transition="opacity "+this.settings.speed+"ms "+this.settings.easing),this.transitionTimeout=setTimeout(function(){e.element.style.transition="",e.glare&&(e.glareElement.style.transition="")},this.settings.speed)},t.prototype.extendSettings=function(e){var t={reverse:!1,max:35,perspective:1e3,easing:"cubic-bezier(.03,.98,.52,.99)",scale:1,speed:300,transition:!0,axis:null,glare:!1,"max-glare":1,"glare-prerender":!1,"full-page-listening":!1,"mouse-event-element":null,reset:!0,gyroscope:!0,gyroscopeMinAngleX:-45,gyroscopeMaxAngleX:45,gyroscopeMinAngleY:-45,gyroscopeMaxAngleY:45,gyroscopeSamples:10},i={};for(var s in t)if(s in e)i[s]=e[s];else if(this.element.hasAttribute("data-tilt-"+s)){var n=this.element.getAttribute("data-tilt-"+s);try{i[s]=JSON.parse(n)}catch(e){i[s]=n}}else i[s]=t[s];return i},t.init=function(e,i){e instanceof Node&&(e=[e]),e instanceof NodeList&&(e=[].slice.call(e)),e instanceof Array&&e.forEach(function(e){"vanillaTilt"in e||(e.vanillaTilt=new t(e,i))})},t}();return"undefined"!=typeof document&&(window.VanillaTilt=t,t.init(document.querySelectorAll("[data-tilt]"))),t}(); \ No newline at end of file diff --git a/dist/vanilla-tilt.js b/dist/vanilla-tilt.js index 05305c6..2e58903 100644 --- a/dist/vanilla-tilt.js +++ b/dist/vanilla-tilt.js @@ -5,7 +5,7 @@ var VanillaTilt = (function () { * Created by Șandor Sergiu (micku7zu) on 1/27/2017. * Original idea: https://github.com/gijsroge/tilt.js * MIT License. - * Version 1.6.1 + * Version 1.6.2 */ class VanillaTilt { @@ -18,6 +18,12 @@ class VanillaTilt { this.height = null; this.left = null; this.top = null; + + this.gammazero = null; + this.betazero = null; + this.lastgammazero = null; + this.lastbetazero = null; + this.transitionTimeout = null; this.updateCall = null; @@ -34,6 +40,7 @@ class VanillaTilt { this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]); this.fullPageListening = this.isSettingTrue(this.settings["full-page-listening"]); this.gyroscope = this.isSettingTrue(this.settings.gyroscope); + this.gyroscopeSamples = this.settings.gyroscopeSamples; if (this.glare) { this.prepareGlare(); @@ -83,9 +90,9 @@ class VanillaTilt { this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind); if (this.fullPageListening) { - window.document.addEventListener("mousemove", this.onMouseMoveBind); + window.document.addEventListener("mousemove", this.onMouseMoveBind); } else { - this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); + this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); } if (this.glare) { @@ -105,9 +112,9 @@ class VanillaTilt { this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind); if (this.fullPageListening) { - window.document.removeEventListener("mousemove", this.onMouseMoveBind); + window.document.removeEventListener("mousemove", this.onMouseMoveBind); } else { - this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); + this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); } if (this.gyroscope) { @@ -141,14 +148,29 @@ class VanillaTilt { this.updateElementPosition(); + if (this.gyroscopeSamples > 0) { + this.lastgammazero = this.gammazero; + this.lastbetazero = this.betazero; + + if (this.gammazero === null) { + this.gammazero = event.gamma; + this.betazero = event.beta; + } else { + this.gammazero = (event.gamma + this.lastgammazero) / 2; + this.betazero = (event.beta + this.lastbetazero) / 2; + } + + this.gyroscopeSamples -= 1; + } + const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX; const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY; const degreesPerPixelX = totalAngleX / this.width; const degreesPerPixelY = totalAngleY / this.height; - const angleX = event.gamma - this.settings.gyroscopeMinAngleX; - const angleY = event.beta - this.settings.gyroscopeMinAngleY; + const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero); + const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero); const posX = angleX / degreesPerPixelX; const posY = angleY / degreesPerPixelY; @@ -181,7 +203,9 @@ class VanillaTilt { } onMouseLeave() { - if (this.fullPageListening) { return; } + if (this.fullPageListening) { + return; + } this.setTransition(); @@ -210,12 +234,14 @@ class VanillaTilt { } getValues() { + let x, y; + if (this.fullPageListening) { - var x = this.event.clientX / document.body.clientWidth; - var y = this.event.clientY / document.body.clientHeight; + x = this.event.clientX / document.body.clientWidth; + y = this.event.clientY / document.body.clientHeight; } else { - var x = (this.event.clientX - this.left) / this.width; - var y = (this.event.clientY - this.top) / this.height; + x = (this.event.clientX - this.left) / this.width; + y = (this.event.clientY - this.top) / this.height; } x = Math.min(Math.max(x, 0), 1); @@ -350,10 +376,12 @@ class VanillaTilt { * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%) * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise + * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc.. + * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position. */ extendSettings(settings) { let defaultSettings = { @@ -376,6 +404,7 @@ class VanillaTilt { gyroscopeMaxAngleX: 45, gyroscopeMinAngleY: -45, gyroscopeMaxAngleY: 45, + gyroscopeSamples: 10 }; let newSettings = {}; diff --git a/dist/vanilla-tilt.min.js b/dist/vanilla-tilt.min.js index d54253c..9f0034b 100644 --- a/dist/vanilla-tilt.min.js +++ b/dist/vanilla-tilt.min.js @@ -1 +1 @@ -var VanillaTilt=function(){"use strict";class e{constructor(e,t={}){if(!(e instanceof Node))throw"Can't initialize VanillaTilt because "+e+" is not a Node.";this.width=null,this.height=null,this.left=null,this.top=null,this.transitionTimeout=null,this.updateCall=null,this.updateBind=this.update.bind(this),this.resetBind=this.reset.bind(this),this.element=e,this.settings=this.extendSettings(t),this.elementListener=this.getElementListener(),this.reverse=this.settings.reverse?-1:1,this.glare=this.isSettingTrue(this.settings.glare),this.glarePrerender=this.isSettingTrue(this.settings["glare-prerender"]),this.fullPageListening=this.isSettingTrue(this.settings["full-page-listening"]),this.gyroscope=this.isSettingTrue(this.settings.gyroscope),this.glare&&this.prepareGlare(),this.addEventListeners()}isSettingTrue(e){return""===e||!0===e||1===e}getElementListener(){if(!this.settings||!this.settings["mouse-event-element"])return this.element;if("string"==typeof this.settings["mouse-event-element"]){const e=document.querySelector(this.settings["mouse-event-element"]);if(e)return e}return this.settings["mouse-event-element"]instanceof Node?this.settings["mouse-event-element"]:void 0}addEventListeners(){this.onMouseEnterBind=this.onMouseEnter.bind(this),this.onMouseMoveBind=this.onMouseMove.bind(this),this.onMouseLeaveBind=this.onMouseLeave.bind(this),this.onWindowResizeBind=this.onWindowResize.bind(this),this.onDeviceOrientationBind=this.onDeviceOrientation.bind(this),this.elementListener.addEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.addEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.addEventListener("mousemove",this.onMouseMoveBind):this.elementListener.addEventListener("mousemove",this.onMouseMoveBind),this.glare&&window.addEventListener("resize",this.onWindowResizeBind),this.gyroscope&&window.addEventListener("deviceorientation",this.onDeviceOrientationBind)}removeEventListeners(){this.elementListener.removeEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.removeEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.removeEventListener("mousemove",this.onMouseMoveBind):this.elementListener.removeEventListener("mousemove",this.onMouseMoveBind),this.gyroscope&&window.removeEventListener("deviceorientation",this.onDeviceOrientationBind),this.glare&&window.removeEventListener("resize",this.onWindowResizeBind)}destroy(){clearTimeout(this.transitionTimeout),null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.reset(),this.removeEventListeners(),this.element.vanillaTilt=null,delete this.element.vanillaTilt,this.element=null}onDeviceOrientation(e){if(null===e.gamma||null===e.beta)return;this.updateElementPosition();const t=this.settings.gyroscopeMaxAngleX-this.settings.gyroscopeMinAngleX,i=this.settings.gyroscopeMaxAngleY-this.settings.gyroscopeMinAngleY,s=t/this.width,n=i/this.height,l=(e.gamma-this.settings.gyroscopeMinAngleX)/s,a=(e.beta-this.settings.gyroscopeMinAngleY)/n;null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event={clientX:l+this.left,clientY:a+this.top},this.updateCall=requestAnimationFrame(this.updateBind)}onMouseEnter(){this.updateElementPosition(),this.element.style.willChange="transform",this.setTransition()}onMouseMove(e){null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event=e,this.updateCall=requestAnimationFrame(this.updateBind)}onMouseLeave(){this.fullPageListening||(this.setTransition(),this.settings.reset&&requestAnimationFrame(this.resetBind))}reset(){this.event={pageX:this.left+this.width/2,pageY:this.top+this.height/2},this.element&&this.element.style&&(this.element.style.transform=`perspective(${this.settings.perspective}px) `+"rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)"),this.glare&&(this.glareElement.style.transform="rotate(180deg) translate(-50%, -50%)",this.glareElement.style.opacity="0")}getValues(){if(this.fullPageListening)var e=this.event.clientX/document.body.clientWidth,t=this.event.clientY/document.body.clientHeight;else e=(this.event.clientX-this.left)/this.width,t=(this.event.clientY-this.top)/this.height;return e=Math.min(Math.max(e,0),1),t=Math.min(Math.max(t,0),1),{tiltX:(this.reverse*(this.settings.max/2-e*this.settings.max)).toFixed(2),tiltY:(this.reverse*(t*this.settings.max-this.settings.max/2)).toFixed(2),percentageX:100*e,percentageY:100*t,angle:Math.atan2(this.event.clientX-(this.left+this.width/2),-(this.event.clientY-(this.top+this.height/2)))*(180/Math.PI)}}updateElementPosition(){let e=this.element.getBoundingClientRect();this.width=this.element.offsetWidth,this.height=this.element.offsetHeight,this.left=e.left,this.top=e.top}update(){let e=this.getValues();this.element.style.transform="perspective("+this.settings.perspective+"px) rotateX("+("x"===this.settings.axis?0:e.tiltY)+"deg) rotateY("+("y"===this.settings.axis?0:e.tiltX)+"deg) scale3d("+this.settings.scale+", "+this.settings.scale+", "+this.settings.scale+")",this.glare&&(this.glareElement.style.transform=`rotate(${e.angle}deg) translate(-50%, -50%)`,this.glareElement.style.opacity=`${e.percentageY*this.settings["max-glare"]/100}`),this.element.dispatchEvent(new CustomEvent("tiltChange",{detail:e})),this.updateCall=null}prepareGlare(){if(!this.glarePrerender){const e=document.createElement("div");e.classList.add("js-tilt-glare");const t=document.createElement("div");t.classList.add("js-tilt-glare-inner"),e.appendChild(t),this.element.appendChild(e)}this.glareElementWrapper=this.element.querySelector(".js-tilt-glare"),this.glareElement=this.element.querySelector(".js-tilt-glare-inner"),this.glarePrerender||(Object.assign(this.glareElementWrapper.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden","pointer-events":"none"}),Object.assign(this.glareElement.style,{position:"absolute",top:"50%",left:"50%","pointer-events":"none","background-image":"linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)",width:`${2*this.element.offsetWidth}px`,height:`${2*this.element.offsetWidth}px`,transform:"rotate(180deg) translate(-50%, -50%)","transform-origin":"0% 0%",opacity:"0"}))}updateGlareSize(){Object.assign(this.glareElement.style,{width:`${2*this.element.offsetWidth}`,height:`${2*this.element.offsetWidth}`})}onWindowResize(){this.updateGlareSize()}setTransition(){clearTimeout(this.transitionTimeout),this.element.style.transition=this.settings.speed+"ms "+this.settings.easing,this.glare&&(this.glareElement.style.transition=`opacity ${this.settings.speed}ms ${this.settings.easing}`),this.transitionTimeout=setTimeout(()=>{this.element.style.transition="",this.glare&&(this.glareElement.style.transition="")},this.settings.speed)}extendSettings(e){let t={reverse:!1,max:35,perspective:1e3,easing:"cubic-bezier(.03,.98,.52,.99)",scale:1,speed:300,transition:!0,axis:null,glare:!1,"max-glare":1,"glare-prerender":!1,"full-page-listening":!1,"mouse-event-element":null,reset:!0,gyroscope:!0,gyroscopeMinAngleX:-45,gyroscopeMaxAngleX:45,gyroscopeMinAngleY:-45,gyroscopeMaxAngleY:45},i={};for(var s in t)if(s in e)i[s]=e[s];else if(this.element.hasAttribute("data-tilt-"+s)){let e=this.element.getAttribute("data-tilt-"+s);try{i[s]=JSON.parse(e)}catch(t){i[s]=e}}else i[s]=t[s];return i}static init(t,i){t instanceof Node&&(t=[t]),t instanceof NodeList&&(t=[].slice.call(t)),t instanceof Array&&t.forEach(t=>{"vanillaTilt"in t||(t.vanillaTilt=new e(t,i))})}}return"undefined"!=typeof document&&(window.VanillaTilt=e,e.init(document.querySelectorAll("[data-tilt]"))),e}(); \ No newline at end of file +var VanillaTilt=function(){"use strict";class e{constructor(e,t={}){if(!(e instanceof Node))throw"Can't initialize VanillaTilt because "+e+" is not a Node.";this.width=null,this.height=null,this.left=null,this.top=null,this.gammazero=null,this.betazero=null,this.lastgammazero=null,this.lastbetazero=null,this.transitionTimeout=null,this.updateCall=null,this.updateBind=this.update.bind(this),this.resetBind=this.reset.bind(this),this.element=e,this.settings=this.extendSettings(t),this.elementListener=this.getElementListener(),this.reverse=this.settings.reverse?-1:1,this.glare=this.isSettingTrue(this.settings.glare),this.glarePrerender=this.isSettingTrue(this.settings["glare-prerender"]),this.fullPageListening=this.isSettingTrue(this.settings["full-page-listening"]),this.gyroscope=this.isSettingTrue(this.settings.gyroscope),this.gyroscopeSamples=this.settings.gyroscopeSamples,this.glare&&this.prepareGlare(),this.addEventListeners()}isSettingTrue(e){return""===e||!0===e||1===e}getElementListener(){if(!this.settings||!this.settings["mouse-event-element"])return this.element;if("string"==typeof this.settings["mouse-event-element"]){const e=document.querySelector(this.settings["mouse-event-element"]);if(e)return e}return this.settings["mouse-event-element"]instanceof Node?this.settings["mouse-event-element"]:void 0}addEventListeners(){this.onMouseEnterBind=this.onMouseEnter.bind(this),this.onMouseMoveBind=this.onMouseMove.bind(this),this.onMouseLeaveBind=this.onMouseLeave.bind(this),this.onWindowResizeBind=this.onWindowResize.bind(this),this.onDeviceOrientationBind=this.onDeviceOrientation.bind(this),this.elementListener.addEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.addEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.addEventListener("mousemove",this.onMouseMoveBind):this.elementListener.addEventListener("mousemove",this.onMouseMoveBind),this.glare&&window.addEventListener("resize",this.onWindowResizeBind),this.gyroscope&&window.addEventListener("deviceorientation",this.onDeviceOrientationBind)}removeEventListeners(){this.elementListener.removeEventListener("mouseenter",this.onMouseEnterBind),this.elementListener.removeEventListener("mouseleave",this.onMouseLeaveBind),this.fullPageListening?window.document.removeEventListener("mousemove",this.onMouseMoveBind):this.elementListener.removeEventListener("mousemove",this.onMouseMoveBind),this.gyroscope&&window.removeEventListener("deviceorientation",this.onDeviceOrientationBind),this.glare&&window.removeEventListener("resize",this.onWindowResizeBind)}destroy(){clearTimeout(this.transitionTimeout),null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.reset(),this.removeEventListeners(),this.element.vanillaTilt=null,delete this.element.vanillaTilt,this.element=null}onDeviceOrientation(e){if(null===e.gamma||null===e.beta)return;this.updateElementPosition(),this.gyroscopeSamples>0&&(this.lastgammazero=this.gammazero,this.lastbetazero=this.betazero,null===this.gammazero?(this.gammazero=e.gamma,this.betazero=e.beta):(this.gammazero=(e.gamma+this.lastgammazero)/2,this.betazero=(e.beta+this.lastbetazero)/2),this.gyroscopeSamples-=1);const t=this.settings.gyroscopeMaxAngleX-this.settings.gyroscopeMinAngleX,i=this.settings.gyroscopeMaxAngleY-this.settings.gyroscopeMinAngleY,s=t/this.width,n=i/this.height,l=(e.gamma-(this.settings.gyroscopeMinAngleX+this.gammazero))/s,a=(e.beta-(this.settings.gyroscopeMinAngleY+this.betazero))/n;null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event={clientX:l+this.left,clientY:a+this.top},this.updateCall=requestAnimationFrame(this.updateBind)}onMouseEnter(){this.updateElementPosition(),this.element.style.willChange="transform",this.setTransition()}onMouseMove(e){null!==this.updateCall&&cancelAnimationFrame(this.updateCall),this.event=e,this.updateCall=requestAnimationFrame(this.updateBind)}onMouseLeave(){this.fullPageListening||(this.setTransition(),this.settings.reset&&requestAnimationFrame(this.resetBind))}reset(){this.event={pageX:this.left+this.width/2,pageY:this.top+this.height/2},this.element&&this.element.style&&(this.element.style.transform=`perspective(${this.settings.perspective}px) `+"rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)"),this.glare&&(this.glareElement.style.transform="rotate(180deg) translate(-50%, -50%)",this.glareElement.style.opacity="0")}getValues(){let e,t;return this.fullPageListening?(e=this.event.clientX/document.body.clientWidth,t=this.event.clientY/document.body.clientHeight):(e=(this.event.clientX-this.left)/this.width,t=(this.event.clientY-this.top)/this.height),e=Math.min(Math.max(e,0),1),t=Math.min(Math.max(t,0),1),{tiltX:(this.reverse*(this.settings.max/2-e*this.settings.max)).toFixed(2),tiltY:(this.reverse*(t*this.settings.max-this.settings.max/2)).toFixed(2),percentageX:100*e,percentageY:100*t,angle:Math.atan2(this.event.clientX-(this.left+this.width/2),-(this.event.clientY-(this.top+this.height/2)))*(180/Math.PI)}}updateElementPosition(){let e=this.element.getBoundingClientRect();this.width=this.element.offsetWidth,this.height=this.element.offsetHeight,this.left=e.left,this.top=e.top}update(){let e=this.getValues();this.element.style.transform="perspective("+this.settings.perspective+"px) rotateX("+("x"===this.settings.axis?0:e.tiltY)+"deg) rotateY("+("y"===this.settings.axis?0:e.tiltX)+"deg) scale3d("+this.settings.scale+", "+this.settings.scale+", "+this.settings.scale+")",this.glare&&(this.glareElement.style.transform=`rotate(${e.angle}deg) translate(-50%, -50%)`,this.glareElement.style.opacity=`${e.percentageY*this.settings["max-glare"]/100}`),this.element.dispatchEvent(new CustomEvent("tiltChange",{detail:e})),this.updateCall=null}prepareGlare(){if(!this.glarePrerender){const e=document.createElement("div");e.classList.add("js-tilt-glare");const t=document.createElement("div");t.classList.add("js-tilt-glare-inner"),e.appendChild(t),this.element.appendChild(e)}this.glareElementWrapper=this.element.querySelector(".js-tilt-glare"),this.glareElement=this.element.querySelector(".js-tilt-glare-inner"),this.glarePrerender||(Object.assign(this.glareElementWrapper.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden","pointer-events":"none"}),Object.assign(this.glareElement.style,{position:"absolute",top:"50%",left:"50%","pointer-events":"none","background-image":"linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)",width:`${2*this.element.offsetWidth}px`,height:`${2*this.element.offsetWidth}px`,transform:"rotate(180deg) translate(-50%, -50%)","transform-origin":"0% 0%",opacity:"0"}))}updateGlareSize(){Object.assign(this.glareElement.style,{width:`${2*this.element.offsetWidth}`,height:`${2*this.element.offsetWidth}`})}onWindowResize(){this.updateGlareSize()}setTransition(){clearTimeout(this.transitionTimeout),this.element.style.transition=this.settings.speed+"ms "+this.settings.easing,this.glare&&(this.glareElement.style.transition=`opacity ${this.settings.speed}ms ${this.settings.easing}`),this.transitionTimeout=setTimeout(()=>{this.element.style.transition="",this.glare&&(this.glareElement.style.transition="")},this.settings.speed)}extendSettings(e){let t={reverse:!1,max:35,perspective:1e3,easing:"cubic-bezier(.03,.98,.52,.99)",scale:1,speed:300,transition:!0,axis:null,glare:!1,"max-glare":1,"glare-prerender":!1,"full-page-listening":!1,"mouse-event-element":null,reset:!0,gyroscope:!0,gyroscopeMinAngleX:-45,gyroscopeMaxAngleX:45,gyroscopeMinAngleY:-45,gyroscopeMaxAngleY:45,gyroscopeSamples:10},i={};for(var s in t)if(s in e)i[s]=e[s];else if(this.element.hasAttribute("data-tilt-"+s)){let e=this.element.getAttribute("data-tilt-"+s);try{i[s]=JSON.parse(e)}catch(t){i[s]=e}}else i[s]=t[s];return i}static init(t,i){t instanceof Node&&(t=[t]),t instanceof NodeList&&(t=[].slice.call(t)),t instanceof Array&&t.forEach(t=>{"vanillaTilt"in t||(t.vanillaTilt=new e(t,i))})}}return"undefined"!=typeof document&&(window.VanillaTilt=e,e.init(document.querySelectorAll("[data-tilt]"))),e}(); \ No newline at end of file diff --git a/lib/README.md b/lib/README.md index b4a3ce1..5593b8c 100644 --- a/lib/README.md +++ b/lib/README.md @@ -18,6 +18,7 @@ A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https ``` +If you want to use this library in IE, you need to include a CustomEvent polyfill: https://github.com/micku7zu/vanilla-tilt.js/issues/49#issuecomment-482711876 or maybe consider the [jQuery version](https://github.com/gijsroge/tilt.js). ### Options ```js { @@ -41,6 +42,7 @@ A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https gyroscopeMaxAngleX: 45, // This is the top limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the right border of the element; gyroscopeMinAngleY: -45, // This is the bottom limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the top border of the element; gyroscopeMaxAngleY: 45, // This is the top limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the bottom border of the element; + gyroscopeSamples: 10 // How many gyroscope moves to decide the starting position. } ``` @@ -88,10 +90,7 @@ npm install vanilla-tilt #### Typings -Installing typings using npm -``` -npm install @types/vanilla-tilt -``` +Typings were out of date in the previous version, so I've rolled a copy directly into the application for you would be Typescript junkies! ### Credits diff --git a/lib/vanilla-tilt.es2015.js b/lib/vanilla-tilt.es2015.js index 2425f1e..bbbd26d 100644 --- a/lib/vanilla-tilt.es2015.js +++ b/lib/vanilla-tilt.es2015.js @@ -2,7 +2,7 @@ * Created by Șandor Sergiu (micku7zu) on 1/27/2017. * Original idea: https://github.com/gijsroge/tilt.js * MIT License. - * Version 1.6.1 + * Version 1.6.2 */ class VanillaTilt { @@ -15,6 +15,12 @@ class VanillaTilt { this.height = null; this.left = null; this.top = null; + + this.gammazero = null; + this.betazero = null; + this.lastgammazero = null; + this.lastbetazero = null; + this.transitionTimeout = null; this.updateCall = null; @@ -31,6 +37,7 @@ class VanillaTilt { this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]); this.fullPageListening = this.isSettingTrue(this.settings["full-page-listening"]); this.gyroscope = this.isSettingTrue(this.settings.gyroscope); + this.gyroscopeSamples = this.settings.gyroscopeSamples; if (this.glare) { this.prepareGlare(); @@ -80,9 +87,9 @@ class VanillaTilt { this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind); if (this.fullPageListening) { - window.document.addEventListener("mousemove", this.onMouseMoveBind); + window.document.addEventListener("mousemove", this.onMouseMoveBind); } else { - this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); + this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); } if (this.glare) { @@ -102,9 +109,9 @@ class VanillaTilt { this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind); if (this.fullPageListening) { - window.document.removeEventListener("mousemove", this.onMouseMoveBind); + window.document.removeEventListener("mousemove", this.onMouseMoveBind); } else { - this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); + this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); } if (this.gyroscope) { @@ -138,14 +145,29 @@ class VanillaTilt { this.updateElementPosition(); + if (this.gyroscopeSamples > 0) { + this.lastgammazero = this.gammazero; + this.lastbetazero = this.betazero; + + if (this.gammazero === null) { + this.gammazero = event.gamma; + this.betazero = event.beta; + } else { + this.gammazero = (event.gamma + this.lastgammazero) / 2; + this.betazero = (event.beta + this.lastbetazero) / 2; + } + + this.gyroscopeSamples -= 1; + } + const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX; const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY; const degreesPerPixelX = totalAngleX / this.width; const degreesPerPixelY = totalAngleY / this.height; - const angleX = event.gamma - this.settings.gyroscopeMinAngleX; - const angleY = event.beta - this.settings.gyroscopeMinAngleY; + const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero); + const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero); const posX = angleX / degreesPerPixelX; const posY = angleY / degreesPerPixelY; @@ -178,7 +200,9 @@ class VanillaTilt { } onMouseLeave() { - if (this.fullPageListening) { return; } + if (this.fullPageListening) { + return; + } this.setTransition(); @@ -207,12 +231,14 @@ class VanillaTilt { } getValues() { + let x, y; + if (this.fullPageListening) { - var x = this.event.clientX / document.body.clientWidth; - var y = this.event.clientY / document.body.clientHeight; + x = this.event.clientX / document.body.clientWidth; + y = this.event.clientY / document.body.clientHeight; } else { - var x = (this.event.clientX - this.left) / this.width; - var y = (this.event.clientY - this.top) / this.height; + x = (this.event.clientX - this.left) / this.width; + y = (this.event.clientY - this.top) / this.height; } x = Math.min(Math.max(x, 0), 1); @@ -347,10 +373,12 @@ class VanillaTilt { * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%) * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise + * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc.. + * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position. */ extendSettings(settings) { let defaultSettings = { @@ -373,6 +401,7 @@ class VanillaTilt { gyroscopeMaxAngleX: 45, gyroscopeMinAngleY: -45, gyroscopeMaxAngleY: 45, + gyroscopeSamples: 10 }; let newSettings = {}; diff --git a/lib/vanilla-tilt.js b/lib/vanilla-tilt.js index c3501b2..fbe0450 100644 --- a/lib/vanilla-tilt.js +++ b/lib/vanilla-tilt.js @@ -10,7 +10,7 @@ var classCallCheck = function (instance, Constructor) { * Created by Șandor Sergiu (micku7zu) on 1/27/2017. * Original idea: https://github.com/gijsroge/tilt.js * MIT License. - * Version 1.6.1 + * Version 1.6.2 */ var VanillaTilt = function () { @@ -26,6 +26,12 @@ var VanillaTilt = function () { this.height = null; this.left = null; this.top = null; + + this.gammazero = null; + this.betazero = null; + this.lastgammazero = null; + this.lastbetazero = null; + this.transitionTimeout = null; this.updateCall = null; @@ -42,6 +48,7 @@ var VanillaTilt = function () { this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]); this.fullPageListening = this.isSettingTrue(this.settings["full-page-listening"]); this.gyroscope = this.isSettingTrue(this.settings.gyroscope); + this.gyroscopeSamples = this.settings.gyroscopeSamples; if (this.glare) { this.prepareGlare(); @@ -155,14 +162,29 @@ var VanillaTilt = function () { this.updateElementPosition(); + if (this.gyroscopeSamples > 0) { + this.lastgammazero = this.gammazero; + this.lastbetazero = this.betazero; + + if (this.gammazero === null) { + this.gammazero = event.gamma; + this.betazero = event.beta; + } else { + this.gammazero = (event.gamma + this.lastgammazero) / 2; + this.betazero = (event.beta + this.lastbetazero) / 2; + } + + this.gyroscopeSamples -= 1; + } + var totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX; var totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY; var degreesPerPixelX = totalAngleX / this.width; var degreesPerPixelY = totalAngleY / this.height; - var angleX = event.gamma - this.settings.gyroscopeMinAngleX; - var angleY = event.beta - this.settings.gyroscopeMinAngleY; + var angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero); + var angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero); var posX = angleX / degreesPerPixelX; var posY = angleY / degreesPerPixelY; @@ -223,12 +245,15 @@ var VanillaTilt = function () { }; VanillaTilt.prototype.getValues = function getValues() { + var x = void 0, + y = void 0; + if (this.fullPageListening) { - var x = this.event.clientX / document.body.clientWidth; - var y = this.event.clientY / document.body.clientHeight; + x = this.event.clientX / document.body.clientWidth; + y = this.event.clientY / document.body.clientHeight; } else { - var x = (this.event.clientX - this.left) / this.width; - var y = (this.event.clientY - this.top) / this.height; + x = (this.event.clientX - this.left) / this.width; + y = (this.event.clientY - this.top) / this.height; } x = Math.min(Math.max(x, 0), 1); @@ -363,10 +388,12 @@ var VanillaTilt = function () { * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%) * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise + * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc.. + * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position. */ @@ -390,7 +417,8 @@ var VanillaTilt = function () { gyroscopeMinAngleX: -45, gyroscopeMaxAngleX: 45, gyroscopeMinAngleY: -45, - gyroscopeMaxAngleY: 45 + gyroscopeMaxAngleY: 45, + gyroscopeSamples: 10 }; var newSettings = {}; diff --git a/package-lock.json b/package-lock.json index e7adb5a..5688861 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vanilla-tilt", - "version": "1.6.1", + "version": "1.6.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2312,9 +2312,9 @@ "dev": true }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "dev": true, "optional": true, "requires": { @@ -2331,7 +2331,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2340,7 +2341,7 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, @@ -2366,7 +2367,7 @@ } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -2405,7 +2406,7 @@ } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -2454,7 +2455,7 @@ } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, @@ -2474,12 +2475,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -2544,17 +2545,17 @@ "optional": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, "optional": true, "requires": { - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, @@ -2578,7 +2579,7 @@ "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.2.4", "bundled": true, "dev": true, "optional": true, @@ -2589,18 +2590,18 @@ } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.10.3", "bundled": true, "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", - "needle": "^2.2.0", + "needle": "^2.2.1", "nopt": "^4.0.1", "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4" @@ -2617,13 +2618,13 @@ } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.5", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.2.0", "bundled": true, "dev": true, "optional": true, @@ -2700,12 +2701,12 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -2735,18 +2736,19 @@ } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2761,7 +2763,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.6.0", "bundled": true, "dev": true, "optional": true @@ -2802,6 +2804,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2813,17 +2816,17 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } }, @@ -2834,23 +2837,25 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -2931,6 +2936,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, + "optional": true, "requires": { "is-glob": "^2.0.0" } @@ -3139,7 +3145,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -3164,7 +3170,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -3217,7 +3223,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true + "dev": true, + "optional": true }, "is-finite": { "version": "1.0.2", @@ -3242,6 +3249,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, + "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -3284,7 +3292,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true + "dev": true, + "optional": true }, "is-typedarray": { "version": "1.0.0", @@ -3589,9 +3598,9 @@ "dev": true }, "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", "dev": true, "optional": true }, @@ -3651,6 +3660,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, + "optional": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -3945,7 +3955,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -3998,7 +4008,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "dev": true, + "optional": true }, "braces": { "version": "2.3.2", @@ -4069,7 +4080,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "optional": true, @@ -4091,7 +4102,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "optional": true, @@ -4261,7 +4272,8 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "dev": true, + "optional": true }, "micromatch": { "version": "3.1.10", @@ -4394,7 +4406,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", - "dev": true + "dev": true, + "optional": true }, "repeat-element": { "version": "1.1.2", @@ -4961,7 +4974,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -5232,7 +5245,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -5368,7 +5381,7 @@ "dependencies": { "commander": { "version": "2.14.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.14.1.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", "dev": true }, diff --git a/package.json b/package.json index 84ebf4b..be84887 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vanilla-tilt", - "version": "1.6.1", + "version": "1.6.2", "description": "A smooth 3D tilt javascript library forked from Tilt.js", "main": "lib/vanilla-tilt.js", "module_es2015": "lib/vanilla-tilt.es2015.js", diff --git a/src/vanilla-tilt.js b/src/vanilla-tilt.js index b3291b1..9895644 100644 --- a/src/vanilla-tilt.js +++ b/src/vanilla-tilt.js @@ -2,7 +2,7 @@ * Created by Șandor Sergiu (micku7zu) on 1/27/2017. * Original idea: https://github.com/gijsroge/tilt.js * MIT License. - * Version 1.6.1 + * Version 1.6.2 */ export default class VanillaTilt { @@ -15,6 +15,12 @@ export default class VanillaTilt { this.height = null; this.left = null; this.top = null; + + this.gammazero = null; + this.betazero = null; + this.lastgammazero = null; + this.lastbetazero = null; + this.transitionTimeout = null; this.updateCall = null; @@ -31,6 +37,7 @@ export default class VanillaTilt { this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]); this.fullPageListening = this.isSettingTrue(this.settings["full-page-listening"]); this.gyroscope = this.isSettingTrue(this.settings.gyroscope); + this.gyroscopeSamples = this.settings.gyroscopeSamples; if (this.glare) { this.prepareGlare(); @@ -80,9 +87,9 @@ export default class VanillaTilt { this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind); if (this.fullPageListening) { - window.document.addEventListener("mousemove", this.onMouseMoveBind); + window.document.addEventListener("mousemove", this.onMouseMoveBind); } else { - this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); + this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); } if (this.glare) { @@ -102,9 +109,9 @@ export default class VanillaTilt { this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind); if (this.fullPageListening) { - window.document.removeEventListener("mousemove", this.onMouseMoveBind) + window.document.removeEventListener("mousemove", this.onMouseMoveBind) } else { - this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); + this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); } if (this.gyroscope) { @@ -138,14 +145,29 @@ export default class VanillaTilt { this.updateElementPosition(); + if (this.gyroscopeSamples > 0) { + this.lastgammazero = this.gammazero; + this.lastbetazero = this.betazero; + + if (this.gammazero === null) { + this.gammazero = event.gamma; + this.betazero = event.beta; + } else { + this.gammazero = (event.gamma + this.lastgammazero) / 2; + this.betazero = (event.beta + this.lastbetazero) / 2; + } + + this.gyroscopeSamples -= 1; + } + const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX; const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY; const degreesPerPixelX = totalAngleX / this.width; const degreesPerPixelY = totalAngleY / this.height; - const angleX = event.gamma - this.settings.gyroscopeMinAngleX; - const angleY = event.beta - this.settings.gyroscopeMinAngleY; + const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero); + const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero); const posX = angleX / degreesPerPixelX; const posY = angleY / degreesPerPixelY; @@ -178,7 +200,9 @@ export default class VanillaTilt { } onMouseLeave() { - if (this.fullPageListening) { return; } + if (this.fullPageListening) { + return; + } this.setTransition(); @@ -207,12 +231,14 @@ export default class VanillaTilt { } getValues() { + let x, y; + if (this.fullPageListening) { - var x = this.event.clientX / document.body.clientWidth; - var y = this.event.clientY / document.body.clientHeight; + x = this.event.clientX / document.body.clientWidth; + y = this.event.clientY / document.body.clientHeight; } else { - var x = (this.event.clientX - this.left) / this.width; - var y = (this.event.clientY - this.top) / this.height; + x = (this.event.clientX - this.left) / this.width; + y = (this.event.clientY - this.top) / this.height; } x = Math.min(Math.max(x, 0), 1); @@ -347,10 +373,12 @@ export default class VanillaTilt { * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%) * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise + * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc.. + * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position. */ extendSettings(settings) { let defaultSettings = { @@ -373,6 +401,7 @@ export default class VanillaTilt { gyroscopeMaxAngleX: 45, gyroscopeMinAngleY: -45, gyroscopeMaxAngleY: 45, + gyroscopeSamples: 10 }; let newSettings = {}; diff --git a/vanilla-tilt.d.ts b/vanilla-tilt.d.ts index 4167d6a..490a600 100644 --- a/vanilla-tilt.d.ts +++ b/vanilla-tilt.d.ts @@ -1,4 +1,4 @@ -// Extended Type definitions for vanilla-tilt 1.6.1 +// Extended Type definitions for vanilla-tilt 1.6.2 // Project: https://github.com/micku7zu/vanilla-tilt.js // Definitions by: Livio Brunner // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped @@ -57,6 +57,9 @@ export interface TiltOptions { */ "glare-prerender"?: boolean; + // If true, parallax effect will listen to mouse move events on the whole document, not only the selected element + "full-page-listening"?: boolean; + // Boolean to enable/disable device orientation detection, gyroscope?: boolean; @@ -83,6 +86,9 @@ export interface TiltOptions { // the mouse was on the bottom border of the element; gyroscopeMaxAngleY?: number + //How many gyroscope moves to decide the starting position. + gyroscopeSamples?: number + } export interface TiltValues {