/
parallax3d.js
83 lines (69 loc) · 2.81 KB
/
parallax3d.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
var prefix = (function() {
var styles = window.getComputedStyle(document.documentElement, ''),
pre = (Array.prototype.slice
.call(styles)
.join('')
.match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
)[1],
dom = ('WebKit|Moz|MS|O').match(new RegExp('(' + pre + ')', 'i'))[1];
return {
dom: dom,
lowercase: pre,
css: '-' + pre + '-',
js: pre[0].toUpperCase() + pre.substr(1)
};
})();
var Parallax3D = (function() {
var self = {};
self.elements = [];
self.handleSingle = function($this, scrollTop, screenHeight, scrollBottom) {
if (null == $this.data('parallax-offset') || $this.data('parallax-offset') < 0) return;
scrollTop = scrollTop || $(window).scrollTop();
screenHeight = screenHeight || $(window).height();
scrollBottom = scrollTop + screenHeight;
var translation = (scrollBottom - $this.data('parallax-start')) / (screenHeight + $this.data('parallax-height'));
var cssTranslation = -1 * Math.min(Math.max(translation,0),1) * $this.data('parallax-offset');
$this.data('parallax-object').css(prefix.css + 'transform', 'translate3d(0, ' + cssTranslation + 'px, 0)');
};
self.handler = function(){
var scrollTop = $(window).scrollTop();
var screenHeight = $(window).height();
var scrollBottom = scrollTop + screenHeight;
self.elements.each(function(){
self.handleSingle($(this), scrollTop, screenHeight, scrollBottom);
});
};
self.parse = function() {
self.elements = $('[data-parallax-3d]');
if (self.elements.length === 0) return;
self.elements.each(function(){
var $el = $(this);
$el.css({ overflow: 'hidden', position: 'relative' }).data({
'parallax-start': $el.offset().top,
'parallax-height': $el.outerHeight()
});
var $obj = $el.find('>[data-parallax-3d-object]');
$el.data('parallax-object', $obj);
$obj.load(function(){
var imageNaturalHeight = $obj[0].naturalHeight / $obj[0].naturalWidth * $el.outerWidth();
$el.data('parallax-offset', imageNaturalHeight - $el.outerHeight());
if ($el.data('parallax-offset') > 0) {
$obj.css({ position: 'absolute', width: '100%', height: 'auto', top: 0, left: 0, right: 0, opacity: 1 });
self.handleSingle($el);
} else {
$obj.css(prefix.css + 'transform', 'none').css('height', $el.outerHeight()).css({
position: 'absolute', width: 'auto', top: 0, bottom: 0,left: '-9999px', right: '-9999px', margin: '0 auto', opacity: 1
});
}
});
if ($obj[0].complete) $obj.load();
});
};
$('head').append('<style>[data-parallax-3d]{ overflow: hidden; position: relative; } [data-parallax-3d-object]{ position: absolute; width: 100%; height: auto; top: 0; left: 0; right: 0; opacity: 0; '+prefix.css+'transition: opacity 1s; }</style>');
$(self.parse);
$(window).load(function() {
$(window).resize(self.parse);
$(window).scroll(self.handler);
});
return self;
})();