1/* eslint-disable */ 2(function (global, factory) { 3 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 4 typeof define === 'function' && define.amd ? define([], factory) : 5 (global.MomentumSlider = factory()); 6}(this, (function () { 7 'use strict'; 8 /* eslint-enable */ 9 10 // fixes weird safari 10 bug where preventDefault is prevented 11 // @see https://github.com/metafizzy/flickity/issues/457#issuecomment-254501356 12 window.addEventListener('touchmove', function () {}); 13 14 function MomentumSlider(options) { 15 this.o = extend({}, this.defaults, options); 16 this.initHtml(); 17 this.initValues(); 18 this.initEvents(); 19 this.updateClassnames(); 20 } 21 22 MomentumSlider.prototype = { 23 defaults: { 24 el: '.ms-container', 25 cssClass: '', 26 vertical: false, 27 multiplier: 1, 28 bounceCoefficient: 0.3, 29 bounceMax: 100, 30 loop: 0, 31 interactive: true, 32 reverse: false, 33 currentIndex: 0 34 }, 35 initHtml: function () { 36 this.msContainer = is.str(this.o.el) ? document.querySelector(this.o.el) : this.o.el; 37 if (this.o.range) { 38 var html = '<div class="ms-container ' + this.o.cssClass + '"><ul class="ms-track">'; 39 for (var i = this.o.range[0]; i <= this.o.range[1]; i++) { 40 html += is.fnc(this.o.rangeContent) ? buildSlide(this.o.rangeContent(i)) : buildSlide(i); 41 } 42 html += '</ul></div>'; 43 var msHtml = document.createElement('div'); 44 msHtml.innerHTML = html; 45 this.msContainer.appendChild(msHtml.firstChild); 46 this.msContainer = this.msContainer.lastChild; 47 } 48 this.msContainer.classList.add('ms-container--' + (this.o.vertical ? 'vertical' : 'horizontal')); 49 if (this.o.reverse) { 50 this.msContainer.classList.add('ms-container--reverse'); 51 } 52 this.msTrack = this.msContainer.children[0]; 53 this.msSlides = this.msTrack.children; 54 this.step = this.o.vertical ? this.msSlides[0].scrollHeight : this.msSlides[0].scrollWidth; 55 this.sliderLength = this.msSlides.length; 56 if (this.o.loop) { 57 var loopLength, slideIndex, fragment; 58 // begin 59 fragment = document.createDocumentFragment(); 60 loopLength = this.o.loop; 61 slideIndex = this.sliderLength - loopLength; 62 while (loopLength--) { 63 fragment.appendChild(this.msSlides[slideIndex++].cloneNode(true)); 64 } 65 this.msTrack.insertBefore(fragment, this.msTrack.firstChild); 66 // end 67 fragment = document.createDocumentFragment(); 68 slideIndex = loopLength = this.o.loop; 69 while (loopLength--) { 70 fragment.appendChild(this.msSlides[slideIndex++].cloneNode(true)); 71 } 72 this.msTrack.appendChild(fragment); 73 // update 74 this.sliderLength += this.o.loop * 2; 75 } 76 this.sliderWidth = this.sliderLength * this.step; 77 }, 78 initValues: function () { 79 this.boundMin = this.o.reverse ? 0 : -this.step * (this.sliderLength - 1); 80 this.boundMax = this.o.reverse ? this.step * (this.sliderLength - 1) : 0; 81 this.targetPosition = this.targetPosition || 0; 82 this.ticking = false; 83 this.enabled = true; 84 this.pointerActive = false; 85 this.pointerMoved = false; 86 this.trackingPoints = []; 87 this.msTrack.style[this.o.vertical ? 'height' : 'width'] = this.sliderWidth + 'px'; 88 this.currentIndex = (this.currentIndex || this.o.currentIndex) + this.o.loop; 89 this.updateSlider(undefined, true); 90 this.renderTarget(); 91 var index = this.sliderLength; 92 while (index--) { 93 this.setStyle(index, this.currentIndex == index ? 0 : -1); 94 } 95 }, 96 initEvents: function () { 97 if (this.o.interactive) { 98 this.msContainer.addEventListener('touchstart', this.onDown.bind(this)); 99 this.msContainer.addEventListener('mousedown', this.onDown.bind(this)); 100 document.addEventListener('touchmove', this.onMove.bind(this), getPassiveSupported() ? { 101 passive: false 102 } : false); 103 document.addEventListener('touchend', this.onUp.bind(this)); 104 document.addEventListener('touchcancel', this.stopTracking.bind(this)); 105 document.addEventListener('mousemove', this.onMove.bind(this), getPassiveSupported() ? { 106 passive: false 107 } : false); 108 document.addEventListener('mouseup', this.onUp.bind(this)); 109 if (this.o.prevEl) { 110 this.prevEl = is.str(this.o.prevEl) ? document.querySelector(this.o.prevEl) : this.o.prevEl; 111 this.prevEl.addEventListener('click', this.prev.bind(this)); 112 } 113 if (this.o.nextEl) { 114 this.nextEl = is.str(this.o.nextEl) ? document.querySelector(this.o.nextEl) : this.o.nextEl; 115 this.nextEl.addEventListener('click', this.next.bind(this)); 116 } 117 } 118 window.addEventListener('resize', this.onResize.bind(this)); 119 }, 120 prev: function () { 121 if (this.enabled) { 122 this.updateSlider(Math.round(this.targetPosition / this.step) * this.step + (this.o.reverse ? -this.step : this.step)); 123 } 124 }, 125 next: function () { 126 if (this.enabled) { 127 this.updateSlider(Math.round(this.targetPosition / this.step) * this.step + (this.o.reverse ? this.step : -this.step)); 128 } 129 }, 130 select: function (index) { 131 if (this.enabled) { 132 // this.currentIndex = index; 133 // this.updateSlider(); 134 this.updateSlider((index + this.o.loop) * (this.o.reverse ? this.step : -this.step)); 135 } 136 }, 137 setStyleToNode: function (node, style, diff, lower) { 138 if (style) { 139 var value = ''; 140 for (var property in style) { 141 if (property[0] == '.') { 142 this.setStyleToNode(node.querySelector(property), style[property], diff, lower); 143 } else if (property == 'transform') {
144 style[property].forEach(function(transform) { 145 for (var t in transform) { 146 value += t + '(' + getCurrentValue(transform[t], diff, lower); 147 if (t == 'rotate') { 148 value += 'deg'; 149 } else if (t == 'translateX' || t == 'translateY' || t == 'translateZ') { 150 value += 'px'; 151 } 152 value += ') '; 153 } 154 }); 155 } else { 156 value = getCurrentValue(style[property], diff, lower); 157 } 158 node.style[property] = value; 159 } 160 } 161 }, 162 setStyle: function (index, diff, lower) { 163 this.setStyleToNode(this.msSlides[index], this.o.style, diff, lower); 164 if (is.fnc(this.o.customStyles)) { 165 this.o.customStyles(index, diff, lower); 166 } 167 }, 168 renderTarget: function () { 169 if (this.o.sync) { 170 var syncIndex = this.o.sync.length; 171 var syncSlider; 172 while (syncIndex--) { 173 syncSlider = this.o.sync[syncIndex]; 174 syncSlider.targetPosition = (syncSlider.o.reverse ? -1 : 1) * this.targetPosition / this.sliderWidth * syncSli
174der.sliderWidth; 175 syncSlider.renderTarget(); 176 } 177 } 178 179 var paddingLength = this.o.loop * this.step; 180 var contentLength = this.sliderWidth - (paddingLength * 2); 181 if (this.o.loop) { 182 if (-this.targetPosition < paddingLength) { 183 while (-this.targetPosition < paddingLength) { 184 this.targetPosition -= contentLength; 185 } 186 } else if (-this.targetPosition >= paddingLength + contentLength) { 187 while (-this.targetPosition >= paddingLength + contentLength) { 188 this.targetPosition += contentLength; 189 } 190 } 191 } 192 193 // var actualIndex = -this.targetPosition / this.step; 194 var actualIndex = (this.o.reverse ? 1 : -1) * this.targetPosition / this.step; 195 this.onChangeCurrentIndex(Math.round(actualIndex)); 196 var lowerIndex = Math.floor(actualIndex); 197 var higherIndex = Math.ceil(actualIndex); 198 var lowerDiff = actualIndex - lowerIndex; 199 var higherDiff = actualIndex - higherIndex; 200 201 if (!is.und(this.lowerIndex) && this.lowerIndex != lowerIndex && this.lowerIndex != higherIndex) { 202 this.setStyle(this.lowerIndex, 1, true); 203 } 204 if (!is.und(this.higherIndex) && this.higherIndex != lowerIndex && this.higherIndex != higherIndex) { 205 this.setStyle(this.higherIndex, -1); 206 } 207 208 if (lowerIndex >= 0 && lowerIndex < this.sliderLength) { 209 this.setStyle(lowerIndex, lowerDiff, true); 210 this.lowerIndex = lowerIndex; 211 } 212 if (higherIndex >= 0 && higherIndex < this.sliderLength) { 213 this.setStyle(higherIndex, higherDiff); 214 this.higherIndex = higherIndex; 215 } 216 217 var transformValue = 'translate' + (this.o.vertical ? 'Y' : 'X') + '(' + this.targetPosition + 'px)'; 218 this.msTrack.style[transformProperty] = transformValue; 219 }, 220 onDown: function (ev) { 221 if (this.enabled && !this.pointerActive) { 222 var event = normalizeEvent(ev); 223 this.pointerActive = true; 224 this.pointerId = event.id; 225 226 this.pointerLastX = this.pointerCurrentX = event.x; 227 this.pointerLastY = this.pointerCurrentY = event.y; 228 this.trackingPoints = []; 229 this.addTrackingPoint(this.pointerLastX, this.pointerLastY); 230 231 if (this.animateInstance) this.animateInstance.stop(); 232 } 233 }, 234 onMove: function (ev) { 235 if (this.enabled && this.pointerActive) { 236 this.pointerMoved = true; 237 ev.preventDefault(); 238 var event = normalizeEvent(ev); 239 240 if (event.id === this.pointerId) { 241 this.pointerCurrentX = event.x; 242 this.pointerCurrentY = event.y; 243 this.addTrackingPoint(this.pointerLastX, this.pointerLastY); 244 this.requestTick(); 245 } 246 } 247 }, 248 onUp: function (ev) { 249 if (this.enabled && this.pointerActive) { 250 var event = normalizeEvent(ev); 251 252 if (event.id === this.pointerId) { 253 var slide = ev.target; 254 if (this.msTrack.contains(slide)) { 255 while (!slide.matches('.ms-slide, .ms-track')) { 256 slide = slide.parentNode; 257 } 258 } 259 var index = Array.prototype.indexOf.call(this.msSlides, slide); 260 if (!this.pointerMoved) { 261 if (index !== -1) { 262 this.currentIndex = index; 263 this.updateSlider(); 264 } 265 } 266 this.stopTracking(index); 267 } 268 } 269 }, 270 onResize: function () { 271 // this.initValues(); 272 }, 273 stopTracking: function (index) { 274 this.pointerActive = false;
275 if (this.pointerMoved || index === -1) { 276 this.pointerMoved = false; 277 this.addTrackingPoint(this.pointerLastX, this.pointerLastY); 278 this.startDecelAnim(); 279 } 280 }, 281 addTrackingPoint: function (x, y) { 282 var time = Date.now(); 283 while (this.trackingPoints.length > 0) { 284 if (time - this.trackingPoints[0].time <= 100) { 285 break; 286 } 287 this.trackingPoints.shift(); 288 } 289 290 this.trackingPoints.push({ 291 x: x, 292 y: y, 293 time: time 294 }); 295 }, 296 updateAndRender: function () { 297 var pointerChange = this.o.vertical ? this.pointerCurrentY - this.pointerLastY : this.pointerCurrentX - this.pointerLastX; 298 this.targetPosition += pointerChange * this.o.multiplier; 299 300 if (this.o.bounceCoefficient) { 301 var diff = this.checkBounds(); 302 if (diff !== 0) { 303 this.targetPosition -= pointerChange * dragOutOfBoundsMultiplier(diff) * this.o.multiplier; 304 } 305 } else { 306 this.checkBounds(true); 307 } 308 309 this.renderTarget(); 310 311 this.pointerLastX = this.pointerCurrentX; 312 this.pointerLastY = this.pointerCurrentY; 313 this.ticking = false; 314 }, 315 requestTick: function () { 316 if (!this.ticking) { 317 requestAnimationFrame(this.updateAndRender.bind(this)); 318 } 319 this.ticking = true; 320 }, 321 checkBounds: function (restrict) { 322 var diff = 0; 323 324 if (this.boundMin !== undefined && this.targetPosition < this.boundMin) { 325 diff = this.boundMin - this.targetPosition; 326 } else if (this.boundMax !== undefined && this.targetPosition > this.boundMax) { 327 diff = this.boundMax - this.targetPosition; 328 } 329 330 if (restrict) { 331 if (diff !== 0) { 332 this.targetPosition = diff > 0 ? this.boundMin : this.boundMax; 333 } 334 } 335 336 return diff; 337 }, 338 startDecelAnim: function () { 339 var firstPoint = this.trackingPoints[0]; 340 var lastPoint = this.trackingPoints[this.trackingPoints.length - 1]; 341 342 var positionOffset = this.o.vertical ? lastPoint.y - firstPoint.y : lastPoint.x - firstPoint.x; 343 var timeOffset = lastPoint.time - firstPoint.time; 344 345 var D = timeOffset / 15 / this.o.multiplier; 346 this.decVel = positionOffset / D || 0; 347 348 var newTargetPosition = this.targetPosition + (this.decVel * 12); 349 var newTargetPositionOffset = newTargetPosition % this.step; 350 newTargetPosition = newTargetPosition - newTargetPositionOffset; 351 if (Math.abs(newTargetPositionOffset) > this.step / 2) { 352 newTargetPosition += (newTargetPositionOffset > 0 ? 1 : -1) * this.step; 353 } 354 355 this.updateSlider(newTargetPosition); 356 }, 357 fixCurrentIndex: function () { 358 if (this.o.loop) { 359 if (this.currentIndex < this.o.loop) { 360 this.currentIndex = this.sliderLength - this.o.loop + (this.currentIndex - this.o.loop); 361 } else if (this.currentIndex > this.sliderLength - this.o.loop - 1) { 362 this.currentIndex = this.currentIndex + this.o.loop * 2 - this.sliderLength; 363 } 364 } 365 }, 366 updateSlider: function (newTargetPosition, initial) { 367 if (is.und(newTargetPosition)) { 368 newTargetPosition = (this.o.reverse ? 1 : -1) * this.currentIndex * this.step; 369 } else { 370 this.currentIndex = (this.o.reverse ? 1 : -1) * newTargetPosition / this.step; 371 } 372 this.fixCurrentIndex(); 373 if (newTargetPosition !== this.targetPosition) { 374 this.updateClassnames(); 375 this.animateTarget(newTargetPosition, initial); 376 } 377 }, 378 updateClassnames: function () { 379 if (this.prevEl) { 380 if (this.currentIndex === 0) { 381 this.prevEl.classList.add('ms-first'); 382 } else { 383 this.prevEl.classList.remove('ms-first'); 384 } 385 } 386 if (this.nextEl) { 387 if (this.currentIndex === this.sliderLength - 1) { 388 this.nextEl.classList.add('ms-last'); 389 } else { 390 this.nextEl.classList.remove('ms-last'); 391 } 392 } 393 }, 394 animateTarget: function (newTargetPosition, initial, back) { 395 if (this.animateInstance) this.animateInstance.stop(); 396 var _ = this; 397 var from = this.targetPosition; 398 var to = newTargetPosition; 399 this.animateInstance = animate(function(progress) { 400 _.targetPosition = to > from ? from + ((to - from) * progress) : from - ((from - to) * progress); // 0 - ((0 - -2100) * progress) 401 var sliderMin = _.o.reverse ? 0 : -(_.sliderLength - 1) * _.step; 402 var sliderMax = _.o.reverse ? (_.sliderLength - 1) * _.step : 0; 403 if (!back && 404 !_.o.loop && 405 _.o.bounceCoefficient && 406 ( 407 ( 408 _.targetPosition > sliderMax && 409 _.targetPosition > sliderMax + Math.min((to - sliderMax) * _.o.bounceCoefficient, _.o.bounceMax) 410 ) || 411 ( 412 _.targetPosition < sliderMin && 413 _.targetPosition < sliderMin - Math.min(-(to - sliderMin) * _.o.bounceCoefficient, _.o.bounceMax) 414 ) 415 ) 416 ) { 417 _.animateInstance.stop(); 418 _.animateTarget(_.targetPosition < sliderMin ? sliderMin : sliderMax, false, true); 419 _.currentIndex = _.targetPosition < sliderMin ? 0 : _.sliderLength - 1; 420 } else { 421 _.renderTarget(); 422 } 423 }, initial ? 0 : 500, function(t) { return t * (2 - t); }); 424 }, 425 onChangeCurrentIndex: function (index) { 426 var currentIndex = this.o.loop ? index - this.o.loop : index; 427 currentIndex = currentIndex === this.sliderLength - this.o.loop * 2 ? 0 : currentIndex; 428 if (is.fnc(this.o.change) && currentIndex !== this.lastCurrentIndex) { 429 this.o.change(currentIndex, this.lastCurrentIndex); 430 this.lastCurrentIndex = currentIndex; 431 } 432 }, 433 getCurrentIndex: function () { 434 return this.o.loop ? this.currentIndex - this.o.loop : this.currentIndex; 435 }, 436 enable: function () { 437 this.enabled = true; 438 }, 439 disable: function () { 440 this.enabled = false;
441 } 442 }; 443 444 445 // Utils 446 447 var is = { 448 arr: function (a) { return Array.isArray(a); }, 449 str: function (a) { return typeof a === 'string'; }, 450 und: function (a) { return typeof a === 'undefined'; }, 451 fnc: function(a) { return typeof a === 'function' } 452 }; 453 454 function stringToHyphens(str) { 455 return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); 456 } 457 458 function getCSSValue(el, prop) { 459 if (prop in el.style) { 460 return getComputedStyle(el).getPropertyValue(stringToHyphens(prop)) || '0'; 461 } 462 } 463 464 var t = 'transform'; 465 var transformProperty = (getCSSValue(document.body, t) ? t : '-webkit-' + t); 466 467 function buildSlide(value) { 468 return '<li class="ms-slide">' + value + '</li>'; 469 } 470 471 function extendSingle(target, source) { 472 for (var key in source) 473 target[key] = is.arr(source[key]) ? source[key].slice(0) : source[key]; 474 return target; 475 } 476 477 function extend(target) { 478 if (!target) target = {}; 479 for (var i = 1; i < arguments.length; i++) 480 extendSingle(target, arguments[i]); 481 return target; 482 } 483 484 function animate(step, duration, easing) { 485 if (duration) { 486 var start = performance.now(); 487 var timer = null; 488 var stopped = false; 489 var animation = function (t) { 490 var progress = (t - start) / duration; 491 if (progress < 0) progress = 0; 492 if (progress > 1) progress = 1; 493 if (is.fnc(easing)) progress = easing(progress); 494 step(progress); 495 if (progress !== 1 && !stopped) timer = requestAnimationFrame(animation); 496 }; 497 timer = requestAnimationFrame(animation); 498 return new function() { 499 this.stop = function() { 500 if (timer) cancelAnimationFrame(timer); 501 stopped = true; 502 }; 503 }; 504 } else { 505 step(1); 506 } 507 } 508 509 /* eslint-disable */ 510 function getPassiveSupported() { 511 var passiveSupported = false; 512 try { 513 var options = Object.defineProperty({}, 'passive', { 514 get: function get() { 515 passiveSupported = true; 516 } 517 }); 518 519 window.addEventListener('test', null, options); 520 } catch (err) {} 521 getPassiveSupported = function () { 522 return passiveSupported; 523 }; 524 return passiveSupported; 525 } 526 /* eslint-enable */ 527 528 function normalizeEvent(ev) { 529 if (ev.type === 'touchmove' || ev.type === 'touchstart' || ev.type === 'touchend') { 530 var touch = ev.targetTouches[0] || ev.changedTouches[0]; 531 return { 532 x: touch.clientX, 533 y: touch.clientY, 534 id: touch.identifier 535 }; 536 } else { 537 return { 538 x: ev.clientX, 539 y: ev.clientY, 540 id: null 541 }; 542 } 543 } 544 545 function dragOutOfBoundsMultiplier(val) { 546 return 0.000005 * Math.pow(val, 2) + 0.0001 * val + 0.55; 547 } 548 549 function getCurrentValue(values, diff, lower) { 550 var lowerValue = values[0]; 551 var centerValue = values[1]; 552 var higherValue = values[2] || lowerValue; 553 var diffValue = lower ? centerValue - lowerValue : centerValue - higherValue; 554 return lower ? centerValue - diffValue * diff : centerValue + diffValue * diff; 555 } 556 557 return extend(MomentumSlider, { 558 extend: extend, 559 transformProperty: transformProperty, 560 getCurrentValue: getCurrentValue 561 }); 562 563})));
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.