Skip to content

Commit 43248a8

Browse files
authored
Merge branch 'master' into master
2 parents 59c6bc2 + 93b2aa0 commit 43248a8

File tree

3 files changed

+44
-30
lines changed

3 files changed

+44
-30
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ $('.parallax-window').parallax({imageSrc: '/path/to/image.jpg'});
3737

3838
### Notes
3939

40-
What parallax.js will do is create a fixed-position element for each parallax image at the start of the document's body. This mirror element will sit behind the other elements and match the position and dimensions of its target object.
40+
What parallax.js will do is create a fixed-position element for each parallax image at the start of the document's body (or another configurable container). This mirror element will sit behind the other elements and match the position and dimensions of its target object.
4141

4242
Due to the nature of this implementation, you must ensure that these parallax objects and any layers below them are transparent so that you can see the parallax effect underneath. Also, if there is no other content in this element, you will need to ensure that it has some fixed dimensions otherwise you won't see anything.
4343

@@ -172,6 +172,12 @@ Note that when specifying these options as html data-attributes, you should conv
172172
<td>false</td>
173173
<td>(Experimental) If true, will freeze the parallax effect when "over scrolling" in browsers like Safari to prevent unexpected gaps caused by negative scroll positions.</td>
174174
</tr>
175+
<tr>
176+
<td>mirrorContainer</td>
177+
<td>jQuery Selector</td>
178+
<td>body</td>
179+
<td>The parallax mirror will be prepended into this container.</td>
180+
</tr>
175181
</tbody>
176182
</table>
177183

parallax.js

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
var vendors = ['ms', 'moz', 'webkit', 'o'];
1515
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
1616
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
17-
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
18-
|| window[vendors[x]+'CancelRequestAnimationFrame'];
17+
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
1918
}
2019

2120
if (!window.requestAnimationFrame)
@@ -65,8 +64,8 @@
6564
positions = [positions[1], positions[0]];
6665
}
6766

68-
if (this.positionX != undefined) positions[0] = this.positionX.toLowerCase();
69-
if (this.positionY != undefined) positions[1] = this.positionY.toLowerCase();
67+
if (this.positionX !== undefined) positions[0] = this.positionX.toLowerCase();
68+
if (this.positionY !== undefined) positions[1] = this.positionY.toLowerCase();
7069

7170
self.positionX = positions[0];
7271
self.positionY = positions[1];
@@ -113,7 +112,7 @@
113112
return this;
114113
}
115114

116-
this.$mirror = $('<div />').prependTo('body');
115+
this.$mirror = $('<div />').prependTo(this.mirrorContainer);
117116

118117
var slider = this.$element.find('>.parallax-slider');
119118
var sliderExisted = false;
@@ -154,7 +153,7 @@
154153
this.$slider.trigger('load');
155154
}
156155

157-
};
156+
}
158157

159158

160159
// Parallax Instance Methods
@@ -167,6 +166,7 @@
167166
androidFix: true,
168167
position: 'center',
169168
overScrollFix: false,
169+
mirrorContainer: 'body',
170170

171171
refresh: function() {
172172
this.boxWidth = this.$element.outerWidth();
@@ -181,13 +181,14 @@
181181
var minOffset = Math.max(this.boxOffsetTop + this.boxHeight - winHeight, 0);
182182
var imageHeightMin = this.boxHeight + (maxOffset - minOffset) * (1 - this.speed) | 0;
183183
var imageOffsetMin = (this.boxOffsetTop - maxOffset) * (1 - this.speed) | 0;
184+
var margin;
184185

185186
if (imageHeightMin * this.aspectRatio >= this.boxWidth) {
186187
this.imageWidth = imageHeightMin * this.aspectRatio | 0;
187188
this.imageHeight = imageHeightMin;
188189
this.offsetBaseTop = imageOffsetMin;
189190

190-
var margin = this.imageWidth - this.boxWidth;
191+
margin = this.imageWidth - this.boxWidth;
191192

192193
if (this.positionX == 'left') {
193194
this.offsetLeft = 0;
@@ -203,7 +204,7 @@
203204
this.imageHeight = this.boxWidth / this.aspectRatio | 0;
204205
this.offsetLeft = 0;
205206

206-
var margin = this.imageHeight - imageHeightMin;
207+
margin = this.imageHeight - imageHeightMin;
207208

208209
if (this.positionY == 'top') {
209210
this.offsetBaseTop = imageOffsetMin;
@@ -233,19 +234,15 @@
233234
}
234235

235236
this.$mirror.css({
236-
transform: 'translate3d(0px, 0px, 0px)',
237+
transform: 'translate3d('+this.mirrorLeft+'px, '+(this.mirrorTop - overScroll)+'px, 0px)',
237238
visibility: this.visibility,
238-
top: this.mirrorTop - overScroll,
239-
left: this.mirrorLeft,
240239
height: this.boxHeight,
241240
width: this.boxWidth
242241
});
243242

244243
this.$slider.css({
245-
transform: 'translate3d(0px, 0px, 0px)',
244+
transform: 'translate3d('+this.offsetLeft+'px, '+this.offsetTop+'px, 0px)',
246245
position: 'absolute',
247-
top: this.offsetTop,
248-
left: this.offsetLeft,
249246
height: this.imageHeight,
250247
width: this.imageWidth,
251248
maxWidth: 'none'
@@ -271,6 +268,8 @@
271268
setup: function() {
272269
if (this.isReady) return;
273270

271+
var self = this;
272+
274273
var $doc = $(document), $win = $(window);
275274

276275
var loadDimensions = function() {
@@ -291,6 +290,7 @@
291290

292291
$win.on('resize.px.parallax load.px.parallax', function() {
293292
loadDimensions();
293+
self.refresh();
294294
Parallax.isFresh = false;
295295
Parallax.requestRender();
296296
})
@@ -303,6 +303,20 @@
303303
loadScrollPosition();
304304

305305
this.isReady = true;
306+
307+
var lastPosition = -1;
308+
309+
function frameLoop() {
310+
if (lastPosition == window.pageYOffset) { // Avoid overcalculations
311+
window.requestAnimationFrame(frameLoop);
312+
return false;
313+
} else lastPosition = window.pageYOffset;
314+
315+
self.render();
316+
window.requestAnimationFrame(frameLoop);
317+
}
318+
319+
frameLoop();
306320
},
307321

308322
configure: function(options) {
@@ -314,25 +328,19 @@
314328
},
315329

316330
refresh: function() {
317-
$.each(this.sliders, function(){ this.refresh() });
331+
$.each(this.sliders, function(){ this.refresh(); });
318332
this.isFresh = true;
319333
},
320334

321335
render: function() {
322336
this.isFresh || this.refresh();
323-
$.each(this.sliders, function(){ this.render() });
337+
$.each(this.sliders, function(){ this.render(); });
324338
},
325339

326340
requestRender: function() {
327341
var self = this;
328-
329-
if (!this.isBusy) {
330-
this.isBusy = true;
331-
window.requestAnimationFrame(function() {
332-
self.render();
333-
self.isBusy = false;
334-
});
335-
}
342+
self.render();
343+
self.isBusy = false;
336344
},
337345
destroy: function(el){
338346
var i,
@@ -373,13 +381,13 @@
373381
}
374382
if (typeof option == 'string') {
375383
if(option == 'destroy'){
376-
Parallax['destroy'](this);
384+
Parallax.destroy(this);
377385
}else{
378386
Parallax[option]();
379387
}
380388
}
381-
})
382-
};
389+
});
390+
}
383391

384392
var old = $.fn.parallax;
385393

parallax.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)