diff options
Diffstat (limited to 'js/components/slider.js')
| -rwxr-xr-x | js/components/slider.js | 540 |
1 files changed, 540 insertions, 0 deletions
diff --git a/js/components/slider.js b/js/components/slider.js new file mode 100755 index 0000000..f89b588 --- /dev/null +++ b/js/components/slider.js | |||
| @@ -0,0 +1,540 @@ | |||
| 1 | /*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ | ||
| 2 | (function(addon) { | ||
| 3 | |||
| 4 | var component; | ||
| 5 | |||
| 6 | if (window.UIkit) { | ||
| 7 | component = addon(UIkit); | ||
| 8 | } | ||
| 9 | |||
| 10 | if (typeof define == "function" && define.amd) { | ||
| 11 | define("uikit-slider", ["uikit"], function(){ | ||
| 12 | return component || addon(UIkit); | ||
| 13 | }); | ||
| 14 | } | ||
| 15 | |||
| 16 | })(function(UI){ | ||
| 17 | |||
| 18 | "use strict"; | ||
| 19 | |||
| 20 | var dragging, delayIdle, anchor, dragged, store = {}; | ||
| 21 | |||
| 22 | UI.component('slider', { | ||
| 23 | |||
| 24 | defaults: { | ||
| 25 | center : false, | ||
| 26 | threshold : 10, | ||
| 27 | infinite : true, | ||
| 28 | autoplay : false, | ||
| 29 | autoplayInterval : 7000, | ||
| 30 | pauseOnHover : true, | ||
| 31 | activecls : 'uk-active' | ||
| 32 | }, | ||
| 33 | |||
| 34 | boot: function() { | ||
| 35 | |||
| 36 | // init code | ||
| 37 | UI.ready(function(context) { | ||
| 38 | |||
| 39 | setTimeout(function(){ | ||
| 40 | |||
| 41 | UI.$('[data-uk-slider]', context).each(function(){ | ||
| 42 | |||
| 43 | var ele = UI.$(this); | ||
| 44 | |||
| 45 | if (!ele.data('slider')) { | ||
| 46 | UI.slider(ele, UI.Utils.options(ele.attr('data-uk-slider'))); | ||
| 47 | } | ||
| 48 | }); | ||
| 49 | |||
| 50 | }, 0); | ||
| 51 | }); | ||
| 52 | }, | ||
| 53 | |||
| 54 | init: function() { | ||
| 55 | |||
| 56 | var $this = this; | ||
| 57 | |||
| 58 | this.container = this.element.find('.uk-slider'); | ||
| 59 | this.focus = 0; | ||
| 60 | |||
| 61 | UI.$win.on('resize load', UI.Utils.debounce(function() { | ||
| 62 | $this.resize(true); | ||
| 63 | }, 100)); | ||
| 64 | |||
| 65 | this.on('click.uk.slider', '[data-uk-slider-item]', function(e) { | ||
| 66 | |||
| 67 | e.preventDefault(); | ||
| 68 | |||
| 69 | var item = UI.$(this).attr('data-uk-slider-item'); | ||
| 70 | |||
| 71 | if ($this.focus == item) return; | ||
| 72 | |||
| 73 | // stop autoplay | ||
| 74 | $this.stop(); | ||
| 75 | |||
| 76 | switch(item) { | ||
| 77 | case 'next': | ||
| 78 | case 'previous': | ||
| 79 | $this[item=='next' ? 'next':'previous'](); | ||
| 80 | break; | ||
| 81 | default: | ||
| 82 | $this.updateFocus(parseInt(item, 10)); | ||
| 83 | } | ||
| 84 | }); | ||
| 85 | |||
| 86 | this.container.on({ | ||
| 87 | |||
| 88 | 'touchstart mousedown': function(evt) { | ||
| 89 | |||
| 90 | if (evt.originalEvent && evt.originalEvent.touches) { | ||
| 91 | evt = evt.originalEvent.touches[0]; | ||
| 92 | } | ||
| 93 | |||
| 94 | // ignore right click button | ||
| 95 | if (evt.button && evt.button==2 || !$this.active) { | ||
| 96 | return; | ||
| 97 | } | ||
| 98 | |||
| 99 | // stop autoplay | ||
| 100 | $this.stop(); | ||
| 101 | |||
| 102 | anchor = UI.$(evt.target).is('a') ? UI.$(evt.target) : UI.$(evt.target).parents('a:first'); | ||
| 103 | dragged = false; | ||
| 104 | |||
| 105 | if (anchor.length) { | ||
| 106 | |||
| 107 | anchor.one('click', function(e){ | ||
| 108 | if (dragged) e.preventDefault(); | ||
| 109 | }); | ||
| 110 | } | ||
| 111 | |||
| 112 | delayIdle = function(e) { | ||
| 113 | |||
| 114 | dragged = true; | ||
| 115 | dragging = $this; | ||
| 116 | store = { | ||
| 117 | touchx : parseInt(e.pageX, 10), | ||
| 118 | dir : 1, | ||
| 119 | focus : $this.focus, | ||
| 120 | base : $this.options.center ? 'center':'area' | ||
| 121 | }; | ||
| 122 | |||
| 123 | if (e.originalEvent && e.originalEvent.touches) { | ||
| 124 | e = e.originalEvent.touches[0]; | ||
| 125 | } | ||
| 126 | |||
| 127 | dragging.element.data({ | ||
| 128 | 'pointer-start': {x: parseInt(e.pageX, 10), y: parseInt(e.pageY, 10)}, | ||
| 129 | 'pointer-pos-start': $this.pos | ||
| 130 | }); | ||
| 131 | |||
| 132 | $this.container.addClass('uk-drag'); | ||
| 133 | |||
| 134 | delayIdle = false; | ||
| 135 | }; | ||
| 136 | |||
| 137 | delayIdle.x = parseInt(evt.pageX, 10); | ||
| 138 | delayIdle.threshold = $this.options.threshold; | ||
| 139 | |||
| 140 | }, | ||
| 141 | |||
| 142 | mouseenter: function() { if ($this.options.pauseOnHover) $this.hovering = true; }, | ||
| 143 | mouseleave: function() { $this.hovering = false; } | ||
| 144 | }); | ||
| 145 | |||
| 146 | this.resize(true); | ||
| 147 | |||
| 148 | this.on('display.uk.check', function(){ | ||
| 149 | if ($this.element.is(":visible")) { | ||
| 150 | $this.resize(true); | ||
| 151 | } | ||
| 152 | }); | ||
| 153 | |||
| 154 | // prevent dragging links + images | ||
| 155 | this.element.find('a,img').attr('draggable', 'false'); | ||
| 156 | |||
| 157 | // Set autoplay | ||
| 158 | if (this.options.autoplay) { | ||
| 159 | this.start(); | ||
| 160 | } | ||
| 161 | |||
| 162 | }, | ||
| 163 | |||
| 164 | resize: function(focus) { | ||
| 165 | |||
| 166 | var $this = this, pos = 0, maxheight = 0, item, width, cwidth, size; | ||
| 167 | |||
| 168 | this.items = this.container.children().filter(':visible'); | ||
| 169 | this.vp = this.element[0].getBoundingClientRect().width; | ||
| 170 | |||
| 171 | this.container.css({'min-width': '', 'min-height': ''}); | ||
| 172 | |||
| 173 | this.items.each(function(idx){ | ||
| 174 | |||
| 175 | item = UI.$(this); | ||
| 176 | size = item.css({'left': '', 'width':''})[0].getBoundingClientRect(); | ||
| 177 | width = size.width; | ||
| 178 | cwidth = item.width(); | ||
| 179 | maxheight = Math.max(maxheight, size.height); | ||
| 180 | |||
| 181 | item.css({'left': pos, 'width':width}).data({'idx':idx, 'left': pos, 'width': width, 'cwidth':cwidth, 'area': (pos+width), 'center':(pos - ($this.vp/2 - cwidth/2))}); | ||
| 182 | |||
| 183 | pos += width; | ||
| 184 | }); | ||
| 185 | |||
| 186 | this.container.css({'min-width': pos, 'min-height': maxheight}); | ||
| 187 | |||
| 188 | if (this.options.infinite && (pos <= (2*this.vp) || this.items.length < 5) && !this.itemsResized) { | ||
| 189 | |||
| 190 | // fill with cloned items | ||
| 191 | this.container.children().each(function(idx){ | ||
| 192 | $this.container.append($this.items.eq(idx).clone(true).attr('id', '')); | ||
| 193 | }).each(function(idx){ | ||
| 194 | $this.container.append($this.items.eq(idx).clone(true).attr('id', '')); | ||
| 195 | }); | ||
| 196 | |||
| 197 | this.itemsResized = true; | ||
| 198 | |||
| 199 | return this.resize(); | ||
| 200 | } | ||
| 201 | |||
| 202 | this.cw = pos; | ||
| 203 | this.pos = 0; | ||
| 204 | this.active = pos >= this.vp; | ||
| 205 | |||
| 206 | this.container.css({ | ||
| 207 | '-ms-transform': '', | ||
| 208 | '-webkit-transform': '', | ||
| 209 | 'transform': '' | ||
| 210 | }); | ||
| 211 | |||
| 212 | if (focus) this.updateFocus(this.focus); | ||
| 213 | }, | ||
| 214 | |||
| 215 | updatePos: function(pos) { | ||
| 216 | this.pos = pos; | ||
| 217 | this.container.css({ | ||
| 218 | '-ms-transform': 'translateX('+pos+'px)', | ||
| 219 | '-webkit-transform': 'translateX('+pos+'px)', | ||
| 220 | 'transform': 'translateX('+pos+'px)' | ||
| 221 | }); | ||
| 222 | }, | ||
| 223 | |||
| 224 | updateFocus: function(idx, dir) { | ||
| 225 | |||
| 226 | if (!this.active) { | ||
| 227 | return; | ||
| 228 | } | ||
| 229 | |||
| 230 | dir = dir || (idx > this.focus ? 1:-1); | ||
| 231 | |||
| 232 | var item = this.items.eq(idx), area, i; | ||
| 233 | |||
| 234 | if (this.options.infinite) { | ||
| 235 | this.infinite(idx, dir); | ||
| 236 | } | ||
| 237 | |||
| 238 | if (this.options.center) { | ||
| 239 | |||
| 240 | this.updatePos(item.data('center')*-1); | ||
| 241 | |||
| 242 | this.items.filter('.'+this.options.activecls).removeClass(this.options.activecls); | ||
| 243 | item.addClass(this.options.activecls); | ||
| 244 | |||
| 245 | } else { | ||
| 246 | |||
| 247 | if (this.options.infinite) { | ||
| 248 | |||
| 249 | this.updatePos(item.data('left')*-1); | ||
| 250 | |||
| 251 | } else { | ||
| 252 | |||
| 253 | area = 0; | ||
| 254 | |||
| 255 | for (i=idx;i<this.items.length;i++) { | ||
| 256 | area += this.items.eq(i).data('width'); | ||
| 257 | } | ||
| 258 | |||
| 259 | |||
| 260 | if (area > this.vp) { | ||
| 261 | |||
| 262 | this.updatePos(item.data('left')*-1); | ||
| 263 | |||
| 264 | } else { | ||
| 265 | |||
| 266 | if (dir == 1) { | ||
| 267 | |||
| 268 | area = 0; | ||
| 269 | |||
| 270 | for (i=this.items.length-1;i>=0;i--) { | ||
| 271 | |||
| 272 | area += this.items.eq(i).data('width'); | ||
| 273 | |||
| 274 | if (area == this.vp) { | ||
| 275 | idx = i; | ||
| 276 | break; | ||
| 277 | } | ||
| 278 | |||
| 279 | if (area > this.vp) { | ||
| 280 | idx = (i < this.items.length-1) ? i+1 : i; | ||
| 281 | break; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | if (area > this.vp) { | ||
| 286 | this.updatePos((this.container.width() - this.vp) * -1); | ||
| 287 | } else { | ||
| 288 | this.updatePos(this.items.eq(idx).data('left')*-1); | ||
| 289 | } | ||
| 290 | } | ||
| 291 | } | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | // mark elements | ||
| 296 | var left = this.items.eq(idx).data('left'); | ||
| 297 | |||
| 298 | this.items.removeClass('uk-slide-before uk-slide-after').each(function(i){ | ||
| 299 | if (i!==idx) { | ||
| 300 | UI.$(this).addClass(UI.$(this).data('left') < left ? 'uk-slide-before':'uk-slide-after'); | ||
| 301 | } | ||
| 302 | }); | ||
| 303 | |||
| 304 | this.focus = idx; | ||
| 305 | |||
| 306 | this.trigger('focusitem.uk.slider', [idx,this.items.eq(idx),this]); | ||
| 307 | }, | ||
| 308 | |||
| 309 | next: function() { | ||
| 310 | |||
| 311 | var focus = this.items[this.focus + 1] ? (this.focus + 1) : (this.options.infinite ? 0:this.focus); | ||
| 312 | |||
| 313 | this.updateFocus(focus, 1); | ||
| 314 | }, | ||
| 315 | |||
| 316 | previous: function() { | ||
| 317 | |||
| 318 | var focus = this.items[this.focus - 1] ? (this.focus - 1) : (this.options.infinite ? (this.items[this.focus - 1] ? this.items-1:this.items.length-1):this.focus); | ||
| 319 | |||
| 320 | this.updateFocus(focus, -1); | ||
| 321 | }, | ||
| 322 | |||
| 323 | start: function() { | ||
| 324 | |||
| 325 | this.stop(); | ||
| 326 | |||
| 327 | var $this = this; | ||
| 328 | |||
| 329 | this.interval = setInterval(function() { | ||
| 330 | if (!$this.hovering) $this.next(); | ||
| 331 | }, this.options.autoplayInterval); | ||
| 332 | |||
| 333 | }, | ||
| 334 | |||
| 335 | stop: function() { | ||
| 336 | if (this.interval) clearInterval(this.interval); | ||
| 337 | }, | ||
| 338 | |||
| 339 | infinite: function(baseidx, direction) { | ||
| 340 | |||
| 341 | var $this = this, item = this.items.eq(baseidx), i, z = baseidx, move = [], area = 0; | ||
| 342 | |||
| 343 | if (direction == 1) { | ||
| 344 | |||
| 345 | |||
| 346 | for (i=0;i<this.items.length;i++) { | ||
| 347 | |||
| 348 | if (z != baseidx) { | ||
| 349 | area += this.items.eq(z).data('width'); | ||
| 350 | move.push(this.items.eq(z)); | ||
| 351 | } | ||
| 352 | |||
| 353 | if (area > this.vp) { | ||
| 354 | break; | ||
| 355 | } | ||
| 356 | |||
| 357 | z = z+1 == this.items.length ? 0:z+1; | ||
| 358 | } | ||
| 359 | |||
| 360 | if (move.length) { | ||
| 361 | |||
| 362 | move.forEach(function(itm){ | ||
| 363 | |||
| 364 | var left = item.data('area'); | ||
| 365 | |||
| 366 | itm.css({'left': left}).data({ | ||
| 367 | 'left' : left, | ||
| 368 | 'area' : (left+itm.data('width')), | ||
| 369 | 'center': (left - ($this.vp/2 - itm.data('cwidth')/2)) | ||
| 370 | }); | ||
| 371 | |||
| 372 | item = itm; | ||
| 373 | }); | ||
| 374 | } | ||
| 375 | |||
| 376 | |||
| 377 | } else { | ||
| 378 | |||
| 379 | for (i=this.items.length-1;i >-1 ;i--) { | ||
| 380 | |||
| 381 | area += this.items.eq(z).data('width'); | ||
| 382 | |||
| 383 | if (z != baseidx) { | ||
| 384 | move.push(this.items.eq(z)); | ||
| 385 | } | ||
| 386 | |||
| 387 | if (area > this.vp) { | ||
| 388 | break; | ||
| 389 | } | ||
| 390 | |||
| 391 | z = z-1 == -1 ? this.items.length-1:z-1; | ||
| 392 | } | ||
| 393 | |||
| 394 | if (move.length) { | ||
| 395 | |||
| 396 | move.forEach(function(itm){ | ||
| 397 | |||
| 398 | var left = item.data('left') - itm.data('width'); | ||
| 399 | |||
| 400 | itm.css({'left': left}).data({ | ||
| 401 | 'left' : left, | ||
| 402 | 'area' : (left+itm.data('width')), | ||
| 403 | 'center': (left - ($this.vp/2 - itm.data('cwidth')/2)) | ||
| 404 | }); | ||
| 405 | |||
| 406 | item = itm; | ||
| 407 | }); | ||
| 408 | } | ||
| 409 | } | ||
| 410 | } | ||
| 411 | }); | ||
| 412 | |||
| 413 | // handle dragging | ||
| 414 | UI.$doc.on('mousemove.uk.slider touchmove.uk.slider', function(e) { | ||
| 415 | |||
| 416 | if (e.originalEvent && e.originalEvent.touches) { | ||
| 417 | e = e.originalEvent.touches[0]; | ||
| 418 | } | ||
| 419 | |||
| 420 | if (delayIdle && Math.abs(e.pageX - delayIdle.x) > delayIdle.threshold) { | ||
| 421 | |||
| 422 | if (!window.getSelection().toString()) { | ||
| 423 | delayIdle(e); | ||
| 424 | } else { | ||
| 425 | dragging = delayIdle = false; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | |||
| 429 | if (!dragging) { | ||
| 430 | return; | ||
| 431 | } | ||
| 432 | |||
| 433 | var x, xDiff, pos, dir, focus, item, next, diff, i, z, itm; | ||
| 434 | |||
| 435 | if (e.clientX || e.clientY) { | ||
| 436 | x = e.clientX; | ||
| 437 | } else if (e.pageX || e.pageY) { | ||
| 438 | x = e.pageX - document.body.scrollLeft - document.documentElement.scrollLeft; | ||
| 439 | } | ||
| 440 | |||
| 441 | focus = store.focus; | ||
| 442 | xDiff = x - dragging.element.data('pointer-start').x; | ||
| 443 | pos = dragging.element.data('pointer-pos-start') + xDiff; | ||
| 444 | dir = x > dragging.element.data('pointer-start').x ? -1:1; | ||
| 445 | item = dragging.items.eq(store.focus); | ||
| 446 | |||
| 447 | if (dir == 1) { | ||
| 448 | |||
| 449 | diff = item.data('left') + Math.abs(xDiff); | ||
| 450 | |||
| 451 | for (i=0,z=store.focus;i<dragging.items.length;i++) { | ||
| 452 | |||
| 453 | itm = dragging.items.eq(z); | ||
| 454 | |||
| 455 | if (z != store.focus && itm.data('left') < diff && itm.data('area') > diff) { | ||
| 456 | focus = z; | ||
| 457 | break; | ||
| 458 | } | ||
| 459 | |||
| 460 | z = z+1 == dragging.items.length ? 0:z+1; | ||
| 461 | } | ||
| 462 | |||
| 463 | } else { | ||
| 464 | |||
| 465 | diff = item.data('left') - Math.abs(xDiff); | ||
| 466 | |||
| 467 | for (i=0,z=store.focus;i<dragging.items.length;i++) { | ||
| 468 | |||
| 469 | itm = dragging.items.eq(z); | ||
| 470 | |||
| 471 | if (z != store.focus && itm.data('area') <= item.data('left') && itm.data('center') < diff) { | ||
| 472 | focus = z; | ||
| 473 | break; | ||
| 474 | } | ||
| 475 | |||
| 476 | z = z-1 == -1 ? dragging.items.length-1:z-1; | ||
| 477 | } | ||
| 478 | } | ||
| 479 | |||
| 480 | if (dragging.options.infinite && focus!=store._focus) { | ||
| 481 | dragging.infinite(focus, dir); | ||
| 482 | } | ||
| 483 | |||
| 484 | dragging.updatePos(pos); | ||
| 485 | |||
| 486 | store.dir = dir; | ||
| 487 | store._focus = focus; | ||
| 488 | store.touchx = parseInt(e.pageX, 10); | ||
| 489 | store.diff = diff; | ||
| 490 | }); | ||
| 491 | |||
| 492 | UI.$doc.on('mouseup.uk.slider touchend.uk.slider', function(e) { | ||
| 493 | |||
| 494 | if (dragging) { | ||
| 495 | |||
| 496 | dragging.container.removeClass('uk-drag'); | ||
| 497 | |||
| 498 | // TODO is this needed? | ||
| 499 | dragging.items.eq(store.focus); | ||
| 500 | |||
| 501 | var itm, focus = false, i, z; | ||
| 502 | |||
| 503 | if (store.dir == 1) { | ||
| 504 | |||
| 505 | for (i=0,z=store.focus;i<dragging.items.length;i++) { | ||
| 506 | |||
| 507 | itm = dragging.items.eq(z); | ||
| 508 | |||
| 509 | if (z != store.focus && itm.data('left') > store.diff) { | ||
| 510 | focus = z; | ||
| 511 | break; | ||
| 512 | } | ||
| 513 | |||
| 514 | z = z+1 == dragging.items.length ? 0:z+1; | ||
| 515 | } | ||
| 516 | |||
| 517 | } else { | ||
| 518 | |||
| 519 | for (i=0,z=store.focus;i<dragging.items.length;i++) { | ||
| 520 | |||
| 521 | itm = dragging.items.eq(z); | ||
| 522 | |||
| 523 | if (z != store.focus && itm.data('left') < store.diff) { | ||
| 524 | focus = z; | ||
| 525 | break; | ||
| 526 | } | ||
| 527 | |||
| 528 | z = z-1 == -1 ? dragging.items.length-1:z-1; | ||
| 529 | } | ||
| 530 | } | ||
| 531 | |||
| 532 | dragging.updateFocus(focus!==false ? focus:store._focus); | ||
| 533 | |||
| 534 | } | ||
| 535 | |||
| 536 | dragging = delayIdle = false; | ||
| 537 | }); | ||
| 538 | |||
| 539 | return UI.slider; | ||
| 540 | }); | ||
