1// Parallax 2( function( theme, $ ) { 3 'use strict'; 4 5 theme = theme || {}; 6 7 var instanceName = '__parallax'; 8 9 var Parallax = function( $el, opts ) { 10 return this.initialize( $el, opts ); 11 }; 12 13 Parallax.defaults = { 14 speed: 1.5, 15 horizontalPosition: '50%', 16 offset: 0, 17 scale: false, 18 startOffset: 7, 19 scaleInvert: false, 20 }; 21 22 Parallax.prototype = { 23 initialize: function( $el, opts ) { 24 if ( $el.data( instanceName ) ) { 25 return this; 26 } 27 28 this.$el = $el; 29 30 this 31 .setData() 32 .setOptions( opts ) 33 .build(); 34 35 return this; 36 }, 37 38 setData: function() { 39 this.$el.data( instanceName, this ); 40 41 return this; 42 }, 43 44 setOptions: function( opts ) { 45 this.options = $.extend( true, {}, Parallax.defaults, opts, { 46 wrapper: this.$el 47 } ); 48 49 return this; 50 }, 51 52 build: function() { 53 var self = this, 54 $window = $( window ), 55 offset, 56 yPos, 57 bgpos, 58 background; 59 60 // Create Parallax Element 61 background = $( '<div class="parallax-background"></div>' ); 62 63 // Set Style for Parallax Element 64 var bg = self.options.wrapper.data( 'image-src' ) ? 'url(' + self.options.wrapper.data( 'image-src' ) + ')' : self.options.wrapper.css( 'background-image' ); 65 background.css( { 66 'background-image': bg, 67 'background-size': 'cover', 68 'background-position': '50% 0%', 69 'position': 'absolute', 70 'top': 0, 71 'left': 0, 72 'width': '100%', 73 'height': self.options.speed * 100 + '%' 74 } ); 75 76 // Add Parallax Element on DOM 77 self.options.wrapper.prepend( background ); 78 79 // Set Overlfow Hidden and Position Relative to Parallax Wrapper 80 self.options.wrapper.css( { 81 'position': 'relative', 82 'overflow': 'hidden' 83 } ); 84 85 if ( self.options.wrapper.attr( 'data-parallax-type' ) ) { // horizontal 86 self.options.parallaxType = 'horizontal'; 87 background.css( { 88 'background-position': '0% 50%', 89 'width': self.options.speed * 100 + '%', 90 'height': '100%', 91 } ); 92 } 93 94 // Scroll Scale 95 if ( self.options.scale ) { 96 background.wrap( '<div class="parallax-scale-wrapper"></div>' ); 97 background.css( { 98 'transition': 'transform 500ms ease-out' 99 } ); 100 this.scaleParallaxFunc = this.scaleParallax.bind( this ); 101 this.scaleParallaxFunc(); 102 window.addEventListener( 'scroll', this.scaleParallaxFunc ); 103 window.addEventListener( 'resize', this.scaleParallaxFunc ); 104 } 105 // Parallax Effect on Scroll & Resize 106 var parallaxEffectOnScrolResize = function() { 107 var skrollr_size = 100 * self.options.speed, 108 skrollr_start = -( skrollr_size - 100 ); 109 if ( !self.options.parallaxType ) { 110 background.attr( "data-bottom-top", "top: " + skrollr_start + "%;" ).attr( "data-top-bottom", "top: 0%;" ); 111 } else { 112 skrollr_start /= 9.8; 113 background.attr( "data-bottom-top", "left: " + skrollr_start + "%;" ).attr( "data-top-bottom", "left: 0%;" ); 114 } 115 } 116 117 if ( !theme.is_device_mobile ) { 118 parallaxEffectOnScrolResize(); 119 } else { 120 if ( self.options.enableOnMobile == true ) { 121 parallaxEffectOnScrolResize(); 122 } else { 123 self.options.wrapper.addClass( 'parallax-disabled' ); 124 } 125 } 126 127 return this; 128 }, 129 130 scaleParallax: function() { 131 var self = this, 132 $window = $( window ), 133 scrollTop = $window.scrollTop(), 134 $background = self.options.wrapper.find( '.parallax-background' ),
135 elementOffset = self.options.wrapper.offset().top, 136 currentElementOffset = ( elementOffset - scrollTop ), 137 scrollPercent = Math.abs( +( currentElementOffset - $window.height() ) / ( self.options.startOffset ? self.options.startOffset : 7 ) ); 138 scrollPercent = parseInt( ( scrollPercent >= 100 ) ? 100 : scrollPercent ); 139 var currentScale = ( scrollPercent / 100 ) * 50; 140 if ( !self.options.scaleInvert ) { 141 $background.css( { 142 'transform': 'scale(1.' + String( currentScale ).padStart( 2, '0' ) + ', 1.' + String( currentScale ).padStart( 2, '0' ) + ')' 143 } ); 144 } else { 145 $background.css( { 146 'transform': 'scale(1.' + String( 50 - currentScale ).padStart( 2, '0' ) + ', 1.' + String( 50 - currentScale ).padStart( 2, '0' ) + ')' 147 } ); 148 } 149 }, 150 151 disable: function() { 152 var self = this; 153 if ( self.options.scale ) { 154 window.removeEventListener( 'scroll', this.scaleParallaxFunc ); 155 window.removeEventListener( 'resize', this.scaleParallaxFunc ); 156 } 157 } 158 }; 159 160 // expose to scope 161 $.extend( theme, { 162 Parallax: Parallax 163 } ); 164 165 // jquery plugin 166 $.fn.themeParallax = function( opts ) { 167 if ( typeof skrollr == 'undefined' ) { 168 return this; 169 } 170 var obj = this.map( function() { 171 var $this = $( this ); 172 173 if ( $this.data( instanceName ) ) { 174 return $this.data( instanceName ); 175 } else { 176 return new theme.Parallax( $this, opts ); 177 } 178 179 } ); 180 if ( theme.portoSkrollr ) { 181 theme.portoSkrollr.refresh(); 182 } else if ( !theme.is_device_mobile ) { 183 theme.portoSkrollr = skrollr.init( { forceHeight: false, smoothScrolling: false, mobileCheck: function() { return theme.is_device_mobile } } ); 184 } 185 return obj; 186 } 187 188} ).apply( this, [window.theme, jQuery] ); 189 190 191( function( $, theme ) { 192 if ( theme.isReady ) { // Finish init 193 // Parallax 194 if ( $.fn.themeParallax ) { 195 $( function() { 196 $( '[data-plugin-parallax]:not(.manual)' ).each( function() { 197 var $this = $( this ), 198 opts; 199 var pluginOptions = $this.data( 'plugin-options' ), 200 parallaxScale = $this.attr( 'data-parallax-scale' ); 201 if ( pluginOptions ) 202 opts = pluginOptions; 203 204 if ( typeof parallaxScale !== 'undefined' ) { 205 opts['scale'] = true; 206 if ( parallaxScale == 'invert' ) { 207 opts['scaleInvert'] = true; 208 } 209 } 210 $this.themeParallax( opts ); 211 } ); 212 } ); 213 } 214 } 215 $( document.body ).on( 'porto_init', function( e, $wrap ) { 216 // Parallax 217 if ( $.fn.themeParallax ) { 218 $( function() { 219 $wrap.find( '[data-plugin-parallax]:not(.manual)' ).each( function() { 220 var $this = $( this ), 221 opts; 222 var pluginOptions = $this.data( 'plugin-options' ), 223 parallaxScale = $this.attr( 'data-parallax-scale' ); 224 if ( pluginOptions ) 225 opts = pluginOptions; 226 227 if ( typeof parallaxScale !== 'undefined' ) { 228 opts['scale'] = true; 229 if ( parallaxScale == 'invert' ) { 230 opts['scaleInvert'] = true; 231 } 232 } 233 $this.themeParallax( opts ); 234 } ); 235 } ); 236 } 237 } ); 238} )( window.jQuery, window.theme )
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.