cambios adicionales

This commit is contained in:
2025-09-25 12:27:01 -04:00
parent 5ddc52658d
commit 104051ede0
2451 changed files with 447790 additions and 2 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 geosenna
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,185 @@
![simpleParallax logo](https://simpleparallax.b-cdn.net/images/logo.png?new=new)
[![GitHub version](https://badge.fury.io/gh/geosenna%2FsimpleParallax.svg)](https://badge.fury.io/gh/geosenna%2FsimpleParallax) [![Only 32 Kb](https://badge-size.herokuapp.com/geosigno/simpleParallax.js/master/dist/simpleParallax.min.js)](https://github.com/geosigno/simpleParallax.js/blob/master/strapdown.min.js) [![](https://img.shields.io/npm/dm/simple-parallax-js)](https://www.npmjs.com/package/simple-parallax-js) [![GitHub issues](https://img.shields.io/github/issues/geosigno/simpleParallax.js.svg)](https://GitHub.com/geosigno/simpleParallax.js/issues/) [![](https://data.jsdelivr.com/v1/package/npm/simple-parallax-js/badge?style=rounded)](https://www.jsdelivr.com/package/npm/simple-parallax-js) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
# simpleParallax.js
simpleParallax.js is a very simple and tiny Vanilla JS library that adds parallax animations on any images.
Where it may be laborious to get results through other plugins, simpleParallax.js stands out for its ease and its visual rendering. The parallax effect is directly applied to image tags, there is no need to use background images. More info on the case study [here](https://medium.com/@geoffrey.signorato/case-study-create-a-parallax-effect-directly-on-img-tags-with-javascript-35b8daf81471).
Any image will fit. Try it out!
## Installation
### Old way
Simply copy/paste the below snippet just before your closing `</body>` tag :
```html
<script src="simpleParallax.js"></script>
```
or use the below CDN link provided by [jsDelivr.com](https://www.jsdelivr.com/package/npm/simple-parallax-js) :
```html
<script src="https://cdn.jsdelivr.net/npm/simple-parallax-js@5.6.1/dist/simpleParallax.min.js"></script>
```
### Via [npm/yarn](https://www.npmjs.com/package/simple-parallax-js)
You can also install it via :
```sh
#npm
npm install simple-parallax-js
#yarn
yarn add simple-parallax-js
```
and then import it as follows :
```javascript
//ES6 import
import simpleParallax from 'simple-parallax-js';
//CommonJS
const simpleParallax = require('simple-parallax-js');
```
## Initialization
Giving the following HTML :
```html
<img class="thumbnail" src="image.jpg" alt="image">
```
simply add the following JavaScript code :
```javascript
const image = document.getElementsByClassName('thumbnail');
new simpleParallax(image);
```
and voilà!
___
You can also choose to apply the parallax on multiple images :
```javascript
const images = document.querySelectorAll('img');
new simpleParallax(images);
```
Once simpleparallax has been correctly initialized, it adds the ```simple-parallax-initialized``` class on the container.
simpleParallax now works with video :
```html
<video>
<source src="video.mp4" type="video/mp4">
</video>
```
```javascript
var video = document.getElementsByTagName('video');
new simpleParallax(video);
```
## Settings
Setting | Type | Default | Hint
--- | --- | --- | ---
orientation | String | up | up - right - down - left - up left - up right - down left - down right
scale | Number | 1.3 | need to be above 1
overflow | Boolean | false |
delay | Number | 0 | the delay is in second **Watch out, sometimes this delay is causing issue on iOS devices [#47](https://github.com/geosigno/simpleParallax.js/issues/47)**
transition | String | '' | any CSS transition
customContainer | String or Node | '' |
customWrapper | String | '' | the selector of the custom wrapper
maxTransition | Number | 0 | it should be a percentage between 1 and 99
You can apply these settings with the following JS code :
```javascript
var images = document.querySelectorAll('.thumbnail');
new simpleParallax(images, {
delay: 0,
orientation: 'down',
scale: 1.3,
overflow: true,
customContainer: '.container',
customWrapper: '.wrapper'
});
```
### orientation - *String* - see [example](https://simpleparallax.com#example-orientation)
This is the orientation (or direction) of the parallax effect. Choose *up* and when scrolling down, the image will translate from the bottom to the top (so the image will translate up). When scrolling up, the image will translate from the top to the bottom. Same logic applies for all others orientations (*right*, *down*, *left*, *up left*, *up right*, *down left* or *down right*). When 2 directions are combined (for example *down right*), the image will translate diagonally.
### scale - *Number* - see [example](https://simpleparallax.com#example-scale)
The higher the scale is set, the more visible the parallax effect will be. In return, the image will lose in quality. To reduce the lossless effect, if the scale is set at 1.5 and your image is 500px width, do the simple math 500 * 1.5 = 750. So you can choose a 750px image to replace your 500px one, and don't see any quality leak. More information is available if you read the case study [here](https://medium.com/@geoffrey.signorato/case-study-create-a-parallax-effect-directly-on-img-tags-with-javascript-35b8daf81471).
### overflow - *Boolean* - see [example](https://simpleparallax.com#example-overflow)
By default, the image is scaled to apply a parallax effect without any overflow on the layout - you can check the [case study](https://medium.com/@geoffrey.signorato/case-study-create-a-parallax-effect-directly-on-img-tags-with-javascript-35b8daf81471) to have a better understanding. When *overflow* is set to true, the image will translate out of its natural flow (so it may overlap with your content).
### delay - *Number* - see [example](https://simpleparallax.com#example-delay-transition)
When a *delay* is set, the translation of the image will continue during that delay when the user stops scrolling. That gives a very nice effect. The delay is in second. **Watch out, sometimes this delay is causing issue on iOS devices [#47](https://github.com/geosigno/simpleParallax.js/issues/47)**
### transition - *String* - see [example](https://simpleparallax.com#example-delay-transition)
The *transition* setting works closely with the *delay* setting. This setting will add any CSS transition to the delay setting. For example, you can use *ease* or *ease-in-out*.
### customContainer - *String or Node*
By default, the parallax calculation is done with the body scroll percentage. In some cases, the images may be in a container that has its own scroll area, so to have an accurate calculation, the custom container should be set.
### customWrapper - *String*
In some cases, you want to use your own wrapper instead of the one created by the plugin. If you specify your custom wrapper, the plugin will add the "simpleParallax" class along with an "overflow: hidden" style.
### maxTransition - *Number* - see [example](https://simpleparallax.com#example-max-transition)
The maxTransition setting should be used to stop the parallax animation after a given percentage. By default, it translates from 0% to 100% of the user viewport. You can change it here to any percentage you want.
## Methods
### refresh
Refresh a simpleParallax instance (to recalculate all the positions) :
```javascript
var images = document.querySelectorAll('img');
var instance = new simpleParallax(images);
instance.refresh();
```
By default, the refresh method is fired at every window resize.
### destroy
Destroy a simpleParallax instance:
```javascript
var images = document.querySelectorAll('img');
var instance = new simpleParallax(images);
instance.destroy();
```
## Examples
You can find all the examples [here](https://simpleparallax.com/#examples).
## Compatibility
| IE | Edge | Firefox | Chrome | Safari | Opera | iOS Safari |
|---|---|---|---|---|---|---|
| no support | 16+ | 55+ | 58+ | 12.1+ | 45+ | 12.2+ |
Even though old browsers are not supported, the page won't crash. Simply, there will be no parallax.
If you want to support older browsers such as IE, you will need a polyfill for [cloest()](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill) and [Intersection Observer](https://github.com/w3c/IntersectionObserver/tree/master/polyfill). Please note that even with polyfills, the parallax effect will not seem fluid.
## Author
[Geoffrey Signorato](https://github.com/geosigno/)
## Contributing
Open an issue or a pull request to suggest changes or additions.

View File

@@ -0,0 +1,747 @@
/*!
* simpleParallax - simpleParallax is a simple JavaScript library that gives your website parallax animations on any images or videos,
* @date: 20-08-2020 14:0:14,
* @version: 5.6.2,
* @link: https://simpleparallax.com/
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("simpleParallax", [], factory);
else if(typeof exports === 'object')
exports["simpleParallax"] = factory();
else
root["simpleParallax"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, "default", function() { return /* binding */ simpleParallax_SimpleParallax; });
// CONCATENATED MODULE: ./src/helpers/isSupportedBrowser.js
// need closest support
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
// need Intersection Observer support
// https://github.com/w3c/IntersectionObserver/tree/master/polyfill
var isSupportedBrowser = function isSupportedBrowser() {
return Element.prototype.closest && 'IntersectionObserver' in window;
};
/* harmony default export */ var helpers_isSupportedBrowser = (isSupportedBrowser);
// CONCATENATED MODULE: ./src/helpers/viewport.js
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Viewport = /*#__PURE__*/function () {
function Viewport() {
_classCallCheck(this, Viewport);
this.positions = {
top: 0,
bottom: 0,
height: 0
};
}
_createClass(Viewport, [{
key: "setViewportTop",
value: function setViewportTop(container) {
// if this is a custom container, user the scrollTop
this.positions.top = container ? container.scrollTop : window.pageYOffset;
return this.positions;
}
}, {
key: "setViewportBottom",
value: function setViewportBottom() {
this.positions.bottom = this.positions.top + this.positions.height;
return this.positions;
}
}, {
key: "setViewportAll",
value: function setViewportAll(container) {
// if this is a custom container, user the scrollTop
this.positions.top = container ? container.scrollTop : window.pageYOffset; // if this is a custom container, get the height from the custom container itself
this.positions.height = container ? container.clientHeight : document.documentElement.clientHeight;
this.positions.bottom = this.positions.top + this.positions.height;
return this.positions;
}
}]);
return Viewport;
}();
var viewport = new Viewport();
// CONCATENATED MODULE: ./src/helpers/convertToArray.js
// check whether the element is a Node List, a HTML Collection or an array
// return an array of nodes
var convertToArray = function convertToArray(elements) {
if (NodeList.prototype.isPrototypeOf(elements) || HTMLCollection.prototype.isPrototypeOf(elements)) return Array.from(elements);
if (typeof elements === 'string' || elements instanceof String) return document.querySelectorAll(elements);
return [elements];
};
/* harmony default export */ var helpers_convertToArray = (convertToArray);
// CONCATENATED MODULE: ./src/helpers/cssTransform.js
// Detect css transform
var cssTransform = function cssTransform() {
var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' ');
var transform;
var i = 0;
while (transform === undefined) {
transform = document.createElement('div').style[prefixes[i]] !== undefined ? prefixes[i] : undefined;
i += 1;
}
return transform;
};
/* harmony default export */ var helpers_cssTransform = (cssTransform());
// CONCATENATED MODULE: ./src/helpers/isImageLoaded.js
// check if media is fully loaded
var isImageLoaded = function isImageLoaded(media) {
// if the media is a video, return true
if (media.tagName.toLowerCase() !== 'img' && media.tagName.toLowerCase() !== 'picture') {
return true;
} // check if media is set as the parameter
if (!media) {
return false;
} // check if media has been 100% loaded
if (!media.complete) {
return false;
} // check if the media is displayed
if (typeof media.naturalWidth !== 'undefined' && media.naturalWidth === 0) {
return false;
}
return true;
};
/* harmony default export */ var helpers_isImageLoaded = (isImageLoaded);
// CONCATENATED MODULE: ./src/instances/parallax.js
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function parallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function parallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function parallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) parallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) parallax_defineProperties(Constructor, staticProps); return Constructor; }
var parallax_ParallaxInstance = /*#__PURE__*/function () {
function ParallaxInstance(element, options) {
var _this = this;
parallax_classCallCheck(this, ParallaxInstance);
// set the element & settings
this.element = element;
this.elementContainer = element;
this.settings = options;
this.isVisible = true;
this.isInit = false;
this.oldTranslateValue = -1;
this.init = this.init.bind(this);
this.customWrapper = this.settings.customWrapper && this.element.closest(this.settings.customWrapper) ? this.element.closest(this.settings.customWrapper) : null; // check if images has not been loaded yet
if (helpers_isImageLoaded(element)) {
this.init();
} else {
this.element.addEventListener('load', function () {
// timeout to ensure the image is fully loaded into the DOM
setTimeout(function () {
_this.init(true);
}, 50);
});
}
}
parallax_createClass(ParallaxInstance, [{
key: "init",
value: function init(asyncInit) {
var _this2 = this;
// for some reason, <picture> are init an infinite time on windows OS
if (this.isInit) return;
if (asyncInit) {
// in case the image is lazy loaded, the rangemax should be cleared
// so it will be updated in the next getTranslateValue()
this.rangeMax = null;
} // check if element has not been already initialized with simpleParallax
if (this.element.closest('.simpleParallax')) return;
if (this.settings.overflow === false) {
// if overflow option is set to false
// wrap the element into a div to apply overflow
this.wrapElement(this.element);
} // apply the transform style on the image
this.setTransformCSS(); // get the current element offset
this.getElementOffset(); // init the Intesection Observer
this.intersectionObserver(); // get its translated value
this.getTranslateValue(); // apply its translation even if not visible for the first init
this.animate(); // if a delay has been set
if (this.settings.delay > 0) {
// apply a timeout to avoid buggy effect
setTimeout(function () {
// apply the transition style on the image
_this2.setTransitionCSS(); //add isInit class
_this2.elementContainer.classList.add('simple-parallax-initialized');
}, 10);
} else {
//add isInit class
this.elementContainer.classList.add('simple-parallax-initialized');
} // for some reason, <picture> are init an infinite time on windows OS
this.isInit = true;
} // if overflow option is set to false
// wrap the element into a .simpleParallax div and apply overflow hidden to hide the image excedant (result of the scale)
}, {
key: "wrapElement",
value: function wrapElement() {
// check is current image is in a <picture> tag
var elementToWrap = this.element.closest('picture') || this.element; // create a .simpleParallax wrapper container
// if there is a custom wrapper
// override the wrapper with it
var wrapper = this.customWrapper || document.createElement('div');
wrapper.classList.add('simpleParallax');
wrapper.style.overflow = 'hidden'; // append the image inside the new wrapper
if (!this.customWrapper) {
elementToWrap.parentNode.insertBefore(wrapper, elementToWrap);
wrapper.appendChild(elementToWrap);
}
this.elementContainer = wrapper;
} // unwrap the element from .simpleParallax wrapper container
}, {
key: "unWrapElement",
value: function unWrapElement() {
var wrapper = this.elementContainer; // if there is a custom wrapper, we jusy need to remove the class and style
if (this.customWrapper) {
wrapper.classList.remove('simpleParallax');
wrapper.style.overflow = '';
} else {
wrapper.replaceWith.apply(wrapper, _toConsumableArray(wrapper.childNodes));
}
} // apply default style on element
}, {
key: "setTransformCSS",
value: function setTransformCSS() {
if (this.settings.overflow === false) {
// if overflow option is set to false
// add scale style so the image can be translated without getting out of its container
this.element.style[helpers_cssTransform] = "scale(".concat(this.settings.scale, ")");
} // add will-change CSS property to improve perfomance
this.element.style.willChange = 'transform';
} // apply the transition effet
}, {
key: "setTransitionCSS",
value: function setTransitionCSS() {
// add transition option
this.element.style.transition = "transform ".concat(this.settings.delay, "s ").concat(this.settings.transition);
} // remove style of the element
}, {
key: "unSetStyle",
value: function unSetStyle() {
// remove will change inline style
this.element.style.willChange = '';
this.element.style[helpers_cssTransform] = '';
this.element.style.transition = '';
} // get the current element offset
}, {
key: "getElementOffset",
value: function getElementOffset() {
// get position of the element
var positions = this.elementContainer.getBoundingClientRect(); // get height
this.elementHeight = positions.height; // get offset top
this.elementTop = positions.top + viewport.positions.top; // if there is a custom container
if (this.settings.customContainer) {
// we need to do some calculation to get the position from the parent rather than the viewport
var parentPositions = this.settings.customContainer.getBoundingClientRect();
this.elementTop = positions.top - parentPositions.top + viewport.positions.top;
} // get offset bottom
this.elementBottom = this.elementHeight + this.elementTop;
} // build the Threshold array to cater change for every pixel scrolled
}, {
key: "buildThresholdList",
value: function buildThresholdList() {
var thresholds = [];
for (var i = 1.0; i <= this.elementHeight; i++) {
var ratio = i / this.elementHeight;
thresholds.push(ratio);
}
return thresholds;
} // create the Intersection Observer
}, {
key: "intersectionObserver",
value: function intersectionObserver() {
var options = {
root: null,
threshold: this.buildThresholdList()
};
this.observer = new IntersectionObserver(this.intersectionObserverCallback.bind(this), options);
this.observer.observe(this.element);
} // Intersection Observer Callback to set the element at visible state or not
}, {
key: "intersectionObserverCallback",
value: function intersectionObserverCallback(entries) {
var _this3 = this;
entries.forEach(function (entry) {
if (entry.isIntersecting) {
_this3.isVisible = true;
} else {
_this3.isVisible = false;
}
});
} // check if the current element is visible in the Viewport
// for browser that not support Intersection Observer API
}, {
key: "checkIfVisible",
value: function checkIfVisible() {
return this.elementBottom > viewport.positions.top && this.elementTop < viewport.positions.bottom;
} // calculate the range between image will be translated
}, {
key: "getRangeMax",
value: function getRangeMax() {
// get the real height of the image without scale
var elementImageHeight = this.element.clientHeight; // range is calculate with the image height by the scale
this.rangeMax = elementImageHeight * this.settings.scale - elementImageHeight;
} // get the percentage and the translate value to apply on the element
}, {
key: "getTranslateValue",
value: function getTranslateValue() {
// calculate the % position of the element comparing to the viewport
// rounding percentage to a 1 number float to avoid unn unnecessary calculation
var percentage = ((viewport.positions.bottom - this.elementTop) / ((viewport.positions.height + this.elementHeight) / 100)).toFixed(1); // sometime the percentage exceeds 100 or goes below 0
percentage = Math.min(100, Math.max(0, percentage)); // if a maxTransition has been set, we round the percentage to that number
if (this.settings.maxTransition !== 0 && percentage > this.settings.maxTransition) {
percentage = this.settings.maxTransition;
} // sometime the same percentage is returned
// if so we don't do aything
if (this.oldPercentage === percentage) {
return false;
} // if not range max is set, recalculate it
if (!this.rangeMax) {
this.getRangeMax();
} // transform this % into the max range of the element
// rounding translateValue to a non float int - as minimum pixel for browser to render is 1 (no 0.5)
this.translateValue = (percentage / 100 * this.rangeMax - this.rangeMax / 2).toFixed(0); // sometime the same translate value is returned
// if so we don't do aything
if (this.oldTranslateValue === this.translateValue) {
return false;
} // store the current percentage
this.oldPercentage = percentage;
this.oldTranslateValue = this.translateValue;
return true;
} // animate the image
}, {
key: "animate",
value: function animate() {
var translateValueY = 0;
var translateValueX = 0;
var inlineCss;
if (this.settings.orientation.includes('left') || this.settings.orientation.includes('right')) {
// if orientation option is left or right
// use horizontal axe - X axe
translateValueX = "".concat(this.settings.orientation.includes('left') ? this.translateValue * -1 : this.translateValue, "px");
}
if (this.settings.orientation.includes('up') || this.settings.orientation.includes('down')) {
// if orientation option is up or down
// use vertical axe - Y axe
translateValueY = "".concat(this.settings.orientation.includes('up') ? this.translateValue * -1 : this.translateValue, "px");
} // set style to apply to the element
if (this.settings.overflow === false) {
// if overflow option is set to false
// add the scale style
inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0) scale(").concat(this.settings.scale, ")");
} else {
inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0)");
} // add style on the element using the adequate CSS transform
this.element.style[helpers_cssTransform] = inlineCss;
}
}]);
return ParallaxInstance;
}();
/* harmony default export */ var parallax = (parallax_ParallaxInstance);
// CONCATENATED MODULE: ./src/simpleParallax.js
function simpleParallax_toConsumableArray(arr) { return simpleParallax_arrayWithoutHoles(arr) || simpleParallax_iterableToArray(arr) || simpleParallax_unsupportedIterableToArray(arr) || simpleParallax_nonIterableSpread(); }
function simpleParallax_nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function simpleParallax_iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function simpleParallax_arrayWithoutHoles(arr) { if (Array.isArray(arr)) return simpleParallax_arrayLikeToArray(arr); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || simpleParallax_unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function simpleParallax_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return simpleParallax_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return simpleParallax_arrayLikeToArray(o, minLen); }
function simpleParallax_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function simpleParallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function simpleParallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function simpleParallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) simpleParallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) simpleParallax_defineProperties(Constructor, staticProps); return Constructor; }
var isInit = false;
var instances = [];
var frameID;
var resizeID;
var simpleParallax_SimpleParallax = /*#__PURE__*/function () {
function SimpleParallax(elements, options) {
simpleParallax_classCallCheck(this, SimpleParallax);
if (!elements) return; // check if the browser support simpleParallax
if (!helpers_isSupportedBrowser()) return;
this.elements = helpers_convertToArray(elements);
this.defaults = {
delay: 0,
orientation: 'up',
scale: 1.3,
overflow: false,
transition: 'cubic-bezier(0,0,0,1)',
customContainer: '',
customWrapper: '',
maxTransition: 0
};
this.settings = Object.assign(this.defaults, options);
if (this.settings.customContainer) {
var _convertToArray = helpers_convertToArray(this.settings.customContainer);
var _convertToArray2 = _slicedToArray(_convertToArray, 1);
this.customContainer = _convertToArray2[0];
}
this.lastPosition = -1;
this.resizeIsDone = this.resizeIsDone.bind(this);
this.refresh = this.refresh.bind(this);
this.proceedRequestAnimationFrame = this.proceedRequestAnimationFrame.bind(this);
this.init();
}
simpleParallax_createClass(SimpleParallax, [{
key: "init",
value: function init() {
var _this = this;
viewport.setViewportAll(this.customContainer);
instances = [].concat(simpleParallax_toConsumableArray(this.elements.map(function (element) {
return new parallax(element, _this.settings);
})), simpleParallax_toConsumableArray(instances)); // update the instance length
// instancesLength = instances.length;
// only if this is the first simpleParallax init
if (!isInit) {
// init the frame
this.proceedRequestAnimationFrame();
window.addEventListener('resize', this.resizeIsDone);
isInit = true;
}
} // wait for resize to be completely done
}, {
key: "resizeIsDone",
value: function resizeIsDone() {
clearTimeout(resizeID);
resizeID = setTimeout(this.refresh, 200);
} // animation frame
}, {
key: "proceedRequestAnimationFrame",
value: function proceedRequestAnimationFrame() {
var _this2 = this;
// get the offset top of the viewport
viewport.setViewportTop(this.customContainer);
if (this.lastPosition === viewport.positions.top) {
// if last position if the same than the curent one
// callback the animationFrame and exit the current loop
frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame);
return;
} // get the offset bottom of the viewport
viewport.setViewportBottom(); // proceed with the current element
instances.forEach(function (instance) {
_this2.proceedElement(instance);
}); // callback the animationFrame
frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); // store the last position
this.lastPosition = viewport.positions.top;
} // proceed the element
}, {
key: "proceedElement",
value: function proceedElement(instance) {
var isVisible = false; // if this is a custom container
// use old function to check if element visible
if (this.customContainer) {
isVisible = instance.checkIfVisible(); // else, use response from Intersection Observer API Callback
} else {
isVisible = instance.isVisible;
} // if element not visible, stop it
if (!isVisible) return; // if percentage is equal to the last one, no need to continue
if (!instance.getTranslateValue()) {
return;
} // animate the image
instance.animate();
}
}, {
key: "refresh",
value: function refresh() {
// re-get all the viewport positions
viewport.setViewportAll(this.customContainer);
instances.forEach(function (instance) {
// re-get the current element offset
instance.getElementOffset(); // re-get the range if the current element
instance.getRangeMax();
}); // force the request animation frame to fired
this.lastPosition = -1;
}
}, {
key: "destroy",
value: function destroy() {
var _this3 = this;
var instancesToDestroy = []; // remove all instances that need to be destroyed from the instances array
instances = instances.filter(function (instance) {
if (_this3.elements.includes(instance.element)) {
// push instance that need to be destroyed into instancesToDestroy
instancesToDestroy.push(instance);
return false;
}
return instance;
});
instancesToDestroy.forEach(function (instance) {
// unset style
instance.unSetStyle();
if (_this3.settings.overflow === false) {
// if overflow option is set to false
// unwrap the element from .simpleParallax wrapper container
instance.unWrapElement();
}
}); // if no instances left, remove the raf and resize event = simpleParallax fully destroyed
if (!instances.length) {
// cancel the animation frame
window.cancelAnimationFrame(frameID); // detach the resize event
window.removeEventListener('resize', this.refresh); // Reset isInit
isInit = false;
}
}
}]);
return SimpleParallax;
}();
/***/ })
/******/ ])["default"];
});

File diff suppressed because one or more lines are too long