1/* 2 Slideshow Plugin for Bondware 3 Author: Ethan Basham 4 Date: August 7th, 2018 5*/ 6 7;( function( $, window, document, undefined ) { 8 "use strict"; 9 10 var pluginName = "bw_slideshow"; 11 var defaults = { 12 slides: [], 13 animation: 'slide', 14 ratio: '4:3', 15 max_width: '100%', 16 animation_duration: 500, 17 animation_interval: 7000, 18 pause_on_hover: true, 19 responsive: true, 20 auto_play: true, 21 hide_buttons: false 22 }; 23 24 function bw_slideshow(element, options) { 25 this.options = $.extend( true, {}, defaults, options ); 26 27 this.parent = $(element); 28 this.element_wrapper = $('<div class="bw_slideshow-wrapper"></div>').appendTo(this.parent); 29 this.element = $('<div class="bw_slideshow"></div>').appendTo(this.element_wrapper); 30 this.element_track = $('<div class="bw_slideshow-track"></div>').appendTo(this.element); 31 32 this.element_arrow_prev = $('<a href="#" class="bw_slideshow-arrow bw_slideshow-arrow-left bw-btn">'+ 33 '<i class="fa fa-chevron-left" aria-hidden="true"></a>'); 34 this.element_arrow_next = $('<a href="#" class="bw_slideshow-arrow bw_slideshow-arrow-right bw-btn">'+ 35 '<i class="fa fa-chevron-right" aria-hidden="true"></a>'); 36 37 // Mutable Options 38 this.slides = []; 39 this.ratio = this.options.ratio; 40 this.max_width = this.options.max_width; 41 this.animation_interval = Number(this.options.animation_interval) + Number(this.options.animation_duration); 42 this.animation_duration = this.options.animation_duration; 43 this.auto_play = this.options.auto_play; 44 this.pause_on_hover = this.options.pause_on_hover; 45 this.hide_buttons = this.options.hide_buttons; 46 this.responsive = this.options.responsive; 47 48 this.active_slide = 1; 49 this.width = 0; 50 this.offset = 0; 51 this.state = 'stable'; 52 this.auto_interval = undefined; 53 this.paused = true; 54 this.init(); 55 } 56 $.extend(bw_slideshow.prototype, { 57 init: function() { 58 var self = this; 59 60 self.set('ratio', self.ratio); 61 self.set('max_width', self.max_width); 62 63 for (var i = 0, len = self.options.slides.length; i < len; i++) { 64 self.add_slide(self.options.slides[i]); 65 } 66 self.revert_to_start(); 67 68 self.initEventListeners(); 69 setTimeout(function() {self.resize();}, 0); 70 71 if (self.auto_play) self.play(); 72 }, 73 initEventListeners: function() { 74 var self = this; 75 76 // Previous 77 self.element_arrow_prev.click(function(e) { 78 e.preventDefault(); 79 self.action_animate(-1); 80 if (!self.paused) self.play(); 81 }); 82 83 // Next 84 self.element_arrow_next.click(function(e) { 85 e.preventDefault(); 86 self.action_animate(1); 87 if (!self.paused) self.play(); 88 }); 89 90 self.set('hide_buttons', self.hide_buttons); 91 self.set('pause_on_hover', self.pause_on_hover); 92 self.set('responsive', self.responsive); 93 }, 94 set: function(field, val) { 95 var self = this; 96 97 98 function soft_debounce(f, d) { 99 var wait = false; 100 return function() { 101 if (!wait) { 102 setTimeout(function () { f(); wait = false; }, d); wait = true; 103 } 104 }; 105 } 106 function hard_debounce(f, d) { 107 var timeout; 108 return function() { 109 clearTimeout(timeout); 110 timeout = setTimeout(function () { f(); }, d); 111 }; 112 } 113 114 switch (field) { 115 case 'ratio': 116 self.ratio = val; 117 var nums = self.ratio.split(':'); 118 self.padding_top = Number(nums[1]) / Number(nums[0]) * 100; 119 self.element.css('padding-top', self.padding_top+'%'); 120 self.resize(); 121 break; 122 case 'max_width': 123 self.max_width = val; 124 self.element_wrapper.css('max-width', self.max_width); 125 self.width = self.element.width(); 126 self.resize(); 127 break; 128 case 'animation_duration': 129 self.animation_interval -= self.animation_duration; 130 self.animation_duration = Number(val); 131 self.animation_interval += self.animation_duration; 132 self.pause(); if (self.auto_play) self.play(); 133 break; 134 case 'animation_interval': 135 self.animation_interval = Number(val) + Number(self.animation_duration); 136 self.pause(); if (self.auto_play) self.play(); 137 break; 138 case 'pause_on_hover': 139 self.pause_on_hover = val; 140 if (self.pause_on_hover) { 141 self.element.hover(function() { 142 self.pause(); 143 }, function() { 144 if (self.auto_play) { 145 self.play(); 146 } 147 }); 148 } else { 149 self.element.unbind('mouseenter mouseleave'); 150 } 151 break; 152 case 'auto_play': 153 self.auto_play = val; 154 self.pause(); if (self.auto_play) self.play(); 155 break; 156 case 'hide_buttons': 157 self.hide_buttons = val; 158 if (self.hide_buttons) { 159 self.element_arrow_prev.detach();
160 self.element_arrow_next.detach(); 161 } else { 162 self.element_arrow_prev.appendTo(self.element); 163 self.element_arrow_next.appendTo(self.element); 164 } 165 break; 166 case 'responsive': 167 self.responsive = val; 168 if (self.responsive) { 169 $(window).resize(function() { self.resize(); }); 170 } else { 171 172 } 173 break; 174 } 175 }, 176 add_slide: function(obj) { 177 var self = this; 178 179 self.slides.push(new bw_slide(self, obj)); 180 self.reset_clones(); 181 self.reset_track_width(); 182 }, 183 reset_track_width: function() { 184 var self = this; 185 186 self.element_track.css({ 187 'width': self.element_track.children().length * self.width+'px', 188 'transition': '', 189 'transform': 'translate3d(-'+(self.active_slide*self.width)+'px, 0px, 0px)' 190 }); 191 }, 192 action_animate: function(direction) { 193 var self = this; 194 195 if (self.state != 'stable') return; 196 197 self.state = 'animating'; 198 if (direction == 1) { 199 self.active_slide++; 200 self.element_track.css({ 201 'transition': 'transform '+self.animation_duration+'ms ease 0s', 202 'transform': 'translate3d(-'+(self.active_slide*self.width)+'px, 0px, 0px)' 203 }); 204 if ((self.element_track.children().length-1) == self.active_slide) { 205 setTimeout(function() { 206 self.active_slide = 1; 207 self.revert_to_start(); 208 }, self.animation_duration); 209 } 210 } else { 211 self.active_slide--; 212 self.element_track.css({ 213 'transition': 'transform '+self.animation_duration+'ms ease 0s', 214 'transform': 'translate3d(-'+(self.active_slide*self.width)+'px, 0px, 0px)' 215 }); 216 if (!self.active_slide) { 217 setTimeout(function() { 218 self.active_slide = self.element_track.children().length-2; 219 self.revert_to_end(); 220 }, self.animation_duration); 221 } 222 } 223 setTimeout(function() { self.state = 'stable'; }, self.animation_duration); 224 }, 225 reset_clones: function() { 226 var self = this; 227 228 self.element_track.children('.bw_slideshow-clone').remove(); 229 230 var start_clone = self.element_track.children().first().clone().addClass('bw_slideshow-clone'); 231 var end_clone = self.element_track.children().last().clone().addClass('bw_slideshow-clone'); 232 233 start_clone.appendTo(self.element_track); 234 end_clone.prependTo(self.element_track); 235 236 var children = self.element_track.children().length; 237 var percent = 1 / children * 100; 238 self.element_track.children().width(percent+'%'); 239 240 self.revert_to_start(); 241 }, 242 revert_to_start: function() { 243 var self = this; 244 245 self.element_track.css({ 246 'transition': '', 247 'transform': 'translate3d(-'+(self.active_slide*self.width)+'px, 0px, 0px)' 248 }); 249 }, 250 revert_to_end: function() { 251 var self = this; 252 253 self.element_track.css({ 254 'transition': '', 255 'transform': 'translate3d(-'+(self.active_slide*self.width)+'px, 0px, 0px)' 256 }); 257 }, 258 pause: function() { 259 var self = this; 260 261 self.paused = true; 262 clearInterval(self.auto_interval); 263 }, 264 play: function() { 265 var self = this; 266 267 self.paused = false; 268 clearInterval(self.auto_interval); 269 270 self.auto_interval = setInterval(function () { 271 self.action_animate(1); 272 }, self.animation_interval); 273 }, 274 stop: function() { 275 var self = this; 276 277 self.auto_play = false;
278 self.pause(); 279 }, 280 resize: function() { 281 var self = this; 282 283 self.width = self.element.width(); 284 self.reset_track_width(); 285 }, 286 }); 287 288 function bw_slide(parent, options) { 289 this.options = $.extend( true, {}, { url:"", caption:"", link:"", link_no_follow:false, link_new_page:true }, options ); 290 this.url = this.options.url; 291 this.caption = this.options.caption; 292 this.alt_text = this.options.alt_text; 293 this.link = this.options.link; 294 295 this.parent = parent; 296 this.element_wrapper = $('<figure class="bw_slideshow-slide-wrapper"></figure>').appendTo(this.parent.element_track); 297 this.element_helper = $('<span class="bw_slideshow-helper"></span>').appendTo(this.element_wrapper); 298 if (this.caption) { 299 this.element_caption = $('<div class="bw_slideshow-caption-wrapper">'+ 300 '<span class="bw_slideshow-caption">'+this.caption+'</span>'+ 301 '</div>').appendTo(this.element_wrapper); 302 } 303 this.element = $('<img class="bw_slideshow-slide" src="'+this.url+'" alt="'+this.alt_text+'"/>').appendTo(this.element_wrapper); 304 if (this.link) { 305 var link_ops = this.options.link_new_page ? ' target="_blank" ' : ''; 306 if (this.options.link_no_follow) link_ops += ' rel="nofollow" '; 307 if (this.caption) { 308 this.element_caption.wrap('<a href="'+this.link+'" '+link_ops+'></a>'); 309 } else { 310 this.element.wrap('<a href="'+this.link+'" '+link_ops+'></a>'); 311 } 312 } 313 } 314 $.extend(bw_slide.prototype, { 315 set: function(field, val) { 316 var self = this; 317 318 self[field] = val; 319 return self; 320 } 321 }); 322 323 $.fn[ pluginName ] = function(options) { 324 if (options === undefined) options = {}; 325 return this.each( function() { 326 if ( !$.data( this, "plugin_" + pluginName ) ) { 327 $.data( this, "plugin_" + pluginName, new bw_slideshow( this, options ) ); 328 } 329 } ); 330 }; 331} )( jQuery, window, document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.