├── LICENSE ├── README.md ├── assets ├── css │ ├── local.css │ └── local.scss └── images │ ├── bg1.jpg │ └── bg2.jpg ├── babel.config.json ├── dist ├── pureParallax.js └── pureParallax.min.js ├── index.html └── src └── pureParallax.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Peter Ballasiotes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pureParallax.js 2 | 3 | pureParallax.js is an easy to use, high-performance and lightweight (only 4.8 Kb) vanilla JS plugin that adds parallax animations on backgrounds, images and elements. 4 | 5 | What stands out with pureParallax.js is it's ease of use and customization. Adding parallax effects to elements or images can be done quickly and easily, all without having to touch any JS. It can be used on elements with any type of positioning (relative, absolute, fixed, ...). It works on css background images, inline images, and any type of html element. 6 | 7 | ## How it works 8 | pureParallax.js works by adjusting the translateY or translateX value for CSS transform property of the element. For background images it adjusts the background-postition and background-size (if needed). The default starting point for the element/background parallax effect is the center of the element in the center of the element container. The starting point can be adjusted anywhere in the container. The top selectors' starting point is always the top of the page, with offset for the header (if option is set). It's pretty rad! 9 | 10 | 11 | ## Installation 12 | 13 | ### Via script link 14 | 15 | First add this script below snippet just before your closing `` tag : 16 | 17 | ```html 18 | 19 | ``` 20 | 21 | 22 | ## Initialization 23 | 24 | JS: Then start pureParallax.js by including the following JavaScript code : 25 | 26 | ```javascript 27 | pureParallax({ 28 | //-- Optional Settings --// 29 | }); 30 | ``` 31 | 32 | HTML: Add a 'data-depth' attribute to any element. (The selector can be changed in the options) 33 | 34 | ```html 35 |
36 |
Parallax Element
37 |
38 | ``` 39 | 40 | and you'll be running! 41 | 42 | ___ 43 | 44 | ## HTML 45 | 46 | ### Default Usage 47 | ```html 48 |
49 | ``` 50 | 51 | ### Background Images 52 | ```html 53 |
54 | ``` 55 | 56 | ### Top of Page Elements 57 | ```html 58 |
59 | ``` 60 | 61 | ### Top of Page background Images 62 | ```html 63 |
64 | ``` 65 | 66 | ### Change the parallax axis by adding a 'parallax-x' class 67 | ```html 68 |
69 | ``` 70 | 71 | ### Choose parent section for a specific element (selector is a class name) 72 | ```html 73 |
74 | ``` 75 | 76 | ## Options (JS) 77 | 78 | ### Change the selectors and options 79 | By default, the selector is [data-depth] attribute. The rest of the selectors are class names. 80 | 81 | ```javascript 82 | pureParallax({ 83 | selector: '[data-depth]', 84 | axisSelector: 'parallax-x', 85 | bgSelector: 'parallax-bg', 86 | bgTopSelector: 'parallax-bg-top', 87 | topSelector: 'parallax-top', 88 | btmSelector: 'parallax-btm', 89 | container: 'section', 90 | offsetHeader: true, 91 | headerId: 'hd', 92 | minWidth: 64, 93 | oldBrowserSupport: 'false' 94 | }); 95 | ``` 96 | 97 | ### Minimum Window Width 98 | 99 | Change the minimum screen width to use pureParallax, width size is in EM's (64em = 1024px) 100 | 101 | ```javascript 102 | pureParallax({ 103 | minWidth: 64 // Minimum window width in EMs 104 | }); 105 | ``` 106 | 107 | 108 | ## Examples 109 | You can find all the examples [here](http://www.pbalweb.com/pureParallax/). 110 | 111 | ## Compatibility 112 | | Edge | Firefox | Chrome | Safari | Opera | iOS Safari | 113 | |---|---|---|---|---|---| 114 | | 16+ | 55+ | 58+ | 12.1+ | 45+ | 12.2+ | 115 | 116 | Full Browser Support Edge and Safari. 117 | 118 | ## Author 119 | 120 | [Peter Ballasiotes](https://github.com/pballasiotes/) 121 | 122 | ## Contributing 123 | 124 | Open an issue or a pull request to suggest changes or additions. 125 | -------------------------------------------------------------------------------- /assets/css/local.css: -------------------------------------------------------------------------------- 1 | body, 2 | html { 3 | max-width: 100%; 4 | overflow-x: hidden; 5 | padding: 0; 6 | margin: 0 7 | } 8 | body { 9 | overflow-x: hidden; 10 | font-weight: 400; 11 | font-style: normal; 12 | font-size: 16px; 13 | line-height: 1em; 14 | font-family: Jost,sans-serif; 15 | text-align: center 16 | } 17 | #hd { 18 | position: fixed; 19 | top: 0; 20 | left: 0; 21 | right: 0; 22 | background: #fff; 23 | z-index: 100; 24 | height: 4em; 25 | display: -webkit-box; 26 | display: -webkit-flex; 27 | display: -moz-box; 28 | display: -ms-flexbox; 29 | display: flex; 30 | -webkit-box-align: center; 31 | -webkit-align-items: center; 32 | -moz-box-align: center; 33 | -ms-flex-align: center; 34 | align-items: center; 35 | -webkit-box-pack: center; 36 | -webkit-justify-content: center; 37 | -moz-box-pack: center; 38 | -ms-flex-pack: center; 39 | justify-content: center 40 | } 41 | h2 { 42 | font-size: 1.5em; 43 | margin: 0 44 | } 45 | .container { 46 | max-width: 1000px; 47 | width: 100%; 48 | margin: 0 auto; 49 | position: relative 50 | } 51 | .section { 52 | position: relative; 53 | overflow: hidden; 54 | padding: 4em 0 55 | } 56 | .section.section1 { 57 | margin-top: 4em; 58 | padding: 0 59 | } 60 | .section.section2 { 61 | height: 40em 62 | } 63 | .section:nth-of-type(1n) { 64 | background: rgba(153,153,153,.2) 65 | } 66 | .section:nth-of-type(2n) { 67 | background: rgba(153,153,153,.6) 68 | } 69 | .section:nth-of-type(3n) { 70 | background: rgba(153,153,153,.4) 71 | } 72 | .section.btm { 73 | padding: 2em 0; 74 | background: rgba(153,153,153,.8) 75 | } 76 | .cols { 77 | display: -webkit-box; 78 | display: -webkit-flex; 79 | display: -moz-box; 80 | display: -ms-flexbox; 81 | display: flex; 82 | -webkit-box-align: center; 83 | -webkit-align-items: center; 84 | -moz-box-align: center; 85 | -ms-flex-align: center; 86 | align-items: center; 87 | -webkit-box-pack: center; 88 | -webkit-justify-content: center; 89 | -moz-box-pack: center; 90 | -ms-flex-pack: center; 91 | justify-content: center; 92 | -webkit-box-align: stretch; 93 | -webkit-align-items: stretch; 94 | -moz-box-align: stretch; 95 | -ms-flex-align: stretch; 96 | align-items: stretch; 97 | gap: 2em 98 | } 99 | .col50 { 100 | width: 50%; 101 | -webkit-box-flex: 1; 102 | -webkit-flex-grow: 1; 103 | -moz-box-flex: 1; 104 | -ms-flex-positive: 1; 105 | flex-grow: 1; 106 | -webkit-flex-shrink: 1; 107 | -ms-flex-negative: 1; 108 | flex-shrink: 1; 109 | position: relative; 110 | padding: 4em 0 111 | } 112 | p { 113 | font-size: 1.3em; 114 | line-height: 1.5em 115 | } 116 | h3 { 117 | font-size: 1.3em; 118 | line-height: 1.5em; 119 | color: #fff 120 | } 121 | .bg1 { 122 | background: url(../images/bg1.jpg) center center/cover no-repeat; 123 | position: absolute; 124 | top: 0; 125 | left: 0; 126 | bottom: 0; 127 | right: 0 128 | } 129 | .bg2 { 130 | background: url(../images/bg2.jpg) center center/cover no-repeat; 131 | position: absolute; 132 | top: 0; 133 | right: 0; 134 | bottom: 0; 135 | left: 0 136 | } 137 | .box { 138 | padding: .6em; 139 | background: #222; 140 | position: relative 141 | } 142 | .box2 { 143 | display: inline-block; 144 | background: rgba(34,34,34,.9); 145 | position: absolute; 146 | top: 50%; 147 | left: 0; 148 | right: 0; 149 | -webkit-transform: translateY(-50%); 150 | transform: translateY(-50%) 151 | } 152 | .box3 { 153 | display: inline-block; 154 | position: absolute; 155 | top: -webkit-calc(50% - 5em); 156 | top: calc(50% - 5em); 157 | width: 12em; 158 | height: 12em; 159 | right: 0; 160 | z-index: 100 161 | } -------------------------------------------------------------------------------- /assets/css/local.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | max-width: 100%; 3 | overflow-x: hidden; 4 | padding: 0; 5 | margin: 0; 6 | } 7 | body { 8 | overflow-x: hidden; 9 | font-weight: normal; 10 | font-style: normal; 11 | font-size: 16px; 12 | line-height:1em; 13 | font-family: 'Jost', sans-serif; 14 | text-align: center; 15 | } 16 | 17 | #hd { 18 | position: fixed; 19 | top:0; 20 | left: 0; 21 | right: 0; 22 | background: #fff; 23 | z-index: 100; 24 | height: 4em; 25 | display: flex; 26 | align-items: center; 27 | justify-content:center; 28 | } 29 | h2 { 30 | font-size: 1.5em; 31 | margin: 0; 32 | } 33 | p { 34 | font-size: 1.1em; 35 | line-height: 1.5em; 36 | } 37 | 38 | .container { 39 | max-width: 1000px; 40 | width: 100%; 41 | margin: 0 auto; 42 | position: relative; 43 | } 44 | 45 | .section { 46 | position: relative; 47 | overflow: hidden; 48 | padding: 4em 0; 49 | 50 | &.section1 { 51 | margin-top: 4em; 52 | padding: 0; 53 | } 54 | &.section2 { 55 | height: 40em; 56 | } 57 | &:nth-of-type(1n){ 58 | background: rgba(#999,.2); 59 | } 60 | &:nth-of-type(2n){ 61 | background: rgba(#999,.6); 62 | } 63 | &:nth-of-type(3n){ 64 | background: rgba(#999,.4); 65 | } 66 | &.btm { 67 | padding: 2em 0; 68 | background: rgba(#999,.8); 69 | } 70 | } 71 | 72 | .cols { 73 | display: flex; 74 | align-items: center; 75 | justify-content:center; 76 | align-items:stretch; 77 | gap: 2em; 78 | } 79 | 80 | .col50 { 81 | width: 50%; 82 | flex-grow: 1; 83 | flex-shrink: 1; 84 | position: relative; 85 | padding: 4em 0; 86 | } 87 | p { 88 | font-size: 1.3em; 89 | line-height: 1.5em; 90 | } 91 | 92 | h3 { 93 | font-size: 1.3em; 94 | line-height: 1.5em; 95 | color: #fff; 96 | } 97 | 98 | .bg1 { 99 | background: url("../images/bg1.jpg") center center / cover no-repeat; 100 | position: absolute; 101 | top:0; 102 | left: 0; 103 | bottom: 0; 104 | right: 0; 105 | } 106 | 107 | .bg2 { 108 | background: url("../images/bg2.jpg") center center / cover no-repeat; 109 | position: absolute; 110 | top:0; 111 | right:0; 112 | bottom: 0; 113 | left: 0; 114 | } 115 | 116 | .box { 117 | padding: 0.6em; 118 | background: rgba(#222,1); 119 | position: relative; 120 | } 121 | .box2 { 122 | display: inline-block; 123 | background: rgba(#222,.9); 124 | position: absolute; 125 | top:50%; 126 | left: 0; 127 | right: 0; 128 | transform: translateY(-50%); 129 | } 130 | .box3 { 131 | display: inline-block; 132 | position: absolute; 133 | top:calc(50% - 5em); 134 | width: 12em; 135 | height: 12em; 136 | right: 0; 137 | z-index: 100; 138 | } -------------------------------------------------------------------------------- /assets/images/bg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pballasiotes/pureParallax/ed4d09a387523b2d339d7b399e78544f1ef3d385/assets/images/bg1.jpg -------------------------------------------------------------------------------- /assets/images/bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pballasiotes/pureParallax/ed4d09a387523b2d339d7b399e78544f1ef3d385/assets/images/bg2.jpg -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": "entry", 7 | "corejs": "3.22", 8 | "targets": { 9 | "chrome": "49", 10 | "edge": "17", 11 | "firefox": "68", 12 | "ie": "11", 13 | "ios": "11.3", 14 | "safari": "5.1", 15 | "samsung": "9.2" 16 | } 17 | } 18 | ] 19 | ] 20 | } -------------------------------------------------------------------------------- /dist/pureParallax.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } 4 | 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); } 5 | 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; } 6 | function pureParallax(customOptions) { 7 | // pureParallax V.1.0 -- Peter Ballasiotes -- 2022-11-26 8 | 9 | var options = { 10 | selector: '[data-depth]', 11 | axisSelector: 'parallax-x', 12 | bgSelector: 'parallax-bg', 13 | bgTopSelector: 'parallax-bg-top', 14 | topSelector: 'parallax-top', 15 | btmSelector: 'parallax-btm', 16 | container: 'section', 17 | offsetHeader: true, 18 | headerId: 'hd', 19 | minWidth: 64, 20 | oldBrowserSupport: 'false' 21 | }; 22 | for (var property in customOptions) { 23 | options[property] = customOptions[property]; 24 | } 25 | var screenWidth, hdHeight; 26 | 27 | // Load, Resize, Scroll 28 | window.addEventListener('load', onLoadFunction); 29 | function onLoadFunction() { 30 | startParallax(); 31 | onResizeFunction(); 32 | window.addEventListener('resize', onResizeFunction); 33 | window.addEventListener('scroll', startParallax); 34 | } 35 | function onResizeFunction() { 36 | screenWidth = EMsize(); 37 | startParallax(screenWidth); 38 | } 39 | 40 | // Set header height 41 | if (options.offsetHeader != false && document.getElementById(options.headerId) != null) { 42 | hdHeight = document.getElementById(options.headerId).offsetHeight; 43 | } else { 44 | hdHeight = 0; 45 | } 46 | 47 | // Returns screen size in EM 48 | function EMsize() { 49 | return (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) / parseFloat(getComputedStyle(document.querySelector('html')).fontSize); 50 | } 51 | 52 | // Checks if element is in viewport 53 | function isInViewport(e) { 54 | var offset = 0; 55 | var rect = e.getBoundingClientRect(); 56 | return rect.bottom + offset > 0 && rect.right > 0 && rect.left < (window.innerWidth || document.documentElement.clientWidth) && rect.top - offset < (window.innerHeight || document.documentElement.clientHeight); 57 | } 58 | 59 | // Find the calculated element BG size 60 | function getBgSize(e) { 61 | var computedStyle = getComputedStyle(e), 62 | image = new Image(), 63 | src = computedStyle.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2'), 64 | cssSize = computedStyle.backgroundSize, 65 | elemW = parseInt(computedStyle.width.replace('px', ''), 10), 66 | elemH = parseInt(computedStyle.height.replace('px', ''), 10), 67 | elemDim = [elemW, elemH], 68 | computedDim = [], 69 | ratio; 70 | image.src = src; 71 | ratio = image.width > image.height ? image.width / image.height : image.height / image.width; 72 | cssSize = cssSize.split(' '); 73 | computedDim[0] = cssSize[0]; 74 | computedDim[1] = cssSize.length > 1 ? cssSize[1] : 'auto'; 75 | if (cssSize[0] === 'cover') { 76 | if (elemDim[0] > elemDim[1]) { 77 | if (elemDim[0] / elemDim[1] >= ratio) { 78 | computedDim[0] = elemDim[0]; 79 | computedDim[1] = 'auto'; 80 | } else { 81 | computedDim[0] = 'auto'; 82 | computedDim[1] = elemDim[1]; 83 | } 84 | } else { 85 | computedDim[0] = 'auto'; 86 | computedDim[1] = elemDim[1]; 87 | } 88 | } else if (cssSize[0] === 'contain') { 89 | if (elemDim[0] < elemDim[1]) { 90 | computedDim[0] = elemDim[0]; 91 | computedDim[1] = 'auto'; 92 | } else { 93 | if (elemDim[0] / elemDim[1] >= ratio) { 94 | computedDim[0] = 'auto'; 95 | computedDim[1] = elemDim[1]; 96 | } else { 97 | computedDim[1] = 'auto'; 98 | computedDim[0] = elemDim[0]; 99 | } 100 | } 101 | } else { 102 | for (var i = cssSize.length; i--;) { 103 | if (cssSize[i].indexOf('px') > -1) { 104 | computedDim[i] = cssSize[i].replace('px', ''); 105 | } else if (cssSize[i].indexOf('%') > -1) { 106 | computedDim[i] = elemDim[i] * (cssSize[i].replace('%', '') / 100); 107 | } 108 | } 109 | } 110 | if (computedDim[0] === 'auto' && computedDim[1] === 'auto') { 111 | computedDim[0] = image.width; 112 | computedDim[1] = image.height; 113 | } else { 114 | ratio = computedDim[0] === 'auto' ? image.height / computedDim[1] : image.width / computedDim[0]; 115 | computedDim[0] = computedDim[0] === 'auto' ? image.width / ratio : computedDim[0]; 116 | computedDim[1] = computedDim[1] === 'auto' ? image.height / ratio : computedDim[1]; 117 | } 118 | return { 119 | width: Math.round(computedDim[0]), 120 | height: Math.round(computedDim[1]) 121 | }; 122 | } 123 | 124 | // Get element distance to top of viewport 125 | function elemtoTop(e) { 126 | return e.getBoundingClientRect().top; 127 | } 128 | 129 | // Check if in viewport and screen width 130 | function checkConditions(e) { 131 | return isInViewport(e) && screenWidth >= options.minWidth; 132 | } 133 | 134 | // Main Parallax Function 135 | function startParallax() { 136 | var elements = document.querySelectorAll(options.selector); 137 | var windowHeight = window.innerHeight || document.documentElement.clientHeight; 138 | var movement = 0; 139 | var depth, i, len, translate3d, translateBg, bgHeightSized, offsetDistTop, container, startPos, containerSelector; 140 | 141 | // Loop through elements 142 | //elements.forEach(element => { 143 | var _iterator = _createForOfIteratorHelper(elements), 144 | _step; 145 | try { 146 | for (_iterator.s(); !(_step = _iterator.n()).done;) { 147 | var element = _step.value; 148 | if (element.hasAttribute('data-container')) { 149 | containerSelector = '.' + element.getAttribute('data-container'); 150 | } else { 151 | containerSelector = '.' + options.container; 152 | } 153 | if (element.closest(containerSelector)) { 154 | container = element.closest(containerSelector); 155 | } else { 156 | container = element.parentElement; 157 | } 158 | if (element.hasAttribute('data-start-position')) { 159 | startPos = element.getAttribute('data-start-position'); 160 | } else { 161 | startPos = .5; 162 | } 163 | var computedStyle = getComputedStyle(element); 164 | var outerHeightBg = element.offsetHeight; 165 | outerHeightBg -= parseFloat(computedStyle.borderTop) + parseFloat(computedStyle.borderBottom); 166 | offsetDistTop = window.pageYOffset; 167 | depth = element.getAttribute('data-depth'); 168 | 169 | // Check if element container visible and for screen width 170 | if (checkConditions(container)) { 171 | // -- BG Elements 172 | if (element.classList.contains(options.bgSelector) || element.classList.contains(options.bgTopSelector) && checkConditions(element)) { 173 | var bgSized = getBgSize(element); 174 | var whRatio = (bgSized.width / bgSized.height).toFixed(3); 175 | if (element.classList.contains(options.bgTopSelector)) { 176 | movement = offsetDistTop * depth; 177 | translateBg = '50% ' + Math.round(movement) + 'px'; 178 | element.style.backgroundPosition = translateBg; 179 | } else { 180 | movement = -(elemtoTop(element) * depth - hdHeight * depth); 181 | translateBg = '50% ' + Math.round(movement) + 'px'; 182 | element.style.backgroundPosition = translateBg; 183 | bgHeightSized = Math.round(outerHeightBg + (windowHeight * depth - outerHeightBg * depth)); 184 | var bgWidthSized = bgHeightSized * whRatio; 185 | if (bgWidthSized < container.offsetWidth) { 186 | element.style.backgroundSize = 'cover'; 187 | } else { 188 | element.style.backgroundSize = 'auto ' + bgHeightSized + 'px'; 189 | } 190 | } 191 | } 192 | 193 | // -- Not BG Elements 194 | else { 195 | // Bottom Elements 196 | if (element.classList.contains(options.btmSelector)) { 197 | movement = -(document.body.scrollHeight - window.innerHeight - window.scrollY) * depth; 198 | } 199 | // Default Elements 200 | else { 201 | if (element.classList.contains(options.topSelector)) { 202 | movement = offsetDistTop * depth; 203 | } else { 204 | var outerToTop = -(elemtoTop(container) - hdHeight); 205 | var outerHeightWindow = (windowHeight - hdHeight - container.offsetHeight) * startPos; 206 | movement = (outerToTop + outerHeightWindow) * depth; 207 | } 208 | } 209 | 210 | // Movement Axis 211 | if (element.classList.contains(options.axisSelector)) { 212 | translate3d = 'translate3d(' + Math.round(movement) + 'px, 0, 0)'; 213 | } else { 214 | translate3d = 'translate3d(0, ' + Math.round(movement) + 'px, 0)'; 215 | } 216 | 217 | // -- Apply Movement 218 | if (options.oldBrowserSupport == 'true') { 219 | element.style['-webkit-transform'] = translate3d; 220 | element.style['-moz-transform'] = translate3d; 221 | element.style['-ms-transform'] = translate3d; 222 | element.style['-o-transform'] = translate3d; 223 | element.style.transform = translate3d; 224 | } else { 225 | element.style['-webkit-transform'] = translate3d; 226 | element.style.transform = translate3d; 227 | } 228 | } 229 | } 230 | 231 | // If not visible or small screen widths 232 | else { 233 | if (element.classList.contains(options.bgSelector) || element.classList.contains(options.bgTopSelector) && checkConditions(element)) { 234 | element.style.backgroundPosition = '50% 50%'; 235 | element.style.backgroundSize = 'cover'; 236 | } else { 237 | element.style.transform = 'translate3d(0,0,0)'; 238 | } 239 | } 240 | } 241 | } catch (err) { 242 | _iterator.e(err); 243 | } finally { 244 | _iterator.f(); 245 | } 246 | } 247 | } -------------------------------------------------------------------------------- /dist/pureParallax.min.js: -------------------------------------------------------------------------------- 1 | "use strict";function _createForOfIteratorHelper(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=_unsupportedIterableToArray(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var o=0,n=function(){};return{s:n,n:function(){return o>=t.length?{done:!0}:{done:!1,value:t[o++]}},e:function(t){throw t},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,i=!0,l=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return i=t.done,t},e:function(t){l=!0,a=t},f:function(){try{i||null==r.return||r.return()}finally{if(l)throw a}}}}function _unsupportedIterableToArray(t,e){if(t){if("string"==typeof t)return _arrayLikeToArray(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(t,e):void 0}}function _arrayLikeToArray(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,o=new Array(e);ro.height?o.width/o.height:o.height/o.width,a=a.split(" "),l[0]=a[0],l[1]=a.length>1?a[1]:"auto","cover"===a[0])i[0]>i[1]&&i[0]/i[1]>=e?(l[0]=i[0],l[1]="auto"):(l[0]="auto",l[1]=i[1]);else if("contain"===a[0])i[0]=e?(l[0]="auto",l[1]=i[1]):(l[1]="auto",l[0]=i[0]);else for(var s=a.length;s--;)a[s].indexOf("px")>-1?l[s]=a[s].replace("px",""):a[s].indexOf("%")>-1&&(l[s]=i[s]*(a[s].replace("%","")/100));return"auto"===l[0]&&"auto"===l[1]?(l[0]=o.width,l[1]=o.height):(e="auto"===l[0]?o.height/l[1]:o.width/l[0],l[0]="auto"===l[0]?o.width/e:l[0],l[1]="auto"===l[1]?o.height/e:l[1]),{width:Math.round(l[0]),height:Math.round(l[1])}}function l(t){return t.getBoundingClientRect().top}function s(t){return function(t){var e=t.getBoundingClientRect();return e.bottom+0>0&&e.right>0&&e.left<(window.innerWidth||document.documentElement.clientWidth)&&e.top-0<(window.innerHeight||document.documentElement.clientHeight)}(t)&&e>=o.minWidth}function c(){var t,e,n,a,c,d,u,f,h,p=document.querySelectorAll(o.selector),g=window.innerHeight||document.documentElement.clientHeight,m=0,y=_createForOfIteratorHelper(p);try{for(y.s();!(h=y.n()).done;){var b=h.value;f=b.hasAttribute("data-container")?"."+b.getAttribute("data-container"):"."+o.container,d=b.closest(f)?b.closest(f):b.parentElement,u=b.hasAttribute("data-start-position")?b.getAttribute("data-start-position"):.5;var w=getComputedStyle(b),S=b.offsetHeight;if(S-=parseFloat(w.borderTop)+parseFloat(w.borderBottom),c=window.pageYOffset,t=b.getAttribute("data-depth"),s(d))if(b.classList.contains(o.bgSelector)||b.classList.contains(o.bgTopSelector)&&s(b)){var v=i(b),x=(v.width/v.height).toFixed(3);if(b.classList.contains(o.bgTopSelector))m=c*t,n="50% "+Math.round(m)+"px",b.style.backgroundPosition=n;else m=-(l(b)*t-r*t),n="50% "+Math.round(m)+"px",b.style.backgroundPosition=n,(a=Math.round(S+(g*t-S*t)))*x 2 | 3 | 4 | pureParallax.js Demo Page 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

14 | pureParallax.js Demo Page 15 |

16 |
17 | 18 | 19 |
20 |
21 |
22 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

23 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

24 |
25 |

Example: parallax-top data-depth=".3"

26 |
27 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

28 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

29 |
30 |
31 |
32 |
33 |
34 |

Example: parallax-bg-top data-depth=".5"

35 |
36 |
37 |
38 |
39 | 40 | 41 |
42 |
43 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

44 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

45 |
46 |

Example: data-depth=".4"

47 |
48 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

49 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

50 |
51 |
52 | 53 | 54 |
55 |
56 |
57 |

Example: parallax-bg data-depth=".6"

58 |
59 |
60 |
61 | 62 | 63 |
64 |
65 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

66 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

67 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

68 |
69 |

Example: parallax-x data-depth=".3"

70 |
71 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

72 |
73 |

Example: parallax-x data-depth="-.3"

74 |
75 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

76 |
77 |
78 | 79 | 80 |
81 |
82 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

83 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facirem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

84 |
85 |

Example: data-depth="-.3" data-start-position="0" data-container="section"

86 |
87 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

88 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facirem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

89 |
90 |
91 | 92 | 93 |
94 |
95 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

96 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facirem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

97 |
98 |

Example: data-depth=".3" data-start-position="1" data-container="section"

99 |
100 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

101 |
102 |
103 | 104 | 105 |
106 |
107 |

Example (position absolute): data-depth=".5"

108 |
109 |
110 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

111 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facirem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

112 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

113 |
114 |
115 | 116 | 117 |
118 |
119 |

Example (position absolute): data-depth=".3" data-start-position=".8"

120 |
121 |
122 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

123 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facirem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

124 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida. Risus commodo viverra maecenas accumsan lacus vel facilisis.

125 |
126 |
127 | 128 | 129 |
130 |
131 |
132 |

Example: parallax-btm data-depth=".5"

133 |
134 |
135 |
136 | 137 | 138 | 139 | 140 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /src/pureParallax.js: -------------------------------------------------------------------------------- 1 | 2 | function pureParallax(customOptions) { 3 | // pureParallax V.1.0 -- Peter Ballasiotes -- 2022-11-26 4 | 5 | let options = { 6 | selector: '[data-depth]', 7 | axisSelector: 'parallax-x', 8 | bgSelector: 'parallax-bg', 9 | bgTopSelector: 'parallax-bg-top', 10 | topSelector: 'parallax-top', 11 | btmSelector: 'parallax-btm', 12 | container: 'section', 13 | offsetHeader: true, 14 | headerId: 'hd', 15 | minWidth: 64, 16 | oldBrowserSupport: 'false' 17 | } 18 | for (const property in customOptions) { 19 | options[property] = customOptions[property]; 20 | } 21 | 22 | let screenWidth, hdHeight; 23 | 24 | 25 | // Load, Resize, Scroll 26 | window.addEventListener('load', onLoadFunction); 27 | 28 | function onLoadFunction() { 29 | startParallax(); 30 | onResizeFunction(); 31 | window.addEventListener('resize', onResizeFunction); 32 | window.addEventListener('scroll', startParallax); 33 | } 34 | 35 | function onResizeFunction() { 36 | screenWidth = EMsize(); 37 | startParallax(screenWidth); 38 | } 39 | 40 | 41 | // Set header height 42 | if ( options.offsetHeader != false && document.getElementById(options.headerId) != null) { 43 | hdHeight = document.getElementById(options.headerId).offsetHeight; 44 | } else { 45 | hdHeight = 0; 46 | } 47 | 48 | 49 | // Returns screen size in EM 50 | function EMsize() { 51 | return (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) / parseFloat(getComputedStyle(document.querySelector('html')).fontSize); 52 | } 53 | 54 | 55 | // Checks if element is in viewport 56 | function isInViewport(e) { 57 | const offset = 0; 58 | const rect = e.getBoundingClientRect(); 59 | return (rect.bottom + offset) > 0 && 60 | rect.right > 0 && 61 | rect.left < (window.innerWidth || document.documentElement.clientWidth) && 62 | (rect.top - offset) < (window.innerHeight || document.documentElement.clientHeight); 63 | } 64 | 65 | 66 | // Find the calculated element BG size 67 | function getBgSize(e) { 68 | let computedStyle = getComputedStyle(e), 69 | image = new Image(), 70 | src = computedStyle.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2'), 71 | cssSize = computedStyle.backgroundSize, 72 | elemW = parseInt(computedStyle.width.replace('px', ''), 10), 73 | elemH = parseInt(computedStyle.height.replace('px', ''), 10), 74 | elemDim = [elemW, elemH], 75 | computedDim = [], 76 | ratio; 77 | image.src = src; 78 | ratio = image.width > image.height ? image.width / image.height : image.height / image.width; 79 | cssSize = cssSize.split(' '); 80 | computedDim[0] = cssSize[0]; 81 | computedDim[1] = cssSize.length > 1 ? cssSize[1] : 'auto'; 82 | if (cssSize[0] === 'cover') { 83 | if (elemDim[0] > elemDim[1]) { 84 | if (elemDim[0] / elemDim[1] >= ratio) { 85 | computedDim[0] = elemDim[0]; 86 | computedDim[1] = 'auto'; 87 | } else { 88 | computedDim[0] = 'auto'; 89 | computedDim[1] = elemDim[1]; 90 | } 91 | } else { 92 | computedDim[0] = 'auto'; 93 | computedDim[1] = elemDim[1]; 94 | } 95 | } else if (cssSize[0] === 'contain') { 96 | if (elemDim[0] < elemDim[1]) { 97 | computedDim[0] = elemDim[0]; 98 | computedDim[1] = 'auto'; 99 | } else { 100 | if (elemDim[0] / elemDim[1] >= ratio) { 101 | computedDim[0] = 'auto'; 102 | computedDim[1] = elemDim[1]; 103 | } else { 104 | computedDim[1] = 'auto'; 105 | computedDim[0] = elemDim[0]; 106 | } 107 | } 108 | } else { 109 | for (let i = cssSize.length; i--;) { 110 | if (cssSize[i].indexOf('px') > -1) { 111 | computedDim[i] = cssSize[i].replace('px', ''); 112 | } else if (cssSize[i].indexOf('%') > -1) { 113 | computedDim[i] = elemDim[i] * (cssSize[i].replace('%', '') / 100); 114 | } 115 | } 116 | } 117 | if (computedDim[0] === 'auto' && computedDim[1] === 'auto') { 118 | computedDim[0] = image.width; 119 | computedDim[1] = image.height; 120 | } else { 121 | ratio = computedDim[0] === 'auto' ? image.height / computedDim[1] : image.width / computedDim[0]; 122 | computedDim[0] = computedDim[0] === 'auto' ? image.width / ratio : computedDim[0]; 123 | computedDim[1] = computedDim[1] === 'auto' ? image.height / ratio : computedDim[1]; 124 | } 125 | return { 126 | width: Math.round(computedDim[0]), 127 | height: Math.round(computedDim[1]) 128 | } 129 | } 130 | 131 | // Get element distance to top of viewport 132 | function elemtoTop(e) { 133 | return e.getBoundingClientRect().top 134 | } 135 | 136 | // Check if in viewport and screen width 137 | function checkConditions(e) { 138 | return isInViewport(e) && screenWidth >= options.minWidth 139 | } 140 | 141 | 142 | // Main Parallax Function 143 | function startParallax() { 144 | 145 | const elements = document.querySelectorAll(options.selector); 146 | const windowHeight = window.innerHeight || document.documentElement.clientHeight; 147 | let movement = 0; 148 | let depth, 149 | i, 150 | len, 151 | translate3d, 152 | translateBg, 153 | bgHeightSized, 154 | offsetDistTop, 155 | container, 156 | startPos, 157 | containerSelector; 158 | 159 | 160 | // Loop through elements 161 | //elements.forEach(element => { 162 | for (const element of elements) { 163 | if (element.hasAttribute('data-container')){ 164 | containerSelector = '.' + element.getAttribute('data-container'); 165 | } 166 | else { 167 | containerSelector = '.' + options.container; 168 | } 169 | 170 | if (element.closest(containerSelector)){ 171 | container = element.closest(containerSelector); 172 | } else { 173 | container = element.parentElement; 174 | } 175 | 176 | if (element.hasAttribute('data-start-position')){ 177 | startPos = element.getAttribute('data-start-position'); 178 | } else { 179 | startPos = .5; 180 | } 181 | 182 | let computedStyle = getComputedStyle(element); 183 | 184 | let outerHeightBg = element.offsetHeight; 185 | outerHeightBg -= parseFloat(computedStyle.borderTop) + parseFloat(computedStyle.borderBottom); 186 | 187 | offsetDistTop = window.pageYOffset; 188 | 189 | depth = element.getAttribute('data-depth'); 190 | 191 | // Check if element container visible and for screen width 192 | if (checkConditions(container)) { 193 | 194 | // -- BG Elements 195 | if (element.classList.contains(options.bgSelector) || element.classList.contains(options.bgTopSelector) && checkConditions(element)) { 196 | 197 | const bgSized = getBgSize(element); 198 | const whRatio = (bgSized.width / bgSized.height).toFixed(3); 199 | 200 | if (element.classList.contains(options.bgTopSelector)) { 201 | movement = (offsetDistTop * depth); 202 | translateBg = ('50% ' + Math.round(movement) + 'px'); 203 | element.style.backgroundPosition = translateBg; 204 | } 205 | else { 206 | movement = -((elemtoTop(element) * (depth)) - ((hdHeight) * depth)); 207 | translateBg = ('50% ' + Math.round(movement) + 'px'); 208 | element.style.backgroundPosition = translateBg; 209 | 210 | bgHeightSized = Math.round(outerHeightBg + ((windowHeight * depth) - (outerHeightBg * depth))); 211 | let bgWidthSized = bgHeightSized * whRatio; 212 | 213 | if (bgWidthSized < container.offsetWidth) { 214 | element.style.backgroundSize ='cover'; 215 | } else { 216 | element.style.backgroundSize = 'auto ' + bgHeightSized + 'px'; 217 | } 218 | } 219 | } 220 | 221 | // -- Not BG Elements 222 | else { 223 | // Bottom Elements 224 | if (element.classList.contains(options.btmSelector)) { 225 | movement = -(document.body.scrollHeight - window.innerHeight - window.scrollY) * depth; 226 | } 227 | // Default Elements 228 | else { 229 | if (element.classList.contains(options.topSelector)) { 230 | movement = (offsetDistTop * depth); 231 | } 232 | else { 233 | let outerToTop = -((elemtoTop(container)) - hdHeight); 234 | let outerHeightWindow = (windowHeight - hdHeight - container.offsetHeight) * startPos; 235 | movement = (outerToTop + outerHeightWindow ) * depth; 236 | } 237 | } 238 | 239 | // Movement Axis 240 | if (element.classList.contains(options.axisSelector)) { 241 | translate3d = 'translate3d(' + Math.round(movement) + 'px, 0, 0)'; 242 | } else { 243 | translate3d = 'translate3d(0, ' + Math.round(movement) + 'px, 0)'; 244 | } 245 | 246 | // -- Apply Movement 247 | if (options.oldBrowserSupport == 'true') { 248 | element.style['-webkit-transform'] = translate3d; 249 | element.style['-moz-transform'] = translate3d; 250 | element.style['-ms-transform'] = translate3d; 251 | element.style['-o-transform'] = translate3d; 252 | element.style.transform = translate3d; 253 | } else { 254 | element.style['-webkit-transform'] = translate3d; 255 | element.style.transform = translate3d; 256 | } 257 | } 258 | } 259 | 260 | // If not visible or small screen widths 261 | else { 262 | if (element.classList.contains(options.bgSelector) || element.classList.contains(options.bgTopSelector) && checkConditions(element)) { 263 | element.style.backgroundPosition = '50% 50%'; 264 | element.style.backgroundSize = 'cover'; 265 | } 266 | else { 267 | element.style.transform = 'translate3d(0,0,0)'; 268 | } 269 | } 270 | } 271 | } 272 | } --------------------------------------------------------------------------------