middleman-wizard-template 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. checksums.yaml +7 -0
  2. data/lib/middleman-wizard-template/template/source/index.html.erb +1 -89
  3. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/Matrix.js +449 -0
  4. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/PxLoader/PxLoader.js +395 -0
  5. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/PxLoader/PxLoaderImage.js +96 -0
  6. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/PxLoader/PxLoaderSwiffy.js +68 -0
  7. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/RouteRecognizer.js +506 -0
  8. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/Slides.js +846 -0
  9. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/Transform.js +312 -0
  10. data/lib/middleman-wizard-template/template/source/javascripts/_lib/{Tween.js → ww/Tween.js} +26 -11
  11. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/base.js +8 -0
  12. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/raf.js +131 -0
  13. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/statemachine.js +1024 -0
  14. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/useragent.js +1244 -0
  15. data/lib/middleman-wizard-template/template/source/javascripts/_lib/{util.js → ww/util.js} +48 -50
  16. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/viewport.js +89 -0
  17. data/lib/middleman-wizard-template/template/source/javascripts/{app.js → site.js} +5 -5
  18. data/lib/middleman-wizard-template/template/source/layouts/layout.erb +85 -0
  19. data/lib/middleman-wizard-template/template/source/stylesheets/default.css +2 -1
  20. data/lib/middleman-wizard-template/template/source/stylesheets/site.css.scss +11 -3
  21. data/lib/middleman-wizard-template/version.rb +1 -1
  22. metadata +23 -23
  23. data/lib/middleman-wizard-template/template/source/javascripts/_lib/Transform.js +0 -401
  24. data/lib/middleman-wizard-template/template/source/javascripts/_lib/raf.js +0 -26
  25. data/lib/middleman-wizard-template/template/source/javascripts/_lib/router.js +0 -679
@@ -0,0 +1,846 @@
1
+ goog.provide('ww.Slides');
2
+ goog.require('ww.Tween');
3
+ goog.require('goog.dom');
4
+ goog.require('goog.dom.classes');
5
+ goog.require('goog.dom.query');
6
+ goog.require('goog.events');
7
+ goog.require('goog.object');
8
+ goog.require('goog.style');
9
+
10
+ /*
11
+ <div id="identifier">
12
+ <div class="slide"></div>
13
+ <div class="slide"></div>
14
+ <div class="slide"></div>
15
+ <div class="slide"></div>
16
+ </div>
17
+ */
18
+
19
+
20
+ /**
21
+ * Slides. Requires ww.Tween for fade and fallback animations.
22
+ * Slide effect can be 'slide' or 'fade'.
23
+ * @constructor
24
+ * @param {Object} element Element to initialize Slides.
25
+ * @param {Object} opts Slides configurable options.
26
+ */
27
+ ww.Slides = function(element, opts) {
28
+ var defaults = {
29
+ 'slideClass': 'slide',
30
+ 'namespace': 'slides',
31
+ 'width': 980,
32
+ 'height': 538,
33
+ 'start': 1,
34
+ 'navigation': {
35
+ 'active': true,
36
+ 'effect': 'slide'
37
+ },
38
+ 'pagination': {
39
+ 'active': true,
40
+ 'effect': 'slide'
41
+ },
42
+ 'play': {
43
+ 'active': false,
44
+ 'effect': 'slide',
45
+ 'interval': 5000,
46
+ 'auto': false,
47
+ 'swap': true,
48
+ 'pauseOnHover': false,
49
+ 'restartDelay': 2500
50
+ },
51
+ 'effect': {
52
+ 'slide': {
53
+ 'speed': 500
54
+ },
55
+ 'fade': {
56
+ 'speed': 300,
57
+ 'crossfade': true
58
+ }
59
+ },
60
+ 'callback': {
61
+ 'loaded': function() {},
62
+ 'start': function() {},
63
+ 'complete': function() {}
64
+ }
65
+ };
66
+
67
+ opts = opts || {};
68
+ goog.object.extend(defaults, opts);
69
+ this.opts = defaults;
70
+
71
+ this.elem = element;
72
+ this.namespace = this.opts['namespace'];
73
+ this.init_();
74
+ };
75
+
76
+
77
+ /**
78
+ * Initialize Slides.
79
+ * @private
80
+ */
81
+ ww.Slides.prototype.init_ = function() {
82
+ var self = this;
83
+
84
+ this.slides = goog.dom.getElementsByClass(this.opts['slideClass'], this.elem);
85
+
86
+ // set data
87
+ this.animating = false;
88
+ this.total = this.slides.length;
89
+ this.current = this.opts['start'] - 1;
90
+ this.vendorPrefix = this.getVendorPrefix_();
91
+
92
+ if (this.vendorPrefix) {
93
+ this.timing_ = this.vendorPrefix + 'TransitionTimingFunction';
94
+ this.duration_ = this.vendorPrefix + 'TransitionDuration';
95
+ this.transform_ = this.vendorPrefix + 'Transform';
96
+
97
+ this.endEvents = ['transitionend', 'webkitTransitionEnd',
98
+ 'oTransitionEnd', 'otransitionend', 'MSTransitionEnd'];
99
+ }
100
+
101
+ // detect touch and set slide speed to half for touch
102
+ this.touch = this.getTouch_();
103
+ if (this.touch) {
104
+ var speed = this.opts['effect']['slide']['speed'];
105
+ this.opts['effect']['slide']['speed'] = speed / 2;
106
+ }
107
+
108
+ // hide overflow
109
+ this.elem['style']['overflow'] = 'hidden';
110
+
111
+ // create container
112
+ this.container = goog.dom.createDom('div', this.namespace + '-container');
113
+ this.container['style']['overflow'] = 'hidden';
114
+ this.container['style']['position'] = 'relative';
115
+
116
+ // create control div
117
+ this.control = goog.dom.createDom('div', this.namespace + '-control');
118
+ this.control['style']['position'] = 'relative';
119
+ this.control['style']['left'] = 0;
120
+
121
+ goog.dom.appendChild(this.elem, this.container);
122
+ goog.dom.appendChild(this.container, this.control);
123
+
124
+ // setup slides
125
+ goog.array.forEach(this.slides, function(slide, index) {
126
+ slide['style']['position'] = 'absolute';
127
+ slide['style']['top'] = 0;
128
+ slide['style']['left'] = 0;
129
+ slide['style']['height'] = '100%';
130
+ slide['style']['width'] = '100%';
131
+ slide['style']['zIndex'] = 0;
132
+ slide['style']['display'] = 'none';
133
+ slide['style']['webkitBackfaceVisibility'] = 'hidden';
134
+
135
+ // assign an index to each slide
136
+ goog.dom.dataset.set(slide, 'index', index);
137
+ goog.dom.classes.add(slide, this.opts['slideClass'] + '-' + index);
138
+
139
+ // move slide to appropriate container
140
+ goog.dom.appendChild(this.control, goog.dom.removeNode(slide));
141
+ }, this);
142
+
143
+ if (this.touch) {
144
+ goog.events.listen(this.control, goog.events.EventType.TOUCHSTART,
145
+ function(e) {
146
+ self.touchstart(e);
147
+ }
148
+ );
149
+
150
+ goog.events.listen(this.control, goog.events.EventType.TOUCHMOVE,
151
+ function(e) {
152
+ self.touchmove(e);
153
+ }
154
+ );
155
+
156
+ goog.events.listen(this.control, goog.events.EventType.TOUCHEND,
157
+ function(e) {
158
+ self.touchend(e);
159
+ }
160
+ );
161
+ }
162
+
163
+ this.elem['style']['display'] = 'block';
164
+ this.elem['style']['opacity'] = '1';
165
+
166
+ if (this.touch) {
167
+ this.setupTouch_();
168
+ }
169
+
170
+ this.slides[this.current]['style']['display'] = 'block';
171
+ this.slides[this.current]['style']['zIndex'] = 10;
172
+ this.slides[this.current]['style']['opacity'] = 1;
173
+
174
+ if (this.opts['navigation']['active']) {
175
+ this.prevButton = goog.dom.createDom('a', {
176
+ 'class': this.namespace + '-previous ' + this.namespace + '-navigation',
177
+ 'href': '#',
178
+ 'title': 'Previous'
179
+ });
180
+
181
+ goog.dom.setTextContent(this.prevButton, 'Previous');
182
+ goog.dom.appendChild(this.elem, this.prevButton);
183
+
184
+ this.nextButton = goog.dom.createDom('a', {
185
+ 'class': this.namespace + '-next ' + this.namespace + '-navigation',
186
+ 'href': '#',
187
+ 'title': 'Next'
188
+ });
189
+
190
+ goog.dom.setTextContent(this.nextButton, 'Next');
191
+ goog.dom.appendChild(this.elem, this.nextButton);
192
+
193
+ goog.events.listen(this.prevButton, goog.events.EventType.CLICK,
194
+ function(e) {
195
+ e.preventDefault();
196
+ this.stop(true);
197
+ this.previous(this.opts['navigation']['effect']);
198
+ }, false, this);
199
+
200
+ goog.events.listen(this.nextButton, goog.events.EventType.CLICK,
201
+ function(e) {
202
+ e.preventDefault();
203
+ this.stop(true);
204
+ this.next(this.opts['navigation']['effect']);
205
+ }, false, this);
206
+ }
207
+
208
+ if (this.opts['play']['active']) {
209
+ this.playButton = goog.dom.createDom('a', {
210
+ 'class': this.namespace + '-play ' + this.namespace + '-navigation',
211
+ 'href': '#',
212
+ 'title': 'Play'
213
+ });
214
+
215
+ goog.dom.setTextContent(this.playButton, 'Play');
216
+ goog.dom.appendChild(this.elem, this.playButton);
217
+
218
+ this.stopButton = goog.dom.createDom('a', {
219
+ 'class': this.namespace + '-stop ' + this.namespace + '-navigation',
220
+ 'href': '#',
221
+ 'title': 'Stop'
222
+ });
223
+
224
+ goog.dom.setTextContent(this.stopButton, 'Stop');
225
+ goog.dom.appendChild(this.elem, this.stopButton);
226
+
227
+ goog.events.listen(this.playButton, goog.events.EventType.CLICK,
228
+ function(e) {
229
+ e.preventDefault();
230
+ this.play(true);
231
+ }, false, this);
232
+
233
+ goog.events.listen(this.stopButton, goog.events.EventType.CLICK,
234
+ function(e) {
235
+ e.preventDefault();
236
+ this.stop(true);
237
+ }, false, this);
238
+ }
239
+
240
+ if (this.opts['pagination']['active']) {
241
+ this.pagination = goog.dom.createDom('ul', this.namespace + '-pagination');
242
+ this.pagination['style']['zIndex'] = 100;
243
+ goog.dom.appendChild(this.elem, this.pagination);
244
+
245
+ for (var i = 0; i < this.total; i++) {
246
+ var li = goog.dom.createDom('li', this.namespace + '-pagination-item');
247
+ goog.dom.appendChild(this.pagination, li);
248
+
249
+ var a = goog.dom.createDom('a', this.namespace + '-pagination-link');
250
+ a['href'] = '#';
251
+
252
+ goog.dom.setTextContent(a, i + 1);
253
+ goog.dom.dataset.set(a, 'item', i);
254
+ goog.dom.appendChild(li, a);
255
+
256
+ goog.events.listen(a, goog.events.EventType.CLICK,
257
+ function(e) {
258
+ e.preventDefault();
259
+ var index = parseInt(
260
+ goog.dom.dataset.get(e.currentTarget, 'item'), 10);
261
+ self.stop(true);
262
+ self.goTo(index + 1);
263
+ });
264
+ }
265
+
266
+ this.pagers = goog.dom.getElementsByClass(
267
+ this.namespace + '-pagination-item', this.pagination);
268
+ }
269
+
270
+ // bind update on browser resize
271
+ goog.events.listen(window, goog.events.EventType.RESIZE, function(e) {
272
+ self.update_();
273
+ });
274
+
275
+ // set start pagination item to active
276
+ this.setActive_();
277
+
278
+ // auto play slideshow if so desired
279
+ if (this.opts['play']['auto']) {
280
+ this.play();
281
+ }
282
+
283
+ this.update_();
284
+
285
+ // slides are loaded
286
+ this.opts['callback']['loaded'](this.opts['start']);
287
+ };
288
+
289
+
290
+ /**
291
+ * Get current slide.
292
+ * @return {element} Returned element.
293
+ */
294
+ ww.Slides.prototype.getCurrentSlide = function() {
295
+ return this.slides[this.current];
296
+ };
297
+
298
+
299
+ /**
300
+ * Set current active in pagination.
301
+ * @param {number} number Index number to make active.
302
+ * @private
303
+ */
304
+ ww.Slides.prototype.setActive_ = function(number) {
305
+ var current = (number > -1) ? number : this.current;
306
+ var active = goog.dom.getElementByClass('active', this.pagination);
307
+
308
+ if (active) {
309
+ goog.dom.classes.remove(active, 'active');
310
+ }
311
+
312
+ goog.dom.classes.add(this.pagers[current], 'active');
313
+ };
314
+
315
+
316
+ /**
317
+ * Sets up previous and next slides during touch.
318
+ * @private
319
+ */
320
+ ww.Slides.prototype.setupTouch_ = function() {
321
+ var next = this.current + 1;
322
+ var prev = this.current - 1;
323
+
324
+ if (prev < 0) {
325
+ prev = this.total - 1;
326
+ }
327
+
328
+ if (next > this.total - 1) {
329
+ next = 0;
330
+ }
331
+
332
+ this.slides[next]['style']['display'] = 'block';
333
+ this.slides[next]['style']['opacity'] = 1;
334
+ this.slides[next]['style']['left'] = this.opts['width'] + 'px';
335
+ };
336
+
337
+
338
+ /**
339
+ * Touch start. Sets up touch related information.
340
+ * @param {Object} e Event object.
341
+ */
342
+ ww.Slides.prototype.touchstart = function(e) {
343
+ var touches = e && e.event_ && e.event_['targetTouches'];
344
+ if (!touches) { return; }
345
+ touches = touches[0];
346
+
347
+ this.setupTouch_();
348
+
349
+ // start touch timer
350
+ this.touchtimer = Number(new Date());
351
+
352
+ // set touch position
353
+ this.touchstartX = touches['pageX'];
354
+ this.touchstartY = touches['pageY'];
355
+
356
+ e.stopPropagation();
357
+ };
358
+
359
+
360
+ /**
361
+ * Touch move. Update touch related information.
362
+ * @param {Object} e Event object.
363
+ */
364
+ ww.Slides.prototype.touchmove = function(e) {
365
+ var touches = e && e.event_ && e.event_['targetTouches'];
366
+ if (!touches) { return; }
367
+ touches = touches[0];
368
+
369
+ this.scrolling_ = Math.abs(touches['pageX'] - this.touchstartX) <
370
+ Math.abs(touches['pageY'] - this.touchstartY);
371
+
372
+ // if not vertically scrolling
373
+ if (!this.animating && !this.scrolling_) {
374
+ e.preventDefault();
375
+ this.setupTouch_();
376
+ this.control['style'][this.transform_] = 'translateX(' +
377
+ (touches['pageX'] - this.touchstartX) + 'px)';
378
+ }
379
+
380
+ e.stopPropagation();
381
+ };
382
+
383
+
384
+ /**
385
+ * Touch end. Slide to previous or next depending on touch direction.
386
+ * Or snap to current slide if touch distance isn't enough.
387
+ * @param {Object} e Event object.
388
+ */
389
+ ww.Slides.prototype.touchend = function(e) {
390
+ var touches = e && e.event_ && e.event_['targetTouches'];
391
+ if (!touches) { return; }
392
+ touches = touches[0];
393
+
394
+ var left = goog.style.getRelativePosition(this.control, this.container)['x'];
395
+ if (left > this.opts['width'] * 0.5 ||
396
+ left > this.opts['width'] * 0.1 &&
397
+ (Number(new Date()) - this.touchtimer < 250)) {
398
+ this.direction = 'previous';
399
+ this.slide_();
400
+ } else if (left < -(this.opts['width'] * 0.5) ||
401
+ left < -(this.opts['width'] * 0.1) &&
402
+ (Number(new Date()) - this.touchtimer < 250)) {
403
+ this.direction = 'next';
404
+ this.slide_();
405
+ } else {
406
+ var speed = this.opts['effect']['slide']['speed'] * 0.85;
407
+ this.control['style'][this.transform_] = 'translateX(0px)';
408
+ this.control['style'][this.duration_] = speed + 'ms';
409
+ this.control['style'][this.timing_] = 'ease-out';
410
+ }
411
+
412
+ goog.events.listenOnce(this.control, this.endEvents, function() {
413
+ this.control['style'][this.transform_] = '';
414
+ this.control['style'][this.duration_] = '';
415
+ this.control['style'][this.timing_] = '';
416
+ }, false, this);
417
+
418
+ e.stopPropagation();
419
+ };
420
+
421
+
422
+ /**
423
+ * Hide all of the slides. Reset states.
424
+ * @private
425
+ */
426
+ ww.Slides.prototype.hideAll_ = function() {
427
+ // hide all slides except current
428
+ var self = this;
429
+ goog.array.forEach(this.slides, function(slide, index) {
430
+ if (self.current !== index) {
431
+ slide['style']['display'] = 'none';
432
+ slide['style']['left'] = 0;
433
+ slide['style']['opacity'] = 0;
434
+ slide['style']['zIndex'] = 0;
435
+ }
436
+ });
437
+ };
438
+
439
+
440
+ /**
441
+ * Update slide container and control sizing.
442
+ * @private
443
+ */
444
+ ww.Slides.prototype.update_ = function() {
445
+ this.hideAll_();
446
+
447
+ // get the new width and height
448
+ var width = goog.style.getSize(this.elem)['width'];
449
+ var height = (this.opts['height'] / this.opts['width']) * width + 'px';
450
+
451
+ // store dat
452
+ this.opts['width'] = width;
453
+ this.opts['height'] = height;
454
+
455
+ // update container and control
456
+ this.container['style']['width'] = width + 'px';
457
+ this.container['style']['height'] = height;
458
+
459
+ this.control['style']['width'] = width + 'px';
460
+ this.control['style']['height'] = height;
461
+ };
462
+
463
+
464
+ /**
465
+ * Play slides.
466
+ * @param {boolean} next Whether to advance to next slide.
467
+ */
468
+ ww.Slides.prototype.play = function(next) {
469
+ if (!this.playInterval) {
470
+ if (next) {
471
+ currentSlide = this.current;
472
+ this.direction = 'next';
473
+
474
+ if (this.opts['play']['effect'] === 'fade') {
475
+ this.fade_();
476
+ } else {
477
+ this.slide_();
478
+ }
479
+ }
480
+
481
+ var self = this;
482
+ this.playInterval = setInterval(function() {
483
+ currentSlide = self.current;
484
+ self.direction = 'next';
485
+
486
+ if (self.opts['play']['effect'] === 'fade') {
487
+ self.fade_();
488
+ } else {
489
+ self.slide_();
490
+ }
491
+ }, this.opts['play']['interval']);
492
+
493
+ if (this.opts['play']['pauseOnHover']) {
494
+ goog.events.removeAll(this.container);
495
+
496
+ goog.events.listen(this.container,
497
+ goog.events.EventType.MOUSEOVER, function(e) {
498
+ self.stop();
499
+ });
500
+
501
+ goog.events.listen(this.container,
502
+ goog.events.EventType.MOUSEOUT, function(e) {
503
+ if (self.opts['play']['restartDelay']) {
504
+ self.restartDelay = setTimeout(function() {
505
+ self.play(true);
506
+ }, self.opts['play']['restartDelay']);
507
+ } else {
508
+ self.play(false);
509
+ }
510
+ });
511
+ }
512
+
513
+ this.playing = true;
514
+ if (this.playButton) {
515
+ goog.dom.classes.add(this.playButton, this.namespace + '-playing');
516
+ }
517
+
518
+ if (this.opts['play']['swap'] && this.playButton && this.stopButton) {
519
+ this.playButton['style']['display'] = 'none';
520
+ this.stopButton['style']['display'] = 'block';
521
+ }
522
+ }
523
+ };
524
+
525
+
526
+ /**
527
+ * Stop slides.
528
+ * @param {boolean} clicked To pause or not to pause.
529
+ */
530
+ ww.Slides.prototype.stop = function(clicked) {
531
+ clearInterval(this.playInterval);
532
+
533
+ if (this.opts['play']['pauseOnHover'] && clicked) {
534
+ goog.events.removeAll(this.container);
535
+ }
536
+
537
+ this.playInterval = null;
538
+ this.playing = false;
539
+
540
+ if (this.playButton) {
541
+ goog.dom.classes.remove(this.playButton, this.namespace + '-playing');
542
+ }
543
+
544
+ if (this.opts['play']['swap'] && this.playButton && this.stopButton) {
545
+ this.playButton['style']['display'] = 'block';
546
+ this.stopButton['style']['display'] = 'none';
547
+ }
548
+ };
549
+
550
+
551
+ /**
552
+ * Advance to next slide.
553
+ * @param {String} effect Desired effect.
554
+ */
555
+ ww.Slides.prototype.next = function(effect) {
556
+ this.direction = 'next';
557
+
558
+ if (effect === void 0) {
559
+ effect = this.opts['navigation']['effect'];
560
+ }
561
+
562
+ if (effect === 'fade') {
563
+ this.fade_();
564
+ } else {
565
+ this.slide_();
566
+ }
567
+ };
568
+
569
+
570
+ /**
571
+ * Advance to previous slide.
572
+ * @param {String} effect Desired effect.
573
+ */
574
+ ww.Slides.prototype.previous = function(effect) {
575
+ this.direction = 'previous';
576
+
577
+ if (effect === void 0) {
578
+ effect = this.opts['navigation']['effect'];
579
+ }
580
+
581
+ if (effect === 'fade') {
582
+ this.fade_();
583
+ } else {
584
+ this.slide_();
585
+ }
586
+ };
587
+
588
+
589
+ /**
590
+ * Advance to a given slide number.
591
+ * @param {Number|String} number Desired go to slide number.
592
+ */
593
+ ww.Slides.prototype.goTo = function(number) {
594
+ if (number > this.total) {
595
+ number = this.total;
596
+ } else if (number < 1) {
597
+ number = 1;
598
+ }
599
+
600
+ if (typeof number === 'number') {
601
+ if (this.opts['pagination']['effect'] === 'fade') {
602
+ this.fade_(number);
603
+ } else {
604
+ this.slide_(number);
605
+ }
606
+ } else if (typeof number === 'string') {
607
+ var index;
608
+
609
+ if (number.toLowerCase() === 'first') {
610
+ index = 0;
611
+ } else if (number.toLowerCase() === 'last') {
612
+ index = this.total;
613
+ }
614
+
615
+ if (this.opts['pagination']['effect'] === 'fade') {
616
+ this.fade_(index);
617
+ } else {
618
+ this.slide_(index);
619
+ }
620
+ }
621
+ };
622
+
623
+
624
+ /**
625
+ * Slide animation.
626
+ * @param {number} number Desired slide number.
627
+ * @private
628
+ */
629
+ ww.Slides.prototype.slide_ = function(number) {
630
+ if (!this.animating && number !== this.current + 1) {
631
+ this.animating = true;
632
+
633
+ var currentSlide = this.current;
634
+ var value, direction, next;
635
+
636
+ if (number > -1) {
637
+ number = number - 1;
638
+ if (number > currentSlide) {
639
+ value = 1;
640
+ direction = -this.opts['width'];
641
+ } else {
642
+ value = -1;
643
+ direction = this.opts['width'];
644
+ }
645
+
646
+ next = number;
647
+ } else {
648
+ if (this.direction === 'next') {
649
+ value = 1;
650
+ direction = -this.opts['width'];
651
+ } else {
652
+ value = -1;
653
+ direction = this.opts['width'];
654
+ }
655
+
656
+ next = currentSlide + value;
657
+ }
658
+
659
+ if (next === -1) {
660
+ next = this.total - 1;
661
+ }
662
+
663
+ if (next === this.total) {
664
+ next = 0;
665
+ }
666
+
667
+ this.setActive_(next);
668
+
669
+ if (number > -1) {
670
+ // hide all except current
671
+ this.hideAll_();
672
+ }
673
+
674
+ // setup next slide
675
+ this.slides[next]['style']['display'] = 'block';
676
+ this.slides[next]['style']['left'] = value * this.opts['width'] + 'px';
677
+ this.slides[next]['style']['opacity'] = 1;
678
+ this.slides[next]['style']['zIndex'] = 10;
679
+
680
+ this.opts['callback']['start'](currentSlide + 1);
681
+
682
+ if (this.vendorPrefix) {
683
+ var speed = this.opts['effect']['slide']['speed'];
684
+ var trans = 'translateX(' + direction + 'px)';
685
+ this.control['style'][this.transform_] = trans;
686
+ this.control['style'][this.duration_] = speed + 'ms';
687
+ this.control['style'][this.timing_] = 'ease-out';
688
+
689
+ goog.events.listenOnce(this.control, this.endEvents, function() {
690
+ this.control['style'][this.transform_] = '';
691
+ this.control['style'][this.duration_] = '';
692
+ this.control['style'][this.timing_] = '';
693
+
694
+ this.slides[next]['style']['left'] = 0;
695
+ this.slides[currentSlide]['style']['display'] = 'none';
696
+ this.slides[currentSlide]['style']['left'] = 0;
697
+ this.slides[currentSlide]['style']['zIndex'] = 0;
698
+
699
+ this.current = next;
700
+ this.animating = false;
701
+
702
+ this.hideAll_();
703
+ if (this.touch) {
704
+ this.setupTouch_();
705
+ }
706
+
707
+ this.opts['callback']['complete'](next + 1);
708
+ }, false, this);
709
+ } else {
710
+ // CSS3 transform fallback
711
+ var self = this;
712
+ var left = parseInt(this.control['style']['left'], 10),
713
+
714
+ move = new ww.Tween({ 'left': left });
715
+ move.to({ 'left': direction }, this.opts['effect']['slide']['speed']);
716
+ move.onUpdate(function() {
717
+ self.control['style']['left'] = this['left'];
718
+ });
719
+ move.onComplete(function() {
720
+ self.control['style']['left'] = 0;
721
+ self.slides[next]['style']['left'] = 0;
722
+
723
+ self.slides[currentSlide]['style']['display'] = 'none';
724
+ self.slides[currentSlide]['style']['left'] = 0;
725
+ self.slides[currentSlide]['style']['zIndex'] = 0;
726
+
727
+ self.current = next;
728
+ self.animating = false;
729
+ self.opts['callback']['complete'](next + 1);
730
+ });
731
+ move.start();
732
+ }
733
+ }
734
+ };
735
+
736
+
737
+ /**
738
+ * Fade and cross-fade animation.
739
+ * @param {number} number Desired slide number.
740
+ * @private
741
+ */
742
+ ww.Slides.prototype.fade_ = function(number) {
743
+ if (!this.animating && number !== this.current + 1) {
744
+ this.animating = true;
745
+
746
+ var self = this;
747
+ var currentSlide = this.current;
748
+ var next, value;
749
+
750
+ if (number) {
751
+ number = number - 1;
752
+ value = number > currentSlide ? 1 : -1;
753
+ next = number;
754
+ } else {
755
+ value = this.direction === 'next' ? 1 : -1;
756
+ next = currentSlide + value;
757
+ }
758
+
759
+ if (next === -1) {
760
+ next = this.total - 1;
761
+ }
762
+
763
+ if (next === this.total) {
764
+ next = 0;
765
+ }
766
+
767
+ this.setActive_(next);
768
+
769
+ this.hideAll_();
770
+ this.slides[next]['style']['zIndex'] = 10;
771
+
772
+ this.opts['callback']['start'](currentSlide + 1);
773
+
774
+ var currentOpacity = this.slides[currentSlide]['style']['opacity'] || 1;
775
+
776
+ var fadeIn = new ww.Tween({ 'opacity': 0 });
777
+ fadeIn.to({ 'opacity': 1 }, self.opts['effect']['fade']['speed']);
778
+ fadeIn.onStart(function() {
779
+ self.slides[next]['style']['display'] = 'block';
780
+ });
781
+ fadeIn.onUpdate(function() {
782
+ self.slides[next]['style']['opacity'] = this['opacity'];
783
+ });
784
+ fadeIn.onComplete(function() {
785
+ self.slides[next]['style']['zIndex'] = 10;
786
+ self.animating = false;
787
+ self.current = next;
788
+
789
+ self.opts['callback']['complete'](next + 1);
790
+ });
791
+
792
+ var fadeOut = new ww.Tween({ 'opacity': parseInt(currentOpacity, 10) });
793
+ fadeOut.to({ 'opacity': 0 }, self.opts['effect']['fade']['speed']);
794
+ fadeOut.onUpdate(function() {
795
+ self.slides[currentSlide]['style']['opacity'] = this['opacity'];
796
+ });
797
+ fadeOut.onComplete(function() {
798
+ self.slides[currentSlide]['style']['zIndex'] = 0;
799
+
800
+ if (!self.opts['effect']['fade']['crossfade']) {
801
+ fadeIn.start();
802
+ }
803
+ });
804
+
805
+ if (this.opts['effect']['fade']['crossfade']) {
806
+ fadeOut.start();
807
+ fadeIn.start();
808
+ } else {
809
+ fadeOut.start();
810
+ }
811
+ }
812
+ };
813
+
814
+
815
+ /**
816
+ * Return vendor prefix. Check if the browser supports CSS3 Transitions.
817
+ * @private
818
+ * @return {String} The vendor prefix.
819
+ */
820
+ ww.Slides.prototype.getVendorPrefix_ = function() {
821
+ var body, i, style, transition, vendor;
822
+ body = document.body || document.documentElement;
823
+ style = body.style;
824
+ transition = 'transition';
825
+ vendor = ['Moz', 'Webkit', 'Khtml', 'O', 'ms', 'MS'];
826
+ transition = transition.charAt(0).toUpperCase() + transition.substr(1);
827
+ i = 0;
828
+ while (i < vendor.length) {
829
+ if (typeof style[vendor[i] + transition] === 'string') {
830
+ return vendor[i];
831
+ }
832
+ i++;
833
+ }
834
+ return false;
835
+ };
836
+
837
+
838
+ /**
839
+ * Detect touch support.
840
+ * @private
841
+ * @return {Boolean} If there is touch support.
842
+ */
843
+ ww.Slides.prototype.getTouch_ = function() {
844
+ return (typeof TouchEvent !== "undefined") ||
845
+ (window['ontouchstart'] !== undefined);
846
+ };