This repository has been archived by the owner on Oct 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rotator.dev.js
368 lines (307 loc) · 13.2 KB
/
rotator.dev.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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
var $j = jQuery.noConflict();
/**
* Change the to the next (or previous) image in the rotator.
*
* Function is called automatically by the web browser's interval feature, or manually when the next/previous navigation buttons are clicked
*
* @param id string HTML ID of the image rotator
* @param direction string next|previous. Optional - defaults to next
*/
function ChangeImage(id, direction) {
var selector,
active,
next;
if ( direction === undefined ) {
direction = 'next';
}
// The CSS selector, based on the id passed to this function
selector = "#" + id;
if ( rotatorSettings[id]['intransition'] ) {
debug (selector + ' ChangeImage() called during transition period -> ignoring request');
return;
}
active = $j(selector + ' img.active');
if (direction == 'next') {
next = $j(active).next('img');
} else if (direction == 'previous') {
next = $j(active).prev('img');
}
// Set the next image in the order they appear in the markup
if (next.length) {
// We aren't at the end of the rotator yet
} else {
// We have just completed this cycle
if (direction == 'next') {
// Reset the the first image in the rotator
next = $j(selector + ' img:first');
rotatorSettings[id]['imagenumber'] = 0;
} else {
// Reset the the last image in the rotator
next = $j(selector + ' img:last');
rotatorSettings[id]['imagenumber'] = rotatorSettings[id]['totalnumimages'] + 1;
}
debug (selector + ' imagenumber reset to ' + rotatorSettings[id]['imagenumber']);
// Increment the cycle count
rotatorSettings[id]['cyclecount'] += 1;
debug (selector + ' completed cycle #' + rotatorSettings[id]['cyclecount'] + ' of ' + rotatorSettings[id]['cycles']);
// If cycles = 0, then it's unlimited
if (rotatorSettings[id]['cycles'] > 0 && rotatorSettings[id]['cycles'] == rotatorSettings[id]['cyclecount']) {
// No more cycles left, stop the rotator
StopRotator(id);
return;
}
}
StartImageTransition(id);
$j(next)
.addClass('next')
.fadeTo(rotatorSettings[id]['transition'], 1.0, function() {
$j(this).addClass('active');
if (direction == 'next') {
rotatorSettings[id]['imagenumber'] += 1;
} else if (direction == 'previous') {
rotatorSettings[id]['imagenumber'] -= 1;
}
debug (selector + ' imagenumber ' + rotatorSettings[id]['imagenumber'] + ': src=' + $j(this).attr('src'));
$j(selector + " .navigation .imagenumber").html(rotatorSettings[id]['imagenumber']);
EndImageTransition(id);
}
);
$j(active)
.removeClass('next')
.fadeTo(rotatorSettings[id]['transition'], 0.0, function() {
$j(this).removeClass('active');
}
);
}
jQuery(document).ready(function($){
// Register each image rotator on the page
var i,
rotators = $j("div.simplerotator"),
numRotators = rotators.size(),
id,
parent,
rotatorid,
self,
imgRatio,
windowWidth,
windowHeight,
imgWidth,
imgHeight,
delay;
for (i = 0; i < numRotators; i++) {
id = $j(rotators[i]).attr('id');
rotatorSettings[id]['imagenumber'] = 1;
rotatorSettings[id]['intransition'] = false;
rotatorSettings[id]['loadeventfired'] = false;
/*
When the first image has finished loading in the browser.
However, as per http://api.jquery.com/load-event/, the load event for images does not work consistently
nor reliably cross-browser, which is why we use the 'loadeventfired' flag.
*/
$j('#' + id + ' img.first').on('load',function() {
if ( rotatorSettings[id]['loadeventfired'] == true ) {
return; // load event for this image has already been fired
}
rotatorSettings[id]['loadeventfired'] = true;
// The parent DIV. Can't use parent because an a tag may exist (if the href shortcode attribute is used)
parent = $j(this).parents('div.simplerotator')[0];
// Obtain the unique rotator ID because it could be different to the id variable above
rotatorid = $j(parent).attr('id');
debug('#' + rotatorid + ': running img.load() event for ' + $j(this).attr('src'));
if (rotatorSettings[rotatorid]['fullscreen']) { // Full Screen Rotator
// Image resize logic is from jQuery Backstretch v1.0 (http://github.com/srobbin/jquery-backstretch and http://srobbin.com/jquery-plugins/jquery-backstretch/)
debug('#' + rotatorid + ': initialising full screen rotator with offsets = T:' + rotatorSettings[rotatorid]['topoffset'] + " R:" + rotatorSettings[rotatorid]['rightoffset'] + " B:" + rotatorSettings[rotatorid]['bottomoffset'] + " L:" + rotatorSettings[rotatorid]['leftoffset'] + ', losingside = ' + rotatorSettings[rotatorid]['losingside'] + ' and ensurefullscreen = ' + rotatorSettings[rotatorid]['ensurefullscreen']);
$j('#' + rotatorid).css({'position': 'fixed', 'left': rotatorSettings[rotatorid]['leftoffset'], 'top': rotatorSettings[rotatorid]['topoffset'], 'z-index': '-1'});
self = $j(this);
imgRatio = self.width() / self.height();
function ResizeImage() {
// If top, right, bottom and left offsets are all defined then one side must give way
switch (rotatorSettings[rotatorid]['losingside']) {
case 'bottom':
// Bottom side must give way, so ignore the bottom offset paramter
rotatorSettings[rotatorid]['bottomoffset'] = 0;
break;
case 'right':
// Right hand side must give way, so ignore the bottom offset paramter
rotatorSettings[rotatorid]['rightoffset'] = 0;
break;
}
// Calculate the web browser's viewport dimensions (taking into account any offset values)
windowWidth = $j(window).width() - rotatorSettings[rotatorid]['leftoffset'] - rotatorSettings[rotatorid]['rightoffset'];
windowHeight = $j(window).height() - rotatorSettings[rotatorid]['topoffset'] - rotatorSettings[rotatorid]['bottomoffset'];
// Calculate the appropriate image dimensions
switch (rotatorSettings[rotatorid]['losingside']) {
case 'bottom':
imgWidth = windowWidth;
imgHeight = imgWidth / imgRatio;
if(rotatorSettings[rotatorid]['ensurefullscreen'] && imgHeight < windowHeight) {
debug('#' + rotatorid + ': White space detected between the bottom of the image and the bottom of the browser window -> increasing image height (potentially chopping off the right hand side of the image)');
imgHeight = windowHeight;
imgWidth = imgHeight * imgRatio;
}
break;
case 'right':
imgHeight = windowHeight;
imgWidth = imgHeight * imgRatio;
if(rotatorSettings[rotatorid]['ensurefullscreen'] && imgWidth < windowWidth) {
debug('#' + rotatorid + ': White space detected between the right hand side of the image and the right hand side of the browser window -> increasing image width (potentially chopping off the bottom side of the image)');
imgWidth = windowWidth;
imgHeight = imgWidth / imgRatio;
}
break;
}
debug('#' + rotatorid + ': browser window dimensions: ' + $j(window).width() + ' x ' + $j(window).height());
debug('#' + rotatorid + ': adjusted window dimensions: ' + windowWidth + ' x ' + windowHeight);
debug('#' + rotatorid + ': imgHeight:' + imgHeight + ', windowHeight:' + windowHeight );
$j('#' + rotatorid + ' img').width( imgWidth ).height( imgHeight );
}
ResizeImage();
// Automatically adjust the image size when the browser window is resized
$j(window).resize(ResizeImage);
}
// Always Re-set the simplerotator div's width/height based on the width/height (including padding, margin and border) of the first image in the rotator set
$j(parent).css('height', $j(this).outerHeight(true))
.css('width', $j(this).outerWidth(true));
$j('#' + rotatorid + ' img').removeClass('hidden first');
}); // End img.load() event
// Manually trigger the img.load() event because some browsers don't trigger it for cached images
// We only do this if the image has a width (because otherwise it might not have loaded yet)
if ( rotatorSettings[id]['loadeventfired'] == false && $j('#' + id + ' img.first').width() > 0 ) {
$j('#' + id + ' img.first').trigger('load');
}
if (rotatorSettings[id]['totalnumimages'] == 1) {
// this image rotator only has one image -> skip this rotator
continue;
}
// Set up the next/previous navigation bar if necessary
if (rotatorSettings[id]['shownavigation'] == 'true' || rotatorSettings[id]['shownavigation'] == 'onhover') {
// Set up the navigation bar
debug('#' + id + ': navigation intialised');
$j('#' + id + " .navigation").append('<ul>');
$j('#' + id + " .navigation ul")
.append('<li class="nav prev enabled"><a href="#" title="Previous"><span>←</span></a></li>')
.append('<li class="imagenumbers"><span class="imagenumber">1</span> / <span class="totalimages">' + rotatorSettings[id]['totalnumimages'] + '</span></li>')
.append('<li class="nav next enabled"><a href="#" title="Next"><span>→</span></a></li>')
.append('</ul>')
;
if (rotatorSettings[id]['shownavigation'] == 'true') {
// Navigation should always be shown
$j('#' + id + " .navigation").show();
debug('#' + id + ': navigation always shown');
} else if (rotatorSettings[id]['shownavigation'] == 'onhover') {
// Navigation should be shown on hover
debug('#' + id + ': navigation shown on hover only');
$j('#' + id).hover(
function() {
// Hovering over rotator -> fade the navigation controls in
debug('#' + id + ': showing navigation');
$j('#' + id + " .navigation").fadeIn();
},
function() {
// No longer hovering over rotator -> fade the navigation controls out
debug('#' + id + ': hiding navigation');
$j('#' + id + " .navigation").fadeOut();
}
);
}
// Previous/Next button click handlers
$j('div.simplerotator .navigation li.nav').click( function(e) {
e.preventDefault();
if ( ! $j(this).hasClass('disabled') ) {
id = $j(this).closest('div.simplerotator').attr('id');
if (rotatorSettings[id]['stoponnavigationclick']) StopRotator(id);
if ($j(this).hasClass('prev')) ShowPrevious(id);
else if ($j(this).hasClass('next')) ShowNext(id);
}
});
}
// The start delay needs to have the interval subtracted from it because the rotator won't actually start rotating until interval seconds after being set up
delay = rotatorSettings[id]['startdelay'] - rotatorSettings[id]['interval'];
if (delay > 0) {
setTimeout( "SetupRotator('" + id + "')", delay );
debug('#' + id + ': delaying the setup of this rotator for ' + delay + 'ms');
} else {
// Set it up immediately
SetupRotator(id);
}
}
});
/**
* Set up the recurring interval, and store the interval id so we can refer to it later
*/
function SetupRotator(id) {
debug('#' + id + ': set up rotator to run with interval = ' + rotatorSettings[id]['interval'] + 'ms transition = ' + rotatorSettings[id]['transition'] + 'ms');
rotatorSettings[id]['intervalid'] = setInterval( "ChangeImage('" + id + "')", rotatorSettings[id]['interval'] );
rotatorSettings[id]['cyclecount'] = 0;
}
/**
* Stop the image rotator from automatically rotating
*
* @param id string HTML ID of the image rotator
**/
function StopRotator(id) {
if (rotatorSettings[id]['intervalid'] == 0) return;
clearInterval(rotatorSettings[id]['intervalid']);
rotatorSettings[id]['intervalid'] = 0;
debug ('#' + id + ' stopped after ' + rotatorSettings[id]['cyclecount'] + ' cycles');
}
/**
* Show the next image in the rotator, or loop back to the start if the we're currently on the last image.
*
* @param id string HTML ID of the image rotator
*/
function ShowNext(id) {
debug ('#' + id + ' ShowNext(' + id + ')');
ChangeImage(id);
}
/**
* Show the previous image in the rotator, or loop back to the end if the we're currently on the first image.
*
* @param id string HTML ID of the image rotator
*/
function ShowPrevious(id) {
debug ('#' + id + ' ShowPrevious(' + id + ')');
ChangeImage(id, 'previous');
}
/**
* Adjust the image rotator when it enters the image transition phase
*
* @param id string HTML ID of the image rotator
*/
function StartImageTransition(id) {
// Hide the next/prev buttons during the transition
rotatorSettings[id]['intransition'] = true;
if (rotatorSettings[id]['hidenavigationduringtransition']) {
$j('#' + id + " .navigation ul li.nav")
.addClass('disabled')
.removeClass('enabled')
;
debug('#' + id + ': Hiding next/prev navigation buttons');
}
}
/**
* Adjust the image rotator when it finishes the image transition phase
*
* @param id string HTML ID of the image rotator
*/
function EndImageTransition(id) {
// Hide the next/prev buttons during the transition
rotatorSettings[id]['intransition'] = false;
if (rotatorSettings[id]['hidenavigationduringtransition']) {
$j('#' + id + " .navigation ul li.nav")
.addClass('enabled')
.removeClass('disabled')
;
debug('#' + id + ': Showing next/prev navigation buttons');
}
}
/**
* Write a debugging message
*
* @param message string Debug message
*/
function debug(message) {
if (window.console) {
console.log(message);
}
}