diff --git a/deploy/parallax.js b/deploy/parallax.js index 6523503..bbea85f 100644 --- a/deploy/parallax.js +++ b/deploy/parallax.js @@ -59,7 +59,9 @@ scalarX: 10.0, scalarY: 10.0, frictionX: 0.1, - frictionY: 0.1 + frictionY: 0.1, + originX: 0.5, + originY: 0.5 }; function Parallax(element, options) { @@ -164,23 +166,6 @@ } }; - Parallax.prototype.offset = function(element) { - var x = 0, y = 0, scrollLeft, scrollTop; - while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) { - if (element === document.body) { - scrollLeft = document.documentElement.scrollLeft; - scrollTop = document.documentElement.scrollTop; - } else { - scrollLeft = element.scrollLeft; - scrollTop = element.scrollTop; - } - x += element.offsetLeft - scrollLeft; - y += element.offsetTop - scrollTop; - element = element.offsetParent; - } - return {top:y, left:x}; - }; - Parallax.prototype.camelCase = function(value) { return value.replace(/-+(.)?/g, function(match, character){ return character ? character.toUpperCase() : ''; @@ -213,11 +198,12 @@ break; case '3D': if (propertySupport) { - document.body.appendChild(element); + var body = document.body || document.createElement('body'); + body.appendChild(element); element.style[jsProperty] = 'translate3d(1px,1px,1px)'; propertyValue = window.getComputedStyle(element).getPropertyValue(cssProperty); featureSupport = propertyValue !== undefined && propertyValue.length > 0 && propertyValue !== "none"; - document.body.removeChild(element); + body.removeChild(element); } break; } @@ -270,8 +256,8 @@ Parallax.prototype.updateDimensions = function() { this.ww = window.innerWidth; this.wh = window.innerHeight; - this.wcx = this.ww / 2; - this.wcy = this.wh / 2; + this.wcx = this.ww * this.originX; + this.wcy = this.wh * this.originY; }; Parallax.prototype.queueCalibration = function(delay) { @@ -459,14 +445,16 @@ // Calculate Mouse Input if (!this.orientationSupport && this.relativeInput) { - // Calculate input relative to the element. + // Extract element bounds. this.bounds = this.element.getBoundingClientRect(); this.ex = this.bounds.left; this.ey = this.bounds.top; this.ew = this.bounds.width; this.eh = this.bounds.height; - this.ecx = this.ew / 2; - this.ecy = this.eh / 2; + this.ecx = this.ew * this.originX; + this.ecy = this.eh * this.originY; + + // Calculate input relative to the element. this.ix = (event.clientX - this.ex - this.ecx) / this.ecx; this.iy = (event.clientY - this.ey - this.ecy) / this.ecy; diff --git a/deploy/parallax.min.js b/deploy/parallax.min.js index 067e5bb..7a07f59 100644 --- a/deploy/parallax.min.js +++ b/deploy/parallax.min.js @@ -1 +1 @@ -!function(t,i,e){"use strict";function s(t,i){this.element=t,this.layers=t.getElementsByClassName("layer");var e={calibrateX:this.data(this.element,"calibrate-x"),calibrateY:this.data(this.element,"calibrate-y"),invertX:this.data(this.element,"invert-x"),invertY:this.data(this.element,"invert-y"),limitX:this.data(this.element,"limit-x"),limitY:this.data(this.element,"limit-y"),scalarX:this.data(this.element,"scalar-x"),scalarY:this.data(this.element,"scalar-y"),frictionX:this.data(this.element,"friction-x"),frictionY:this.data(this.element,"friction-y")};for(var s in e)null===e[s]&&delete e[s];this.extend(this,a,i,e),this.calibrationTimer=null,this.calibrationFlag=!0,this.enabled=!1,this.depths=[],this.raf=null,this.bounds=null,this.ex=0,this.ey=0,this.ew=0,this.eh=0,this.ecx=0,this.ecy=0,this.cx=0,this.cy=0,this.ix=0,this.iy=0,this.mx=0,this.my=0,this.vx=0,this.vy=0,this.onMouseMove=this.onMouseMove.bind(this),this.onDeviceOrientation=this.onDeviceOrientation.bind(this),this.onOrientationTimer=this.onOrientationTimer.bind(this),this.onCalibrationTimer=this.onCalibrationTimer.bind(this),this.onAnimationFrame=this.onAnimationFrame.bind(this),this.onWindowResize=this.onWindowResize.bind(this),this.initialise()}var n="Parallax",o=30,a={relativeInput:!1,clipRelativeInput:!1,calibrationThreshold:100,calibrationDelay:500,supportDelay:500,calibrateX:!1,calibrateY:!0,invertX:!0,invertY:!0,limitX:!1,limitY:!1,scalarX:10,scalarY:10,frictionX:.1,frictionY:.1};s.prototype.extend=function(){if(arguments.length>1)for(var t=arguments[0],i=1,e=arguments.length;e>i;i++){var s=arguments[i];for(var n in s)t[n]=s[n]}},s.prototype.data=function(t,i){return this.deserialize(t.getAttribute("data-"+i))},s.prototype.deserialize=function(t){return"true"===t?!0:"false"===t?!1:"null"===t?null:!isNaN(parseFloat(t))&&isFinite(t)?parseFloat(t):t},s.prototype.offset=function(t){for(var e,s,n=0,o=0;t&&!isNaN(t.offsetLeft)&&!isNaN(t.offsetTop);)t===i.body?(e=i.documentElement.scrollLeft,s=i.documentElement.scrollTop):(e=t.scrollLeft,s=t.scrollTop),n+=t.offsetLeft-e,o+=t.offsetTop-s,t=t.offsetParent;return{top:o,left:n}},s.prototype.camelCase=function(t){return t.replace(/-+(.)?/g,function(t,i){return i?i.toUpperCase():""})},s.prototype.transformSupport=function(s){for(var n=i.createElement("div"),o=!1,a=null,r=!1,h=null,l=null,c=0,p=this.vendors.length;p>c;c++)if(null!==this.vendors[c]?(h=this.vendors[c][0]+"transform",l=this.vendors[c][1]+"Transform"):(h="transform",l="transform"),n.style[l]!==e){o=!0;break}switch(s){case"2D":r=o;break;case"3D":o&&(i.body.appendChild(n),n.style[l]="translate3d(1px,1px,1px)",a=t.getComputedStyle(n).getPropertyValue(h),r=a!==e&&a.length>0&&"none"!==a,i.body.removeChild(n))}return r},s.prototype.ww=null,s.prototype.wh=null,s.prototype.wcx=null,s.prototype.wcy=null,s.prototype.portrait=null,s.prototype.desktop=!navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|BB10|mobi|tablet|opera mini|nexus 7)/i),s.prototype.vendors=[null,["-webkit-","webkit"],["-moz-","Moz"],["-o-","O"],["-ms-","ms"]],s.prototype.motionSupport=!!t.DeviceMotionEvent,s.prototype.orientationSupport=!!t.DeviceOrientationEvent,s.prototype.orientationStatus=0,s.prototype.transform2DSupport=s.prototype.transformSupport("2D"),s.prototype.transform3DSupport=s.prototype.transformSupport("3D"),s.prototype.initialise=function(){this.transform3DSupport&&this.accelerate(this.element);var i=t.getComputedStyle(this.element);"static"===i.getPropertyValue("position")&&(this.element.style.position="relative");for(var e=0,s=this.layers.length;s>e;e++){var n=this.layers[e];this.transform3DSupport&&this.accelerate(n),n.style.position=e?"absolute":"relative",n.style.display="block",n.style.height="100%",n.style.width="100%",n.style.left=0,n.style.top=0,this.depths.push(this.data(n,"depth")||0)}this.updateDimensions(),this.enable(),this.queueCalibration(this.calibrationDelay)},s.prototype.updateDimensions=function(){this.ww=t.innerWidth,this.wh=t.innerHeight,this.wcx=this.ww/2,this.wcy=this.wh/2},s.prototype.queueCalibration=function(t){clearTimeout(this.calibrationTimer),this.calibrationTimer=setTimeout(this.onCalibrationTimer,t)},s.prototype.enable=function(){this.enabled||(this.enabled=!0,this.orientationSupport?(this.portrait=null,t.addEventListener("deviceorientation",this.onDeviceOrientation),setTimeout(this.onOrientationTimer,this.supportDelay)):(this.cx=0,this.cy=0,this.portrait=!1,t.addEventListener("mousemove",this.onMouseMove)),t.addEventListener("resize",this.onWindowResize),this.raf=requestAnimationFrame(this.onAnimationFrame))},s.prototype.disable=function(){this.enabled&&(this.enabled=!1,this.orientationSupport?t.removeEventListener("deviceorientation",this.onDeviceOrientation):t.removeEventListener("mousemove",this.onMouseMove),t.removeEventListener("resize",this.onWindowResize),cancelAnimationFrame(this.raf))},s.prototype.calibrate=function(t,i){this.calibrateX=t===e?this.calibrateX:t,this.calibrateY=i===e?this.calibrateY:i},s.prototype.invert=function(t,i){this.invertX=t===e?this.invertX:t,this.invertY=i===e?this.invertY:i},s.prototype.friction=function(t,i){this.frictionX=t===e?this.frictionX:t,this.frictionY=i===e?this.frictionY:i},s.prototype.scalar=function(t,i){this.scalarX=t===e?this.scalarX:t,this.scalarY=i===e?this.scalarY:i},s.prototype.limit=function(t,i){this.limitX=t===e?this.limitX:t,this.limitY=i===e?this.limitY:i},s.prototype.clamp=function(t,i,e){return t=Math.max(t,i),t=Math.min(t,e)},s.prototype.css=function(t,i,s){for(var n=null,o=0,a=this.vendors.length;a>o;o++)if(n=null!==this.vendors[o]?this.camelCase(this.vendors[o][1]+"-"+i):i,t.style[n]!==e){t.style[n]=s;break}},s.prototype.accelerate=function(t){this.css(t,"transform","translate3d(0,0,0)"),this.css(t,"transform-style","preserve-3d"),this.css(t,"backface-visibility","hidden")},s.prototype.setPosition=function(t,i,e){i+="%",e+="%",this.transform3DSupport?this.css(t,"transform","translate3d("+i+","+e+",0)"):this.transform2DSupport?this.css(t,"transform","translate("+i+","+e+")"):(t.style.left=i,t.style.top=e)},s.prototype.onOrientationTimer=function(){this.orientationSupport&&0===this.orientationStatus&&(this.disable(),this.orientationSupport=!1,this.enable())},s.prototype.onCalibrationTimer=function(){this.calibrationFlag=!0},s.prototype.onWindowResize=function(){this.updateDimensions()},s.prototype.onAnimationFrame=function(){var t=this.ix-this.cx,i=this.iy-this.cy;(Math.abs(t)>this.calibrationThreshold||Math.abs(i)>this.calibrationThreshold)&&this.queueCalibration(0),this.portrait?(this.mx=(this.calibrateX?i:this.iy)*this.scalarX,this.my=(this.calibrateY?t:this.ix)*this.scalarY):(this.mx=(this.calibrateX?t:this.ix)*this.scalarX,this.my=(this.calibrateY?i:this.iy)*this.scalarY),isNaN(parseFloat(this.limitX))||(this.mx=this.clamp(this.mx,-this.limitX,this.limitX)),isNaN(parseFloat(this.limitY))||(this.my=this.clamp(this.my,-this.limitY,this.limitY)),this.vx+=(this.mx-this.vx)*this.frictionX,this.vy+=(this.my-this.vy)*this.frictionY;for(var e=0,s=this.layers.length;s>e;e++){var n=this.layers[e],o=this.depths[e],a=this.vx*o*(this.invertX?-1:1),r=this.vy*o*(this.invertY?-1:1);this.setPosition(n,a,r)}this.raf=requestAnimationFrame(this.onAnimationFrame)},s.prototype.onDeviceOrientation=function(t){if(!this.desktop&&null!==t.beta&&null!==t.gamma){this.orientationStatus=1;var i=(t.beta||0)/o,e=(t.gamma||0)/o,s=this.wh>this.ww;this.portrait!==s&&(this.portrait=s,this.calibrationFlag=!0),this.calibrationFlag&&(this.calibrationFlag=!1,this.cx=i,this.cy=e),this.ix=i,this.iy=e}},s.prototype.onMouseMove=function(t){!this.orientationSupport&&this.relativeInput?(this.bounds=this.element.getBoundingClientRect(),this.ex=this.bounds.left,this.ey=this.bounds.top,this.ew=this.bounds.width,this.eh=this.bounds.height,this.ecx=this.ew/2,this.ecy=this.eh/2,this.ix=(t.clientX-this.ex-this.ecx)/this.ecx,this.iy=(t.clientY-this.ey-this.ecy)/this.ecy,this.clipRelativeInput&&(this.ix=Math.max(this.ix,-1),this.ix=Math.min(this.ix,1),this.iy=Math.max(this.iy,-1),this.iy=Math.min(this.iy,1))):(this.ix=(t.clientX-this.wcx)/this.wcx,this.iy=(t.clientY-this.wcy)/this.wcy)},t[n]=s}(window,document),function(){for(var t=0,i=["ms","moz","webkit","o"],e=0;e1)for(var t=arguments[0],i=1,e=arguments.length;e>i;i++){var s=arguments[i];for(var n in s)t[n]=s[n]}},s.prototype.data=function(t,i){return this.deserialize(t.getAttribute("data-"+i))},s.prototype.deserialize=function(t){return"true"===t?!0:"false"===t?!1:"null"===t?null:!isNaN(parseFloat(t))&&isFinite(t)?parseFloat(t):t},s.prototype.camelCase=function(t){return t.replace(/-+(.)?/g,function(t,i){return i?i.toUpperCase():""})},s.prototype.transformSupport=function(s){for(var n=i.createElement("div"),o=!1,a=null,r=!1,h=null,l=null,c=0,p=this.vendors.length;p>c;c++)if(null!==this.vendors[c]?(h=this.vendors[c][0]+"transform",l=this.vendors[c][1]+"Transform"):(h="transform",l="transform"),n.style[l]!==e){o=!0;break}switch(s){case"2D":r=o;break;case"3D":if(o){var m=i.body||i.createElement("body");m.appendChild(n),n.style[l]="translate3d(1px,1px,1px)",a=t.getComputedStyle(n).getPropertyValue(h),r=a!==e&&a.length>0&&"none"!==a,m.removeChild(n)}}return r},s.prototype.ww=null,s.prototype.wh=null,s.prototype.wcx=null,s.prototype.wcy=null,s.prototype.portrait=null,s.prototype.desktop=!navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|BB10|mobi|tablet|opera mini|nexus 7)/i),s.prototype.vendors=[null,["-webkit-","webkit"],["-moz-","Moz"],["-o-","O"],["-ms-","ms"]],s.prototype.motionSupport=!!t.DeviceMotionEvent,s.prototype.orientationSupport=!!t.DeviceOrientationEvent,s.prototype.orientationStatus=0,s.prototype.transform2DSupport=s.prototype.transformSupport("2D"),s.prototype.transform3DSupport=s.prototype.transformSupport("3D"),s.prototype.initialise=function(){this.transform3DSupport&&this.accelerate(this.element);var i=t.getComputedStyle(this.element);"static"===i.getPropertyValue("position")&&(this.element.style.position="relative");for(var e=0,s=this.layers.length;s>e;e++){var n=this.layers[e];this.transform3DSupport&&this.accelerate(n),n.style.position=e?"absolute":"relative",n.style.display="block",n.style.height="100%",n.style.width="100%",n.style.left=0,n.style.top=0,this.depths.push(this.data(n,"depth")||0)}this.updateDimensions(),this.enable(),this.queueCalibration(this.calibrationDelay)},s.prototype.updateDimensions=function(){this.ww=t.innerWidth,this.wh=t.innerHeight,this.wcx=this.ww*this.originX,this.wcy=this.wh*this.originY},s.prototype.queueCalibration=function(t){clearTimeout(this.calibrationTimer),this.calibrationTimer=setTimeout(this.onCalibrationTimer,t)},s.prototype.enable=function(){this.enabled||(this.enabled=!0,this.orientationSupport?(this.portrait=null,t.addEventListener("deviceorientation",this.onDeviceOrientation),setTimeout(this.onOrientationTimer,this.supportDelay)):(this.cx=0,this.cy=0,this.portrait=!1,t.addEventListener("mousemove",this.onMouseMove)),t.addEventListener("resize",this.onWindowResize),this.raf=requestAnimationFrame(this.onAnimationFrame))},s.prototype.disable=function(){this.enabled&&(this.enabled=!1,this.orientationSupport?t.removeEventListener("deviceorientation",this.onDeviceOrientation):t.removeEventListener("mousemove",this.onMouseMove),t.removeEventListener("resize",this.onWindowResize),cancelAnimationFrame(this.raf))},s.prototype.calibrate=function(t,i){this.calibrateX=t===e?this.calibrateX:t,this.calibrateY=i===e?this.calibrateY:i},s.prototype.invert=function(t,i){this.invertX=t===e?this.invertX:t,this.invertY=i===e?this.invertY:i},s.prototype.friction=function(t,i){this.frictionX=t===e?this.frictionX:t,this.frictionY=i===e?this.frictionY:i},s.prototype.scalar=function(t,i){this.scalarX=t===e?this.scalarX:t,this.scalarY=i===e?this.scalarY:i},s.prototype.limit=function(t,i){this.limitX=t===e?this.limitX:t,this.limitY=i===e?this.limitY:i},s.prototype.clamp=function(t,i,e){return t=Math.max(t,i),t=Math.min(t,e)},s.prototype.css=function(t,i,s){for(var n=null,o=0,a=this.vendors.length;a>o;o++)if(n=null!==this.vendors[o]?this.camelCase(this.vendors[o][1]+"-"+i):i,t.style[n]!==e){t.style[n]=s;break}},s.prototype.accelerate=function(t){this.css(t,"transform","translate3d(0,0,0)"),this.css(t,"transform-style","preserve-3d"),this.css(t,"backface-visibility","hidden")},s.prototype.setPosition=function(t,i,e){i+="%",e+="%",this.transform3DSupport?this.css(t,"transform","translate3d("+i+","+e+",0)"):this.transform2DSupport?this.css(t,"transform","translate("+i+","+e+")"):(t.style.left=i,t.style.top=e)},s.prototype.onOrientationTimer=function(){this.orientationSupport&&0===this.orientationStatus&&(this.disable(),this.orientationSupport=!1,this.enable())},s.prototype.onCalibrationTimer=function(){this.calibrationFlag=!0},s.prototype.onWindowResize=function(){this.updateDimensions()},s.prototype.onAnimationFrame=function(){var t=this.ix-this.cx,i=this.iy-this.cy;(Math.abs(t)>this.calibrationThreshold||Math.abs(i)>this.calibrationThreshold)&&this.queueCalibration(0),this.portrait?(this.mx=(this.calibrateX?i:this.iy)*this.scalarX,this.my=(this.calibrateY?t:this.ix)*this.scalarY):(this.mx=(this.calibrateX?t:this.ix)*this.scalarX,this.my=(this.calibrateY?i:this.iy)*this.scalarY),isNaN(parseFloat(this.limitX))||(this.mx=this.clamp(this.mx,-this.limitX,this.limitX)),isNaN(parseFloat(this.limitY))||(this.my=this.clamp(this.my,-this.limitY,this.limitY)),this.vx+=(this.mx-this.vx)*this.frictionX,this.vy+=(this.my-this.vy)*this.frictionY;for(var e=0,s=this.layers.length;s>e;e++){var n=this.layers[e],o=this.depths[e],a=this.vx*o*(this.invertX?-1:1),r=this.vy*o*(this.invertY?-1:1);this.setPosition(n,a,r)}this.raf=requestAnimationFrame(this.onAnimationFrame)},s.prototype.onDeviceOrientation=function(t){if(!this.desktop&&null!==t.beta&&null!==t.gamma){this.orientationStatus=1;var i=(t.beta||0)/o,e=(t.gamma||0)/o,s=this.wh>this.ww;this.portrait!==s&&(this.portrait=s,this.calibrationFlag=!0),this.calibrationFlag&&(this.calibrationFlag=!1,this.cx=i,this.cy=e),this.ix=i,this.iy=e}},s.prototype.onMouseMove=function(t){!this.orientationSupport&&this.relativeInput?(this.bounds=this.element.getBoundingClientRect(),this.ex=this.bounds.left,this.ey=this.bounds.top,this.ew=this.bounds.width,this.eh=this.bounds.height,this.ecx=this.ew*this.originX,this.ecy=this.eh*this.originY,this.ix=(t.clientX-this.ex-this.ecx)/this.ecx,this.iy=(t.clientY-this.ey-this.ecy)/this.ecy,this.clipRelativeInput&&(this.ix=Math.max(this.ix,-1),this.ix=Math.min(this.ix,1),this.iy=Math.max(this.iy,-1),this.iy=Math.min(this.iy,1))):(this.ix=(t.clientX-this.wcx)/this.wcx,this.iy=(t.clientY-this.wcy)/this.wcy)},t[n]=s}(window,document),function(){for(var t=0,i=["ms","moz","webkit","o"],e=0;e 0 && propertyValue !== "none"; - document.body.removeChild(element); + body.removeChild(element); } break; } @@ -239,8 +225,8 @@ Parallax.prototype.updateDimensions = function() { this.ww = window.innerWidth; this.wh = window.innerHeight; - this.wcx = this.ww / 2; - this.wcy = this.wh / 2; + this.wcx = this.ww * this.originX; + this.wcy = this.wh * this.originY; }; Parallax.prototype.queueCalibration = function(delay) { @@ -428,14 +414,16 @@ // Calculate Mouse Input if (!this.orientationSupport && this.relativeInput) { - // Calculate input relative to the element. + // Extract element bounds. this.bounds = this.element.getBoundingClientRect(); this.ex = this.bounds.left; this.ey = this.bounds.top; this.ew = this.bounds.width; this.eh = this.bounds.height; - this.ecx = this.ew / 2; - this.ecy = this.eh / 2; + this.ecx = this.ew * this.originX; + this.ecy = this.eh * this.originY; + + // Calculate input relative to the element. this.ix = (event.clientX - this.ex - this.ecx) / this.ecx; this.iy = (event.clientY - this.ey - this.ecy) / this.ecy;