forked from pwalczyszyn/scroll2play
-
Notifications
You must be signed in to change notification settings - Fork 0
/
s2p.js
192 lines (166 loc) · 6.62 KB
/
s2p.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*jslint browser: true, curly: false*/
(function () {
'use strict';
/**
* Scroll2Play type constructor.
*
* @constructor
* @this {Scroll2Play}
* @param {String} elId Scroll2Play container id.
* @param {String} lowResImgsUrl Path to low res images folder.
* @param {String} highResImgsUrl Path to low high images folder.
* @param {String} imgPrefix Image file prefix.
* @param {String} imgsCount Number of available images.
* @param {String} imgsType Images type, like: 'jpg', 'png', 'gif'...
* @param {String} imgsNumFormat Format for images numbering, like: 0000 will be substitued with 0001, 0002,...,0010 etc.
*/
var Scroll2Play = window.Scroll2Play = function Scroll2Play(elId, lowResImgsUrl, highResImgsUrl, imgPrefix, imgsCount, imgsType, imgsNumFormat) {
this.el = document.getElementById(elId);
if (!this.el) throw new Error('Element with specified id doesn\'t exist!');
this.el.style.cssText += 'position:fixed;overflow:hidden;width:100%;height:100%;';
this.img = document.createElement('img');
this.img.style.cssText = 'position:relative;height:auto;width:auto;min-height:100vh;min-width:100vw;';
this.el.appendChild(this.img);
this.lowResImgsUrl = lowResImgsUrl;
this.highResImgsUrl = highResImgsUrl;
this.imgPrefix = imgPrefix;
this.imgsCount = imgsCount;
this.imgsType = imgsType ? imgsType : 'jpg';
this.imgsNumFormat = imgsNumFormat ? imgsNumFormat : '0';
this.xhrs = [];
this.images = [];
};
/**
* Initiates loading of low res images.
*
* @fires Scroll2Play#onload Fired when loading images is complete.
* @fires Scroll2Play#onprogress Fired during images loading, callback param is % of progress.
* @fires Scroll2Play#onerror Fired when loading images fails.
* @return {Scroll2Play}
*/
Scroll2Play.prototype.load = function s2p_load() {
console.log("load");
var that = this,
loaded = 0,
error = false;
for (var i = 0; i < this.imgsCount; i++) {
that.xhrs[i] = xhr(i);
console.log("working");
}
function xhr(i) {
console.log("getting");
var req = new XMLHttpRequest();
req.open('GET', that._getImgUrl(that.lowResImgsUrl, i), true);
req.responseType = 'blob';
req.addEventListener('load', xhr_loadHandler(i), false);
req.addEventListener('error', xhr_errorHandler(), false);
req.addEventListener('abort', xhr_abortHandler(), false);
req.send();
return req;
}
function xhr_loadHandler(i) {
return function _xhr_loadHandler(e) {
if (!error) {
// Creating BLOB references
that.images[i] = window.URL.createObjectURL(e.target.response);
// Incrementing num of loaded images
loaded++;
if (that.onprogress) {
that.onprogress(loaded / that.imgsCount);
}
if (loaded == that.imgsCount) {
delete that.xhrs; // Cleaning up
if (that.onload) that.onload();
that._handleScrolling();
}
}
};
}
function xhr_errorHandler() {
return function (e) {
error = true;
if (that.onerror) that.onerror(e);
};
}
function xhr_abortHandler() {
return function (e) {
error = true;
if (that.onerror) that.onerror(e);
};
}
return this;
};
/**
* @event
*/
Scroll2Play.prototype.onload = function () {};
/**
* @event
*/
Scroll2Play.prototype.onerror = function () {};
/**
* @event
* @param {Number} progress Progress at which loading low res images is. Values range 0-1.
*/
/*jshint unused: vars */
Scroll2Play.prototype.onprogress = function (progress) {};
/**
* @private
*/
Scroll2Play.prototype._getImgUrl = function s2p_getImgUrl(url, imgNum) {
var strNum = String(imgNum);
return url + '/' + this.imgPrefix + this.imgsNumFormat.substr(0, this.imgsNumFormat.length - strNum.length) + strNum + '.' + this.imgsType;
};
/**
* @private
*/
Scroll2Play.prototype._handleScrolling = function s2p_handleScrolling() {
var that = this,
prevImgNum = null,
scrollEndTimeout = null;
function window_scrollHandler() { // Handling window scroll event
// First clearing the timeout, if there is one already
if (scrollEndTimeout !== null) {
clearTimeout(scrollEndTimeout);
}
var img,
imgNum = Math.round(window.pageYOffset / document.body.clientHeight * that.images.length);
if (null === prevImgNum || prevImgNum != imgNum) {
img = that.images[imgNum];
if (img) {
// Setting src
that.img.src = img;
// Resizing and repositioning image
window_resizeHandler();
// Setting prev image num so it doesn't reload it unecessarly
prevImgNum = imgNum;
}
}
scrollEndTimeout = setTimeout(function () {
that._loadHighResImg(imgNum);
}, 250);
}
window.addEventListener('scroll', window_scrollHandler, false);
window_scrollHandler();
function window_resizeHandler() { // Centering image
// Updating min-width & min-height so it doesn't use img width & height
var top = (window.innerHeight - that.img.height) / 2 + 'px',
left = (window.innerWidth - that.img.width) / 2 + 'px';
that.img.style.cssText = 'position:relative;height:auto;width:auto;min-height:100vh;min-width:100vw;top:' + top + ';left:' + left;
}
window.addEventListener('resize', window_resizeHandler, false);
};
/**
* @private
*/
/*jshint unused: vars */
Scroll2Play.prototype._loadHighResImg = function s2p_loadHighResImg(imgNum) {
if (this.highResImgsUrl) {
var width = this.img.width,
height = this.img.height;
this.img.src = this._getImgUrl(this.highResImgsUrl, imgNum);
this.img.width = width;
this.img.height = height;
}
};
})();