From 9031da53b8b5bdffd98ae86f90fa0ab7ef66f571 Mon Sep 17 00:00:00 2001 From: Geoffrey Signorato Date: Mon, 13 Aug 2018 16:44:08 +0400 Subject: [PATCH] add overflow option --- .nvmrc | 1 + .prettierrc | 9 ++ README.md | 8 +- package.json | 14 +-- src/simpleParallax.js | 196 +++++++++++++++++--------------------- src/simpleParallax.min.js | 4 +- 6 files changed, 110 insertions(+), 122 deletions(-) create mode 100644 .nvmrc create mode 100644 .prettierrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..5b3ff95 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v10.4.1 \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..61e1d25 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "useTabs": false, + "printWidth": 300, + "tabWidth": 4, + "singleQuote": true, + "trailingComma": "none", + "jsxBracketSameLine": false, + "semi": true +} diff --git a/README.md b/README.md index 113f140..f17fbe7 100755 --- a/README.md +++ b/README.md @@ -70,14 +70,16 @@ Find below the different settings you can apply to simpleParallax: | setting | default | | |-------------|---------|---| +| delay | 0.6 | add some delay for parallax animations - in second | | orientation | up | choose the parallax orientation effect - *up*, *right*, *down* or *left* | | scale | 1.2 | choose the scale ratio - need to be above *1.0* | -| delay | 0 | add some delay for parallax animations - in second | +| overflow | true | by default, the image is scaled to apply a parallax effect without any overflow on the original image. If set to false, the image will be translated out of its orignal flow | + You can apply these settings with the following jQuery code: ```javascript -$('img').simpleParallax({scale: '1.30', orientation: 'down', delay: '0.6'}); +$('img').simpleParallax({delay: 0, orientation: 'down', scale: 1.30, overfow: true }); ``` ## 4. Methods @@ -92,7 +94,7 @@ $('.thumbnail').data('simpleParallax').destroy(); # Good to know -* The higher the scale setting is set, the more visible the parallax effect will be. In return, the image will lose in quality. +* The higher the scale setting is set, the more visible the parallax effect will be. In return, the image will lose in quality (no loss of quality if overlow option is set to false) * This plugin apply parallax on the image tag and not the background image. This gives you a lot of flexibility and can be added to any image. diff --git a/package.json b/package.json index 71ad19b..ae24785 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "simple-parallax-jquery", - "version": "2.4.0", + "version": "2.5.0", "description": "simpleParallax is a simple and lightweight jQuery plugin that gives your website parallax animations on the images", "homepage": "https://anakao-theme.com/simpleparallax/", "main": "src/simpleParallax.js", @@ -27,26 +27,28 @@ "express": "^4.15.4", "jquery": ">=1.7", "morgan": "^1.8.2", - "pug": "^2.0.0-rc.4" + "pug": "^2.0.3" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "format": "prettier --write 'src/*.js'" }, "bugs": { "url": "https://github.com/geosenna/simpleParallax/issues" }, "devDependencies": { "gulp": "github:gulpjs/gulp#4.0", - "gulp-autoprefixer": "^4.0.0", + "gulp-autoprefixer": "^5.0.0", "gulp-cssnano": "^2.1.2", "gulp-header": "^2.0.5", "gulp-jshint": "^2.0.4", "gulp-nodemon": "^2.2.1", "gulp-plumber": "^1.1.0", - "gulp-pug": "^3.3.0", + "gulp-pug": "^4.0.1", "gulp-rename": "^1.2.2", - "gulp-uglify": "^3.0.0", + "gulp-uglify": "^3.0.1", "gulp-util": "^3.0.8", + "prettier": "^1.14.2", "serve-favicon": "^2.4.4", "vinyl-ftp": "^0.6.1" } diff --git a/src/simpleParallax.js b/src/simpleParallax.js index 8bd0410..1baa8a8 100755 --- a/src/simpleParallax.js +++ b/src/simpleParallax.js @@ -7,99 +7,86 @@ * Author : Geoffrey Signorato (@geosenna) */ -;(function (factory) { - - if(typeof module === "object" && typeof module.exports === "object") { - factory(require("jquery"), window, document); +(function(factory) { + if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery'), window, document); } else { factory(jQuery, window, document); } - -}(function($, window, document, undefined) { - +})(function($, window, document, undefined) { 'use strict'; - + // Detect css transform - var cssTransform = (function(){ - var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' ') - , cssTransform - , i = 0 - while( cssTransform === undefined ){ - cssTransform = document.createElement('div').style[prefixes[i]] != undefined ? prefixes[i] : undefined - i++ + var cssTransform = (function() { + var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' '), + cssTransform, + i = 0; + while (cssTransform === undefined) { + cssTransform = document.createElement('div').style[prefixes[i]] != undefined ? prefixes[i] : undefined; + i++; } - return cssTransform + return cssTransform; })(); - + //requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel //via: https://gist.github.com/paulirish/1579671 (function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; - for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] - || window[vendors[x]+'CancelRequestAnimationFrame']; + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; } - + if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); - var id = window.setTimeout(function() { callback(currTime + timeToCall); }, - timeToCall); + var id = window.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); lastTime = currTime + timeToCall; return id; }; - + if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; - }()); + })(); var pluginName = 'simpleParallax', edge = 20, lastPosition = -1, isInitialized = false; - - function SimpleParallax ( element, options ) { + function SimpleParallax(element, options) { this.element = element; this.$element = $(this.element); this._name = pluginName; this._defaults = $.fn.simpleParallax.defaults; - this.options = $.extend( {}, this._defaults, options ); + this.options = $.extend({}, this._defaults, options); this.init(); } $.extend(SimpleParallax, { - getViewportOffsetTop: function() { - this.viewportTop = window.pageYOffset; - }, getViewportOffset: function() { - var win = $(window); - this.viewportHeight = win.outerHeight(), - this.viewportBottom = SimpleParallax.viewportTop + SimpleParallax.viewportHeight; - + (this.viewportHeight = win.outerHeight()), (this.viewportBottom = SimpleParallax.viewportTop + SimpleParallax.viewportHeight); } - }); $.extend(SimpleParallax.prototype, { - occurence: [], //initialization of elements - init: function () { - + init: function() { var plugin = this; plugin.wrapElement(); @@ -107,88 +94,90 @@ this.occurence.push(plugin); if (isInitialized) plugin.proceedLoop(); - }, //wrap the element with the .simpleParallax div and apply overflow hidden to hide the image excedant (cause of the scale) wrapElement: function() { - var plugin = this; - plugin.$elementToWrap = plugin.$element; + //wrap into a div only if overflow is set to true + if (plugin.options.overflow == true) { + plugin.$elementToWrap = plugin.$element; - if ( plugin.$element.closest('picture').length ) plugin.$elementToWrap = plugin.$element.parent('picture'); + if (plugin.$element.closest('picture').length) plugin.$elementToWrap = plugin.$element.parent('picture'); - plugin.$elementToWrap.wrap('
'); + plugin.$elementToWrap.wrap('
'); - plugin.$elementContainer = plugin.$element.closest('.simpleParallax'); + plugin.$elementContainer = plugin.$element.closest('.simpleParallax'); - //add scale option to ensure correct calculation of the rangeMax value - plugin.$element[0].style[cssTransform] = 'scale('+plugin.options.scale+')'; + //add scale option to ensure correct calculation of the rangeMax value + plugin.$element[0].style[cssTransform] = 'scale(' + plugin.options.scale + ')'; + } else { + plugin.$elementContainer = plugin.$element; + } //add will-change CSs property to improve persomance plugin.$element[0].style.willChange = 'transform'; //if animation is set, add a transition CSS if (plugin.options.delay > 0) { - plugin.$element[0].style.transition = 'transform '+plugin.options.delay+'s cubic-bezier(0,0,0,1)'; + plugin.$element[0].style.transition = 'transform ' + plugin.options.delay + 's cubic-bezier(0,0,0,1)'; } - }, //unwrap the element from the .simpleParallax div unWrapElement: function() { - var plugin = this; - plugin.$elementToWrap.unwrap('.simpleParallax'); + if (plugin.options.overflow == true) { + plugin.$elementToWrap.unwrap('.simpleParallax'); + } }, //calculate the current element offset getElementOffset: function() { - var plugin = this; plugin.elementHeight = plugin.$elementContainer[0].offsetHeight; plugin.elementTopX = plugin.$elementContainer.offset().top; plugin.elementBottomX = plugin.elementTopX + plugin.elementHeight; - }, //check if the current element is visible in the Viewport isVisible: function() { - var plugin = this; - - return plugin.elementBottomX > (SimpleParallax.viewportTop - edge) && plugin.elementTopX < (SimpleParallax.viewportBottom + edge); + return plugin.elementBottomX > SimpleParallax.viewportTop - edge && plugin.elementTopX < SimpleParallax.viewportBottom + edge; }, calculateRange: function() { - var plugin = this; //get the real height of the image with the scaling apply to it plugin.elementImageHeight = plugin.$element[0].getBoundingClientRect().height; - //range is calculate with the extra space of the scaled image comparing to its container - plugin.rangeMax = Math.abs(plugin.elementHeight - plugin.elementImageHeight); + if (plugin.options.overflow == true) { + //range is calculate with the extra space of the scaled image comparing to its container + plugin.rangeMax = Math.abs(plugin.elementHeight - plugin.elementImageHeight); + } else { + //range is calculate with the image height by the scale + plugin.rangeMax = plugin.elementImageHeight * plugin.options.scale - plugin.elementImageHeight; + } - if ( plugin.options.orientation === 'down' || plugin.options.orientation === 'right' ) { + if (plugin.options.orientation === 'down' || plugin.options.orientation === 'right') { plugin.rangeMax *= -1; } }, //calculate the percentage and the translate value to apply on the element calculate: function() { - var plugin = this, - //calculate the % position of the element comparing to the viewport - percentage = (SimpleParallax.viewportBottom - plugin.elementTopX) / ((SimpleParallax.viewportHeight + plugin.elementHeight) / 100); + //calculate the % position of the element comparing to the viewport + percentage = (SimpleParallax.viewportBottom - plugin.elementTopX) / ((SimpleParallax.viewportHeight + plugin.elementHeight) / 100); //Rounded to percentage to the nearest 0.1 to increase perfomance - percentage = Number((percentage).toFixed(1)); - + percentage = Number(percentage.toFixed(1)); + //sometime the same percentage if returned, to avoid this if the old percentage is equal to the new one, we don't do aything if (plugin.oldPercentage === percentage) return false; @@ -199,7 +188,7 @@ plugin.calculateRange(); //transform this % into the max range of the element - plugin.translateValue = ((percentage / 100) * plugin.rangeMax) - (plugin.rangeMax / 2); + plugin.translateValue = (percentage / 100) * plugin.rangeMax - plugin.rangeMax / 2; plugin.oldPercentage = percentage; @@ -207,92 +196,77 @@ }, animate: function() { - var plugin = this, inlineCss, translateValueY = plugin.translateValue, translateValueX = 0; //check the orientation to know which of X or Y axe should we use - if (plugin.options.orientation == 'left' || plugin.options.orientation == 'right' ) { + if (plugin.options.orientation == 'left' || plugin.options.orientation == 'right') { translateValueY = 0; translateValueX = plugin.translateValue; - } + } //prepare style to apply to the element - inlineCss = 'scale('+plugin.options.scale+') translate3d('+translateValueX+'px, '+translateValueY+'px, 0)'; + if (plugin.options.overflow == true) { + inlineCss = 'scale(' + plugin.options.scale + ') translate3d(' + translateValueX + 'px, ' + translateValueY + 'px, 0)'; + } else { + inlineCss = 'translate3d(' + translateValueX + 'px, ' + translateValueY + 'px, 0)'; + } //add style depending the current vendor CSS of the browser plugin.$element[0].style[cssTransform] = inlineCss; - }, proceedElement: function(elem) { - elem.getElementOffset(); if (!elem.isVisible()) return; - + if (!elem.calculate()) return; elem.animate(); - }, proceedLoop: function() { - var plugin = this; SimpleParallax.getViewportOffsetTop(); if (lastPosition === SimpleParallax.viewportTop) { - plugin.frameID = window.requestAnimationFrame(plugin.proceedLoop.bind(plugin)); - return; - } else { - lastPosition = SimpleParallax.viewportTop; - $.each( this.occurence, function(index) { + for (var i = 0; i < this.occurence.length; i++) { + if (i === 0) SimpleParallax.getViewportOffset(); + plugin.proceedElement(this.occurence[i]); + } - if (index === 0) SimpleParallax.getViewportOffset(); - - plugin.proceedElement(this.occurence[index]); - - }); - - plugin.frameID = window.requestAnimationFrame(plugin.proceedLoop.bind(plugin)); - + plugin.frameID = window.requestAnimationFrame(plugin.proceedLoop.bind(plugin)); } - }, destroy: function() { + for (var i = 0; i < this.occurence.length; i++) { + this.occurence[i].$element.removeData(); - $.each( this.occurence, function(index) { - - this.occurence[index].$element.removeData(); - - this.occurence[index].$element[0].style[cssTransform] = ''; + this.occurence[i].$element[0].style[cssTransform] = ''; - this.occurence[index].unWrapElement(); - - window.cancelAnimationFrame(this.occurence[index].frameID); - - }); - - }, + this.occurence[i].unWrapElement(); + window.cancelAnimationFrame(this.occurence[i].frameID); + } + } }); - $.fn.simpleParallax = function ( options ) { + $.fn.simpleParallax = function(options) { var length = this.length; this.each(function(index) { - if ( !$.data( this, pluginName ) ) { - if ((length - 1) == index) isInitialized = true; - $.data( this, pluginName, new SimpleParallax( this, options ) ); + if (!$.data(this, pluginName)) { + if (length - 1 == index) isInitialized = true; + $.data(this, pluginName, new SimpleParallax(this, options)); } }); @@ -300,9 +274,9 @@ }; $.fn.simpleParallax.defaults = { - 'orientation': 'up', - 'scale': 1.2, - 'delay': 0 + delay: 0.6, + orientation: 'up', + scale: 1.2, + overflow: true }; - -})); \ No newline at end of file +}); diff --git a/src/simpleParallax.min.js b/src/simpleParallax.min.js index eb3b12a..f50ef92 100755 --- a/src/simpleParallax.min.js +++ b/src/simpleParallax.min.js @@ -1,7 +1,7 @@ /** * simple-parallax-jquery - simpleParallax is a simple and lightweight jQuery plugin that gives your website parallax animations on the images - * @version v2.4.0 + * @version v2.5.0 * @link https://anakao-theme.com/simpleparallax/ * @license MIT */ -!function(e){"object"==typeof module&&"object"==typeof module.exports?e(require("jquery"),window,document):e(jQuery,window,document)}(function(i,r,o,a){"use strict";var l=function(){for(var e,t="transform webkitTransform mozTransform oTransform msTransform".split(" "),n=0;e===a;)e=o.createElement("div").style[t[n]]!=a?t[n]:a,n++;return e}();!function(){for(var a=0,e=["ms","moz","webkit","o"],t=0;t'),e.$elementContainer=e.$element.closest(".simpleParallax"),e.$element[0].style[l]="scale("+e.options.scale+")",e.$element[0].style.willChange="transform",0c.viewportTop-20&&this.elementTopX'),e.$elementContainer=e.$element.closest(".simpleParallax"),e.$element[0].style[l]="scale("+e.options.scale+")"):e.$elementContainer=e.$element,e.$element[0].style.willChange="transform",0c.viewportTop-20&&this.elementTopX