1(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ProgressBar = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 2/* shifty - v1.5.3 - 2016-11-29 - http://jeremyckahn.github.io/shifty */ 3;(function () { 4 var root = this || Function('return this')(); 5 6/** 7 * Shifty Core 8 * By Jeremy Kahn - [email protected] 9 */ 10 11var Tweenable = (function () { 12 13 'use strict'; 14 15 // Aliases that get defined later in this function 16 var formula; 17 18 // CONSTANTS 19 var DEFAULT_SCHEDULE_FUNCTION; 20 var DEFAULT_EASING = 'linear'; 21 var DEFAULT_DURATION = 500; 22 var UPDATE_TIME = 1000 / 60; 23 24 var _now = Date.now 25 ? Date.now 26 : function () {return +new Date();}; 27 28 var now = typeof SHIFTY_DEBUG_NOW !== 'undefined' ? SHIFTY_DEBUG_NOW : _now; 29 30 if (typeof window !== 'undefined') { 31 // requestAnimationFrame() shim by Paul Irish (modified for Shifty) 32 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 33 DEFAULT_SCHEDULE_FUNCTION = window.requestAnimationFrame 34 || window.webkitRequestAnimationFrame 35 || window.oRequestAnimationFrame 36 || window.msRequestAnimationFrame 37 || (window.mozCancelRequestAnimationFrame 38 && window.mozRequestAnimationFrame) 39 || setTimeout; 40 } else { 41 DEFAULT_SCHEDULE_FUNCTION = setTimeout; 42 } 43 44 function noop () { 45 // NOOP! 46 } 47 48 /** 49 * Handy shortcut for doing a for-in loop. This is not a "normal" each 50 * function, it is optimized for Shifty. The iterator function only receives 51 * the property name, not the value. 52 * @param {Object} obj 53 * @param {Function(string)} fn 54 * @private 55 */ 56 function each (obj, fn) { 57 var key; 58 for (key in obj) { 59 if (Object.hasOwnProperty.call(obj, key)) { 60 fn(key); 61 } 62 } 63 } 64 65 /** 66 * Perform a shallow copy of Object properties. 67 * @param {Object} targetObject The object to copy into 68 * @param {Object} srcObject The object to copy from 69 * @return {Object} A reference to the augmented `targetObj` Object 70 * @private 71 */ 72 function shallowCopy (targetObj, srcObj) { 73 each(srcObj, function (prop) { 74 targetObj[prop] = srcObj[prop]; 75 }); 76 77 return targetObj; 78 } 79 80 /** 81 * Copies each property from src onto target, but only if the property to 82 * copy to target is undefined. 83 * @param {Object} target Missing properties in this Object are filled in 84 * @param {Object} src 85 * @private 86 */ 87 function defaults (target, src) { 88 each(src, function (prop) { 89 if (typeof target[prop] === 'undefined') { 90 target[prop] = src[prop]; 91 } 92 }); 93 } 94 95 /** 96 * Calculates the interpolated tween values of an Object for a given 97 * timestamp. 98 * @param {Number} forPosition The position to compute the state for. 99 * @param {Object} currentState Current state properties. 100 * @param {Object} originalState: The original state properties the Object is 101 * tweening from. 102 * @param {Object} targetState: The destination state properties the Object 103 * is tweening to. 104 * @param {number} duration: The length of the tween in milliseconds. 105 * @param {number} timestamp: The UNIX epoch time at which the tween began. 106 * @param {Object} easing: This Object's keys must correspond to the keys in 107 * targetState. 108 * @private 109 */ 110 function tweenProps (forPosition, currentState, originalState, targetState, 111 duration, timestamp, easing) { 112 var normalizedPosition = 113 forPosition < timestamp ? 0 : (forPosition - timestamp) / duration; 114 115 116 var prop; 117 var easingObjectProp; 118 var easingFn; 119 for (prop in currentState) { 120 if (currentState.hasOwnProperty(prop)) { 121 easingObjectProp = easing[prop]; 122 easingFn = typeof easingObjectProp === 'function' 123 ? easingObjectProp 124 : formula[easingObjectProp]; 125 126 currentState[prop] = tweenProp( 127 originalState[prop], 128 targetState[prop], 129 easingFn, 130 normalizedPosition 131 ); 132 } 133 } 134 135 return currentState; 136 } 137 138 /** 139 * Tweens a single property. 140 * @param {number} start The value that the tween started from. 141 * @param {number} end The value that the tween should end at. 142 * @param {Function} easingFunc The easing curve to apply to the tween. 143 * @param {number} position The normalized position (between 0.0 and 1.0) to 144 * calculate the midpoint of 'start' and 'end' against. 145 * @return {number} The tweened value. 146 * @private 147 */ 148 function tweenProp (start, end, easingFunc, position) { 149 return start + (end - start) * easingFunc(position); 150 } 151 152 /** 153 * Applies a filter to Tweenable instance. 154 * @param {Tweenable} tweenable The `Tweenable` instance to call the filter 155 * upon. 156 * @param {String} filterName The name of the filter to apply. 157 * @private 158 */ 159 function applyFilter (tweenable, filterName) { 160 var filters = Tweenable.prototype.filter; 161 var args = tweenable._filterArgs; 162 163 each(filters, function (name) { 164 if (typeof filters[name][filterName] !== 'undefined') {
165 filters[name][filterName].apply(tweenable, args); 166 } 167 }); 168 } 169 170 var timeoutHandler_endTime; 171 var timeoutHandler_currentTime; 172 var timeoutHandler_isEnded; 173 var timeoutHandler_offset; 174 /** 175 * Handles the update logic for one step of a tween. 176 * @param {Tweenable} tweenable 177 * @param {number} timestamp 178 * @param {number} delay 179 * @param {number} duration 180 * @param {Object} currentState 181 * @param {Object} originalState 182 * @param {Object} targetState 183 * @param {Object} easing 184 * @param {Function(Object, *, number)} step 185 * @param {Function(Function,number)}} schedule 186 * @param {number=} opt_currentTimeOverride Needed for accurate timestamp in 187 * Tweenable#seek. 188 * @private 189 */ 190 function timeoutHandler (tweenable, timestamp, delay, duration, currentState, 191 originalState, targetState, easing, step, schedule, 192 opt_currentTimeOverride) { 193 194 timeoutHandler_endTime = timestamp + delay + duration; 195 196 timeoutHandler_currentTime = 197 Math.min(opt_currentTimeOverri
vendor: 24,840 bytes, lines 197-1005
197de || now(), timeoutHandler_endTime); 198 199 timeoutHandler_isEnded = 200 timeoutHandler_currentTime >= timeoutHandler_endTime; 201 202 timeoutHandler_offset = duration - ( 203 timeoutHandler_endTime - timeoutHandler_currentTime); 204 205 if (tweenable.isPlaying()) { 206 if (timeoutHandler_isEnded) { 207 step(targetState, tweenable._attachment, timeoutHandler_offset); 208 tweenable.stop(true); 209 } else { 210 tweenable._scheduleId = 211 schedule(tweenable._timeoutHandler, UPDATE_TIME); 212 213 applyFilter(tweenable, 'beforeTween'); 214 215 // If the animation has not yet reached the start point (e.g., there was 216 // delay that has not yet completed), just interpolate the starting 217 // position of the tween. 218 if (timeoutHandler_currentTime < (timestamp + delay)) { 219 tweenProps(1, currentState, originalState, targetState, 1, 1, easing); 220 } else { 221 tweenProps(timeoutHandler_currentTime, currentState, originalState, 222 targetState, duration, timestamp + delay, easing); 223 } 224 225 applyFilter(tweenable, 'afterTween'); 226 227 step(currentState, tweenable._attachment, timeoutHandler_offset); 228 } 229 } 230 } 231 232 233 /** 234 * Creates a usable easing Object from a string, a function or another easing 235 * Object. If `easing` is an Object, then this function clones it and fills 236 * in the missing properties with `"linear"`. 237 * @param {Object.<string|Function>} fromTweenParams 238 * @param {Object|string|Function} easing 239 * @return {Object.<string|Function>} 240 * @private 241 */ 242 function composeEasingObject (fromTweenParams, easing) { 243 var composedEasing = {}; 244 var typeofEasing = typeof easing; 245 246 if (typeofEasing === 'string' || typeofEasing === 'function') { 247 each(fromTweenParams, function (prop) { 248 composedEasing[prop] = easing; 249 }); 250 } else { 251 each(fromTweenParams, function (prop) { 252 if (!composedEasing[prop]) { 253 composedEasing[prop] = easing[prop] || DEFAULT_EASING; 254 } 255 }); 256 } 257 258 return composedEasing; 259 } 260 261 /** 262 * Tweenable constructor. 263 * @class Tweenable 264 * @param {Object=} opt_initialState The values that the initial tween should 265 * start at if a `from` object is not provided to `{{#crossLink 266 * "Tweenable/tween:method"}}{{/crossLink}}` or `{{#crossLink 267 * "Tweenable/setConfig:method"}}{{/crossLink}}`. 268 * @param {Object=} opt_config Configuration object to be passed to 269 * `{{#crossLink "Tweenable/setConfig:method"}}{{/crossLink}}`. 270 * @module Tweenable 271 * @constructor 272 */ 273 function Tweenable (opt_initialState, opt_config) { 274 this._currentState = opt_initialState || {}; 275 this._configured = false; 276 this._scheduleFunction = DEFAULT_SCHEDULE_FUNCTION; 277 278 // To prevent unnecessary calls to setConfig do not set default 279 // configuration here. Only set default configuration immediately before 280 // tweening if none has been set. 281 if (typeof opt_config !== 'undefined') { 282 this.setConfig(opt_config); 283 } 284 } 285 286 /** 287 * Configure and start a tween. 288 * @method tween 289 * @param {Object=} opt_config Configuration object to be passed to 290 * `{{#crossLink "Tweenable/setConfig:method"}}{{/crossLink}}`. 291 * @chainable 292 */ 293 Tweenable.prototype.tween = function (opt_config) { 294 if (this._isTweening) { 295 return this; 296 } 297 298 // Only set default config if no configuration has been set previously and 299 // none is provided now. 300 if (opt_config !== undefined || !this._configured) { 301 this.setConfig(opt_config); 302 } 303 304 this._timestamp = now(); 305 this._start(this.get(), this._attachment); 306 return this.resume(); 307 }; 308 309 /** 310 * Configure a tween that will start at some point in the future. 311 * 312 * @method setConfig 313 * @param {Object} config The following values are valid: 314 * - __from__ (_Object=_): Starting position. If omitted, `{{#crossLink 315 * "Tweenable/get:method"}}get(){{/crossLink}}` is used. 316 * - __to__ (_Object=_): Ending position. 317 * - __duration__ (_number=_): How many milliseconds to animate for. 318 * - __delay__ (_delay=_): How many milliseconds to wait before starting the 319 * tween. 320 * - __start__ (_Function(Object, *)_): Function to execute when the tween 321 * begins. Receives the state of the tween as the first parameter and 322 * `attachment` as the second parameter. 323 * - __step__ (_Function(Object, *, number)_): Function to execute on every 324 * tick. Receives `{{#crossLink 325 * "Tweenable/get:method"}}get(){{/crossLink}}` as the first parameter, 326 * `attachment` as the second parameter, and the time elapsed since the 327 * start of the tween as the third. This function is not called on the 328 * final step of the animation, but `finish` is. 329 * - __finish__ (_Function(Object, *)_): Function to execute upon tween 330 * completion. Receives the state of the tween as the first parameter and 331 * `attachment` as the second parameter. 332 * - __easing__ (_Object.<string|Function>|string|Function=_): Easing curve 333 * name(s) or function(s) to use for the tween. 334 * - __attachment__ (_*_): Cached value that is passed to the 335 * `step`/`start`/`finish` methods. 336 * @chainable 337 */ 338 Tweenable.prototype.setConfig = function (config) { 339 config = config || {}; 340 this._configured = true; 341 342 // Attach something to this Tweenable instance (e.g.: a DOM element, an 343 // object, a string, etc.); 344 this._attachment = config.attachment; 345 346 // Init the internal state 347 this._pausedAtTime = null; 348 this._scheduleId = null; 349 this._delay = config.delay || 0; 350 this._start = config.start || noop; 351 this._step = config.step || noop; 352 this._finish = config.finish || noop; 353 this._duration = config.duration || DEFAULT_DURATION; 354 this._currentState = shallowCopy({}, config.from || this.get()); 355 this._originalState = this.get(); 356 this._targetState = shallowCopy({}, config.to || this.get()); 357 358 var self = this; 359 this._timeoutHandler = function () { 360 timeoutHandler(self, 361 self._timestamp, 362 self._delay, 363 self._duration, 364 self._currentState, 365 self._originalState, 366 self._targetState, 367 self._easing, 368 self._step, 369 self._scheduleFunction 370 ); 371 }; 372 373 // Aliases used below 374 var currentState = this._currentState; 375 var targetState = this._targetState; 376 377 // Ensure that there is always something to tween to. 378 defaults(targetState, currentState); 379 380 this._easing = composeEasingObject( 381 currentState, config.easing || DEFAULT_EASING); 382 383 this._filterArgs = 384 [currentState, this._originalState, targetState, this._easing]; 385 386 applyFilter(this, 'tweenCreated'); 387 return this; 388 }; 389 390 /** 391 * @method get 392 * @return {Object} The current state. 393 */ 394 Tweenable.prototype.get = function () { 395 return shallowCopy({}, this._currentState); 396 }; 397 398 /** 399 * @method set 400 * @param {Object} state The current state. 401 */ 402 Tweenable.prototype.set = function (state) { 403 this._currentState = state; 404 }; 405 406 /** 407 * Pause a tween. Paused tweens can be resumed from the point at which they 408 * were paused. This is different from `{{#crossLink 409 * "Tweenable/stop:method"}}{{/crossLink}}`, as that method 410 * causes a tween to start over when it is resumed. 411 * @method pause 412 * @chainable 413 */ 414 Tweenable.prototype.pause = function () { 415 this._pausedAtTime = now(); 416 this._isPaused = true; 417 return this; 418 }; 419 420 /** 421 * Resume a paused tween. 422 * @method resume 423 * @chainable 424 */ 425 Tweenable.prototype.resume = function () { 426 if (this._isPaused) { 427 this._timestamp += now() - this._pausedAtTime; 428 } 429 430 this._isPaused = false; 431 this._isTweening = true; 432 433 this._timeoutHandler(); 434 435 return this; 436 }; 437 438 /** 439 * Move the state of the animation to a specific point in the tween's 440 * timeline. If the animation is not running, this will cause the `step` 441 * handlers to be called. 442 * @method seek 443 * @param {millisecond} millisecond The millisecond of the animation to seek 444 * to. This must not be less than `0`. 445 * @chainable 446 */ 447 Tweenable.prototype.seek = function (millisecond) { 448 millisecond = Math.max(millisecond, 0); 449 var currentTime = now(); 450 451 if ((this._timestamp + millisecond) === 0) { 452 return this; 453 } 454 455 this._timestamp = currentTime - millisecond; 456 457 if (!this.isPlaying()) { 458 this._isTweening = true; 459 this._isPaused = false; 460 461 // If the animation is not running, call timeoutHandler to make sure that 462 // any step handlers are run. 463 timeoutHandler(this, 464 this._timestamp, 465 this._delay, 466 this._duration, 467 this._currentState, 468 this._originalState, 469 this._targetState, 470 this._easing, 471 this._step, 472 this._scheduleFunction, 473 currentTime 474 ); 475 476 this.pause(); 477 } 478 479 return this; 480 }; 481 482 /** 483 * Stops and cancels a tween. 484 * @param {boolean=} gotoEnd If `false` or omitted, the tween just stops at 485 * its current state, and the `finish` handler is not invoked. If `true`, 486 * the tweened object's values are instantly set to the target values, and 487 * `finish` is invoked. 488 * @method stop 489 * @chainable 490 */ 491 Tweenable.prototype.stop = function (gotoEnd) { 492 this._isTweening = false; 493 this._isPaused = false; 494 this._timeoutHandler = noop; 495 496 (root.cancelAnimationFrame || 497 root.webkitCancelAnimationFrame || 498 root.oCancelAnimationFrame || 499 root.msCancelAnimationFrame || 500 root.mozCancelRequestAnimationFrame || 501 root.clearTimeout)(this._scheduleId); 502 503 if (gotoEnd) { 504 applyFilter(this, 'beforeTween'); 505 tweenProps( 506 1, 507 this._currentState, 508 this._originalState, 509 this._targetState, 510 1, 511 0, 512 this._easing 513 ); 514 applyFilter(this, 'afterTween'); 515 applyFilter(this, 'afterTweenEnd'); 516 this._finish.call(this, this._currentState, this._attachment); 517 } 518 519 return this; 520 }; 521 522 /** 523 * @method isPlaying 524 * @return {boolean} Whether or not a tween is running. 525 */ 526 Tweenable.prototype.isPlaying = function () { 527 return this._isTweening && !this._isPaused; 528 }; 529 530 /** 531 * Set a custom schedule function. 532 * 533 * If a custom function is not set, 534 * [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame) 535 * is used if available, otherwise 536 * [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout) 537 * is used. 538 * @method setScheduleFunction 539 * @param {Function(Function,number)} scheduleFunction The function to be 540 * used to schedule the next frame to be rendered. 541 */ 542 Tweenable.prototype.setScheduleFunction = function (scheduleFunction) { 543 this._scheduleFunction = scheduleFunction; 544 }; 545 546 /** 547 * `delete` all "own" properties. Call this when the `Tweenable` instance 548 * is no longer needed to free memory. 549 * @method dispose 550 */ 551 Tweenable.prototype.dispose = function () { 552 var prop; 553 for (prop in this) { 554 if (this.hasOwnProperty(prop)) { 555 delete this[prop]; 556 } 557 } 558 }; 559 560 /** 561 * Filters are used for transforming the properties of a tween at various 562 * points in a Tweenable's life cycle. See the README for more info on this. 563 * @private 564 */ 565 Tweenable.prototype.filter = {}; 566 567 /** 568 * This object contains all of the tweens available to Shifty. It is 569 * extensible - simply attach properties to the `Tweenable.prototype.formula` 570 * Object following the same format as `linear`. 571 * 572 * `pos` should be a normalized `number` (between 0 and 1). 573 * @property formula 574 * @type {Object(function)} 575 */ 576 Tweenable.prototype.formula = { 577 linear: function (pos) { 578 return pos; 579 } 580 }; 581 582 formula = Tweenable.prototype.formula; 583 584 shallowCopy(Tweenable, { 585 'now': now 586 ,'each': each 587 ,'tweenProps': tweenProps 588 ,'tweenProp': tweenProp 589 ,'applyFilter': applyFilter 590 ,'shallowCopy': shallowCopy 591 ,'defaults': defaults 592 ,'composeEasingObject': composeEasingObject 593 }); 594 595 // `root` is provided in the intro/outro files. 596 597 // A hook used for unit testing. 598 if (typeof SHIFTY_DEBUG_NOW === 'function') { 599 root.timeoutHandler = timeoutHandler; 600 } 601 602 // Bootstrap Tweenable appropriately for the environment. 603 if (typeof exports === 'object') { 604 // CommonJS 605 module.exports = Tweenable; 606 } else if (typeof define === 'function' && define.amd) { 607 // AMD 608 define(function () {return Tweenable;}); 609 } else if (typeof root.Tweenable === 'undefined') { 610 // Browser: Make `Tweenable` globally accessible. 611 root.Tweenable = Tweenable; 612 } 613 614 return Tweenable; 615 616} ()); 617 618/*! 619 * All equations are adapted from Thomas Fuchs' 620 * [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/penner.js). 621 * 622 * Based on Easing Equations (c) 2003 [Robert 623 * Penner](http://www.robertpenner.com/), all rights reserved. This work is 624 * [subject to terms](http://www.robertpenner.com/easing_terms_of_use.html). 625 */ 626 627/*! 628 * TERMS OF USE - EASING EQUATIONS 629 * Open source under the BSD License. 630 * Easing Equations (c) 2003 Robert Penner, all rights reserved. 631 */ 632 633;(function () { 634 635 Tweenable.shallowCopy(Tweenable.prototype.formula, { 636 easeInQuad: function (pos) { 637 return Math.pow(pos, 2); 638 }, 639 640 easeOutQuad: function (pos) { 641 return -(Math.pow((pos - 1), 2) - 1); 642 }, 643 644 easeInOutQuad: function (pos) { 645 if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,2);} 646 return -0.5 * ((pos -= 2) * pos - 2); 647 }, 648 649 easeInCubic: function (pos) { 650 return Math.pow(pos, 3); 651 }, 652 653 easeOutCubic: function (pos) { 654 return (Math.pow((pos - 1), 3) + 1); 655 }, 656 657 easeInOutCubic: function (pos) { 658 if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,3);} 659 return 0.5 * (Math.pow((pos - 2),3) + 2); 660 }, 661 662 easeInQuart: function (pos) { 663 return Math.pow(pos, 4); 664 }, 665 666 easeOutQuart: function (pos) { 667 return -(Math.pow((pos - 1), 4) - 1); 668 }, 669 670 easeInOutQuart: function (pos) { 671 if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,4);} 672 return -0.5 * ((pos -= 2) * Math.pow(pos,3) - 2); 673 }, 674 675 easeInQuint: function (pos) { 676 return Math.pow(pos, 5); 677 }, 678 679 easeOutQuint: function (pos) { 680 return (Math.pow((pos - 1), 5) + 1); 681 }, 682 683 easeInOutQuint: function (pos) { 684 if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,5);} 685 return 0.5 * (Math.pow((pos - 2),5) + 2); 686 }, 687 688 easeInSine: function (pos) { 689 return -Math.cos(pos * (Math.PI / 2)) + 1; 690 }, 691 692 easeOutSine: function (pos) { 693 return Math.sin(pos * (Math.PI / 2)); 694 }, 695 696 easeInOutSine: function (pos) { 697 return (-0.5 * (Math.cos(Math.PI * pos) - 1)); 698 }, 699 700 easeInExpo: function (pos) { 701 return (pos === 0) ? 0 : Math.pow(2, 10 * (pos - 1)); 702 }, 703 704 easeOutExpo: function (pos) { 705 return (pos === 1) ? 1 : -Math.pow(2, -10 * pos) + 1; 706 }, 707 708 easeInOutExpo: function (pos) { 709 if (pos === 0) {return 0;} 710 if (pos === 1) {return 1;} 711 if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(2,10 * (pos - 1));} 712 return 0.5 * (-Math.pow(2, -10 * --pos) + 2); 713 }, 714 715 easeInCirc: function (pos) { 716 return -(Math.sqrt(1 - (pos * pos)) - 1); 717 }, 718 719 easeOutCirc: function (pos) { 720 return Math.sqrt(1 - Math.pow((pos - 1), 2)); 721 }, 722 723 easeInOutCirc: function (pos) { 724 if ((pos /= 0.5) < 1) {return -0.5 * (Math.sqrt(1 - pos * pos) - 1);} 725 return 0.5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1); 726 }, 727 728 easeOutBounce: function (pos) { 729 if ((pos) < (1 / 2.75)) { 730 return (7.5625 * pos * pos); 731 } else if (pos < (2 / 2.75)) { 732 return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75); 733 } else if (pos < (2.5 / 2.75)) { 734 return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375); 735 } else { 736 return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375); 737 } 738 }, 739 740 easeInBack: function (pos) { 741 var s = 1.70158; 742 return (pos) * pos * ((s + 1) * pos - s); 743 }, 744 745 easeOutBack: function (pos) { 746 var s = 1.70158; 747 return (pos = pos - 1) * pos * ((s + 1) * pos + s) + 1; 748 }, 749 750 easeInOutBack: function (pos) { 751 var s = 1.70158; 752 if ((pos /= 0.5) < 1) { 753 return 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)); 754 } 755 return 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2); 756 }, 757 758 elastic: function (pos) { 759 // jshint maxlen:90 760 return -1 * Math.pow(4,-8 * pos) * Math.sin((pos * 6 - 1) * (2 * Math.PI) / 2) + 1; 761 }, 762 763 swingFromTo: function (pos) { 764 var s = 1.70158; 765 return ((pos /= 0.5) < 1) ? 766 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)) : 767 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2); 768 }, 769 770 swingFrom: function (pos) { 771 var s = 1.70158; 772 return pos * pos * ((s + 1) * pos - s); 773 }, 774 775 swingTo: function (pos) { 776 var s = 1.70158; 777 return (pos -= 1) * pos * ((s + 1) * pos + s) + 1; 778 }, 779 780 bounce: function (pos) { 781 if (pos < (1 / 2.75)) { 782 return (7.5625 * pos * pos); 783 } else if (pos < (2 / 2.75)) { 784 return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75); 785 } else if (pos < (2.5 / 2.75)) { 786 return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375); 787 } else { 788 return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375); 789 } 790 }, 791 792 bouncePast: function (pos) { 793 if (pos < (1 / 2.75)) { 794 return (7.5625 * pos * pos); 795 } else if (pos < (2 / 2.75)) { 796 return 2 - (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75); 797 } else if (pos < (2.5 / 2.75)) { 798 return 2 - (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375); 799 } else { 800 return 2 - (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375); 801 } 802 }, 803 804 easeFromTo: function (pos) { 805 if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,4);} 806 return -0.5 * ((pos -= 2) * Math.pow(pos,3) - 2); 807 }, 808 809 easeFrom: function (pos) { 810 return Math.pow(pos,4); 811 }, 812 813 easeTo: function (pos) { 814 return Math.pow(pos,0.25); 815 } 816 }); 817 818}()); 819 820// jshint maxlen:100 821/** 822 * The Bezier magic in this file is adapted/copied almost wholesale from 823 * [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/cubic-bezier.js), 824 * which was adapted from Apple code (which probably came from 825 * [here](http://opensource.apple.com/source/WebCore/WebCore-955.66/platform/graphics/UnitBezier.h)). 826 * Special thanks to Apple and Thomas Fuchs for much of this code. 827 */ 828 829/** 830 * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. 831 * 832 * Redistribution and use in source and binary forms, with or without 833 * modification, are permitted provided that the following conditions are met: 834 * 835 * 1. Redistributions of source code must retain the above copyright notice, 836 * this list of conditions and the following disclaimer. 837 * 838 * 2. Redistributions in binary form must reproduce the above copyright notice, 839 * this list of conditions and the following disclaimer in the documentation 840 * and/or other materials provided with the distribution. 841 * 842 * 3. Neither the name of the copyright holder(s) nor the names of any 843 * contributors may be used to endorse or promote products derived from 844 * this software without specific prior written permission. 845 * 846 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 847 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 848 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 849 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 850 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 851 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 852 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 853 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 854 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 855 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 856 * POSSIBILITY OF SUCH DAMAGE. 857 */ 858;(function () { 859 // port of webkit cubic bezier handling by http://www.netzgesta.de/dev/ 860 function cubicBezierAtTime(t,p1x,p1y,p2x,p2y,duration) { 861 var ax = 0,bx = 0,cx = 0,ay = 0,by = 0,cy = 0; 862 function sampleCurveX(t) { 863 return ((ax * t + bx) * t + cx) * t; 864 } 865 function sampleCurveY(t) { 866 return ((ay * t + by) * t + cy) * t; 867 } 868 function sampleCurveDerivativeX(t) { 869 return (3.0 * ax * t + 2.0 * bx) * t + cx; 870 } 871 function solveEpsilon(duration) { 872 return 1.0 / (200.0 * duration); 873 } 874 function solve(x,epsilon) { 875 return sampleCurveY(solveCurveX(x, epsilon)); 876 } 877 function fabs(n) { 878 if (n >= 0) { 879 return n; 880 } else { 881 return 0 - n; 882 } 883 } 884 function solveCurveX(x, epsilon) { 885 var t0,t1,t2,x2,d2,i; 886 for (t2 = x, i = 0; i < 8; i++) { 887 x2 = sampleCurveX(t2) - x; 888 if (fabs(x2) < epsilon) { 889 return t2; 890 } 891 d2 = sampleCurveDerivativeX(t2); 892 if (fabs(d2) < 1e-6) { 893 break; 894 } 895 t2 = t2 - x2 / d2; 896 } 897 t0 = 0.0; 898 t1 = 1.0; 899 t2 = x; 900 if (t2 < t0) { 901 return t0; 902 } 903 if (t2 > t1) { 904 return t1; 905 } 906 while (t0 < t1) { 907 x2 = sampleCurveX(t2); 908 if (fabs(x2 - x) < epsilon) { 909 return t2; 910 } 911 if (x > x2) { 912 t0 = t2; 913 }else { 914 t1 = t2; 915 } 916 t2 = (t1 - t0) * 0.5 + t0; 917 } 918 return t2; // Failure. 919 } 920 cx = 3.0 * p1x; 921 bx = 3.0 * (p2x - p1x) - cx; 922 ax = 1.0 - cx - bx; 923 cy = 3.0 * p1y; 924 by = 3.0 * (p2y - p1y) - cy; 925 ay = 1.0 - cy - by; 926 return solve(t, solveEpsilon(duration)); 927 } 928 /** 929 * getCubicBezierTransition(x1, y1, x2, y2) -> Function 930 * 931 * Generates a transition easing function that is compatible 932 * with WebKit's CSS transitions `-webkit-transition-timing-function` 933 * CSS property. 934 * 935 * The W3C has more information about CSS3 transition timing functions: 936 * http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag 937 * 938 * @param {number} x1 939 * @param {number} y1 940 * @param {number} x2 941 * @param {number} y2 942 * @return {function} 943 * @private 944 */ 945 function getCubicBezierTransition (x1, y1, x2, y2) { 946 return function (pos) { 947 return cubicBezierAtTime(pos,x1,y1,x2,y2,1); 948 }; 949 } 950 // End ported code 951 952 /** 953 * Create a Bezier easing function and attach it to `{{#crossLink 954 * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}`. This 955 * function gives you total control over the easing curve. Matthew Lein's 956 * [Ceaser](http://matthewlein.com/ceaser/) is a useful tool for visualizing 957 * the curves you can make with this function. 958 * @method setBezierFunction 959 * @param {string} name The name of the easing curve. Overwrites the old 960 * easing function on `{{#crossLink 961 * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}` if it 962 * exists. 963 * @param {number} x1 964 * @param {number} y1 965 * @param {number} x2 966 * @param {number} y2 967 * @return {function} The easing function that was attached to 968 * Tweenable.prototype.formula. 969 */ 970 Tweenable.setBezierFunction = function (name, x1, y1, x2, y2) { 971 var cubicBezierTransition = getCubicBezierTransition(x1, y1, x2, y2); 972 cubicBezierTransition.displayName = name; 973 cubicBezierTransition.x1 = x1; 974 cubicBezierTransition.y1 = y1; 975 cubicBezierTransition.x2 = x2; 976 cubicBezierTransition.y2 = y2; 977 978 return Tweenable.prototype.formula[name] = cubicBezierTransition; 979 }; 980 981 982 /** 983 * `delete` an easing function from `{{#crossLink 984 * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}`. Be 985 * careful with this method, as it `delete`s whatever easing formula matches 986 * `name` (which means you can delete standard Shifty easing functions). 987 * @method unsetBezierFunction 988 * @param {string} name The name of the easing function to delete. 989 * @return {function} 990 */ 991 Tweenable.unsetBezierFunction = function (name) { 992 delete Tweenable.prototype.formula[name]; 993 }; 994 995})(); 996 997;(function () { 998 999 function getInterpolatedValues ( 1000 from, current, targetState, position, easing, delay) { 1001 return Tweenable.tweenProps( 1002 position, current, from, targetState, 1, delay, easing); 1003 } 1004 1005 // Fake a Tweenable and patch some internals. This approach allows us to
1006 // skip uneccessary processing and object recreation, cutting down on garbage 1007 // collection pauses. 1008 var mockTweenable = new Tweenable(); 1009 mockTweenable._filterArgs = []; 1010 1011 /** 1012 * Compute the midpoint of two Objects. This method effectively calculates a 1013 * specific frame of animation that `{{#crossLink 1014 * "Tweenable/tween:method"}}{{/crossLink}}` does many times over the course 1015 * of a full tween. 1016 * 1017 * var interpolatedValues = Tweenable.interpolate({ 1018 * width: '100px', 1019 * opacity: 0, 1020 * color: '#fff' 1021 * }, { 1022 * width: '200px', 1023 * opacity: 1, 1024 * color: '#000' 1025 * }, 0.5); 1026 * 1027 * console.log(interpolatedValues); 1028 * // {opacity: 0.5, width: "150px", color: "rgb(127,127,127)"} 1029 * 1030 * @static 1031 * @method interpolate 1032 * @param {Object} from The starting values to tween from. 1033 * @param {Object} targetState The ending values to tween to. 1034 * @param {number} position The normalized position value (between `0.0` and 1035 * `1.0`) to interpolate the values between `from` and `to` for. `from` 1036 * represents `0` and `to` represents `1`. 1037 * @param {Object.<string|Function>|string|Function} easing The easing 1038 * curve(s) to calculate the midpoint against. You can reference any easing 1039 * function attached to `Tweenable.prototype.formula`, or provide the easing 1040 * function(s) directly. If omitted, this defaults to "linear". 1041 * @param {number=} opt_delay Optional delay to pad the beginning of the 1042 * interpolated tween with. This increases the range of `position` from (`0` 1043 * through `1`) to (`0` through `1 + opt_delay`). So, a delay of `0.5` would 1044 * increase all valid values of `position` to numbers between `0` and `1.5`. 1045 * @return {Object} 1046 */ 1047 Tweenable.interpolate = function ( 1048 from, targetState, position, easing, opt_delay) { 1049 1050 var current = Tweenable.shallowCopy({}, from); 1051 var delay = opt_delay || 0; 1052 var easingObject = Tweenable.composeEasingObject( 1053 from, easing || 'linear'); 1054 1055 mockTweenable.set({}); 1056 1057 // Alias and reuse the _filterArgs array instead of recreating it. 1058 var filterArgs = mockTweenable._filterArgs; 1059 filterArgs.length = 0; 1060 filterArgs[0] = current; 1061 filterArgs[1] = from; 1062 filterArgs[2] = targetState; 1063 filterArgs[3] = easingObject; 1064 1065 // Any defined value transformation must be applied 1066 Tweenable.applyFilter(mockTweenable, 'tweenCreated'); 1067 Tweenable.applyFilter(mockTweenable, 'beforeTween'); 1068 1069 var interpolatedValues = getInterpolatedValues( 1070 from, current, targetState, position, easingObject, delay); 1071 1072 // Transform values back into their original format 1073 Tweenable.applyFilter(mockTweenable, 'afterTween'); 1074 1075 return interpolatedValues; 1076 }; 1077 1078}()); 1079 1080/** 1081 * This module adds string interpolation support to Shifty. 1082 * 1083 * The Token extension allows Shifty to tween numbers inside of strings. Among 1084 * other things, this allows you to animate CSS properties. For example, you 1085 * can do this: 1086 * 1087 * var tweenable = new Tweenable(); 1088 * tweenable.tween({ 1089 * from: { transform: 'translateX(45px)' }, 1090 * to: { transform: 'translateX(90xp)' } 1091 * }); 1092 * 1093 * `translateX(45)` will be tweened to `translateX(90)`. To demonstrate: 1094 * 1095 * var tweenable = new Tweenable(); 1096 * tweenable.tween({ 1097 * from: { transform: 'translateX(45px)' }, 1098 * to: { transform: 'translateX(90px)' }, 1099 * step: function (state) { 1100 * console.log(state.transform); 1101 * } 1102 * }); 1103 * 1104 * The above snippet will log something like this in the console: 1105 * 1106 * translateX(60.3px) 1107 * ... 1108 * translateX(76.05px) 1109 * ... 1110 * translateX(90px) 1111 * 1112 * Another use for this is animating colors: 1113 * 1114 * var tweenable = new Tweenable(); 1115 * tweenable.tween({ 1116 * from: { color: 'rgb(0,255,0)' }, 1117 * to: { color: 'rgb(255,0,255)' }, 1118 * step: function (state) { 1119 * console.log(state.color); 1120 * } 1121 * }); 1122 * 1123 * The above snippet will log something like this: 1124 * 1125 * rgb(84,170,84) 1126 * ... 1127 * rgb(170,84,170) 1128 * ... 1129 * rgb(255,0,255) 1130 * 1131 * This extension also supports hexadecimal colors, in both long (`#ff00ff`) 1132 * and short (`#f0f`) forms. Be aware that hexadecimal input values will be 1133 * converted into the equivalent RGB output values. This is done to optimize 1134 * for performance. 1135 * 1136 * var tweenable = new Tweenable(); 1137 * tweenable.tween({ 1138 * from: { color: '#0f0' }, 1139 * to: { color: '#f0f' }, 1140 * step: function (state) { 1141 * console.log(state.color); 1142 * } 1143 * }); 1144 * 1145 * This snippet will generate the same output as the one before it because 1146 * equivalent values were supplied (just in hexadecimal form rather than RGB): 1147 * 1148 * rgb(84,170,84) 1149 * ... 1150 * rgb(170,84,170) 1151 * ... 1152 * rgb(255,0,255) 1153 * 1154 * ## Easing support 1155 * 1156 * Easing works somewhat differently in the Token extension. This is because
1157 * some CSS properties have multiple values in them, and you might need to 1158 * tween each value along its own easing curve. A basic example: 1159 * 1160 * var tweenable = new Tweenable(); 1161 * tweenable.tween({ 1162 * from: { transform: 'translateX(0px) translateY(0px)' }, 1163 * to: { transform: 'translateX(100px) translateY(100px)' }, 1164 * easing: { transform: 'easeInQuad' }, 1165 * step: function (state) { 1166 * console.log(state.transform); 1167 * } 1168 * }); 1169 * 1170 * The above snippet will create values like this: 1171 * 1172 * translateX(11.56px) translateY(11.56px) 1173 * ... 1174 * translateX(46.24px) translateY(46.24px) 1175 * ... 1176 * translateX(100px) translateY(100px) 1177 * 1178 * In this case, the values for `translateX` and `translateY` are always the 1179 * same for each step of the tween, because they have the same start and end 1180 * points and both use the same easing curve. We can also tween `translateX` 1181 * and `translateY` along independent curves: 1182 * 1183 * var tweenable = new Tweenable(); 1184 * tweenable.tween({ 1185 * from: { transform: 'translateX(0px) translateY(0px)' }, 1186 * to: { transform: 'translateX(100px) translateY(100px)' }, 1187 * easing: { transform: 'easeInQuad bounce' }, 1188 * step: function (state) { 1189 * console.log(state.transform); 1190 * } 1191 * }); 1192 * 1193 * The above snippet will create values like this: 1194 * 1195 * translateX(10.89px) translateY(82.35px) 1196 * ... 1197 * translateX(44.89px) translateY(86.73px) 1198 * ... 1199 * translateX(100px) translateY(100px) 1200 * 1201 * `translateX` and `translateY` are not in sync anymore, because `easeInQuad` 1202 * was specified for `translateX` and `bounce` for `translateY`. Mixing and 1203 * matching easing curves can make for some interesting motion in your 1204 * animations. 1205 * 1206 * The order of the space-separated easing curves correspond the token values 1207 * they apply to. If there are more token values than easing curves listed, 1208 * the last easing curve listed is used. 1209 * @submodule Tweenable.token 1210 */ 1211 1212// token function is defined above only so that dox-foundation sees it as 1213// documentation and renders it. It is never used, and is optimized away at 1214// build time. 1215 1216;(function (Tweenable) { 1217 1218 /** 1219 * @typedef {{ 1220 * formatString: string 1221 * chunkNames: Array.<string> 1222 * }} 1223 * @private 1224 */ 1225 var formatManifest; 1226 1227 // CONSTANTS 1228 1229 var R_NUMBER_COMPONENT = /(\d|\-|\.)/; 1230 var R_FORMAT_CHUNKS = /([^\-0-9\.]+)/g; 1231 var R_UNFORMATTED_VALUES = /[0-9.\-]+/g; 1232 var R_RGB = new RegExp( 1233 'rgb\\(' + R_UNFORMATTED_VALUES.source + 1234 (/,\s*/.source) + R_UNFORMATTED_VALUES.source + 1235 (/,\s*/.source) + R_UNFORMATTED_VALUES.source + '\\)', 'g'); 1236 var R_RGB_PREFIX = /^.*\(/; 1237 var R_HEX = /#([0-9]|[a-f]){3,6}/gi; 1238 var VALUE_PLACEHOLDER = 'VAL'; 1239 1240 // HELPERS 1241 1242 /** 1243 * @param {Array.number} rawValues 1244 * @param {string} prefix 1245 * 1246 * @return {Array.<string>} 1247 * @private 1248 */
vendor: 8,890 bytes, lines 1249-1574
1249 function getFormatChunksFrom (rawValues, prefix) { 1250 var accumulator = []; 1251 1252 var rawValuesLength = rawValues.length; 1253 var i; 1254 1255 for (i = 0; i < rawValuesLength; i++) { 1256 accumulator.push('_' + prefix + '_' + i); 1257 } 1258 1259 return accumulator; 1260 } 1261 1262 /** 1263 * @param {string} formattedString 1264 * 1265 * @return {string} 1266 * @private 1267 */ 1268 function getFormatStringFrom (formattedString) { 1269 var chunks = formattedString.match(R_FORMAT_CHUNKS); 1270 1271 if (!chunks) { 1272 // chunks will be null if there were no tokens to parse in 1273 // formattedString (for example, if formattedString is '2'). Coerce 1274 // chunks to be useful here. 1275 chunks = ['', '']; 1276 1277 // If there is only one chunk, assume that the string is a number 1278 // followed by a token... 1279 // NOTE: This may be an unwise assumption. 1280 } else if (chunks.length === 1 || 1281 // ...or if the string starts with a number component (".", "-", or a 1282 // digit)... 1283 formattedString.charAt(0).match(R_NUMBER_COMPONENT)) { 1284 // ...prepend an empty string here to make sure that the formatted number 1285 // is properly replaced by VALUE_PLACEHOLDER 1286 chunks.unshift(''); 1287 } 1288 1289 return chunks.join(VALUE_PLACEHOLDER); 1290 } 1291 1292 /** 1293 * Convert all hex color values within a string to an rgb string. 1294 * 1295 * @param {Object} stateObject 1296 * 1297 * @return {Object} The modified obj 1298 * @private 1299 */ 1300 function sanitizeObjectForHexProps (stateObject) { 1301 Tweenable.each(stateObject, function (prop) { 1302 var currentProp = stateObject[prop]; 1303 1304 if (typeof currentProp === 'string' && currentProp.match(R_HEX)) { 1305 stateObject[prop] = sanitizeHexChunksToRGB(currentProp); 1306 } 1307 }); 1308 } 1309 1310 /** 1311 * @param {string} str 1312 * 1313 * @return {string} 1314 * @private 1315 */ 1316 function sanitizeHexChunksToRGB (str) { 1317 return filterStringChunks(R_HEX, str, convertHexToRGB); 1318 } 1319 1320 /** 1321 * @param {string} hexString 1322 * 1323 * @return {string} 1324 * @private 1325 */ 1326 function convertHexToRGB (hexString) { 1327 var rgbArr = hexToRGBArray(hexString); 1328 return 'rgb(' + rgbArr[0] + ',' + rgbArr[1] + ',' + rgbArr[2] + ')'; 1329 } 1330 1331 var hexToRGBArray_returnArray = []; 1332 /** 1333 * Convert a hexadecimal string to an array with three items, one each for 1334 * the red, blue, and green decimal values. 1335 * 1336 * @param {string} hex A hexadecimal string. 1337 * 1338 * @returns {Array.<number>} The converted Array of RGB values if `hex` is a 1339 * valid string, or an Array of three 0's. 1340 * @private 1341 */ 1342 function hexToRGBArray (hex) { 1343 1344 hex = hex.replace(/#/, ''); 1345 1346 // If the string is a shorthand three digit hex notation, normalize it to 1347 // the standard six digit notation 1348 if (hex.length === 3) { 1349 hex = hex.split(''); 1350 hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; 1351 } 1352 1353 hexToRGBArray_returnArray[0] = hexToDec(hex.substr(0, 2)); 1354 hexToRGBArray_returnArray[1] = hexToDec(hex.substr(2, 2)); 1355 hexToRGBArray_returnArray[2] = hexToDec(hex.substr(4, 2)); 1356 1357 return hexToRGBArray_returnArray; 1358 } 1359 1360 /** 1361 * Convert a base-16 number to base-10. 1362 * 1363 * @param {Number|String} hex The value to convert 1364 * 1365 * @returns {Number} The base-10 equivalent of `hex`. 1366 * @private 1367 */ 1368 function hexToDec (hex) { 1369 return parseInt(hex, 16); 1370 } 1371 1372 /** 1373 * Runs a filter operation on all chunks of a string that match a RegExp 1374 * 1375 * @param {RegExp} pattern 1376 * @param {string} unfilteredString 1377 * @param {function(string)} filter 1378 * 1379 * @return {string} 1380 * @private 1381 */ 1382 function filterStringChunks (pattern, unfilteredString, filter) { 1383 var pattenMatches = unfilteredString.match(pattern); 1384 var filteredString = unfilteredString.replace(pattern, VALUE_PLACEHOLDER); 1385 1386 if (pattenMatches) { 1387 var pattenMatchesLength = pattenMatches.length; 1388 var currentChunk; 1389 1390 for (var i = 0; i < pattenMatchesLength; i++) { 1391 currentChunk = pattenMatches.shift(); 1392 filteredString = filteredString.replace( 1393 VALUE_PLACEHOLDER, filter(currentChunk)); 1394 } 1395 } 1396 1397 return filteredString; 1398 } 1399 1400 /** 1401 * Check for floating point values within rgb strings and rounds them. 1402 * 1403 * @param {string} formattedString 1404 * 1405 * @return {string} 1406 * @private 1407 */ 1408 function sanitizeRGBChunks (formattedString) { 1409 return filterStringChunks(R_RGB, formattedString, sanitizeRGBChunk); 1410 } 1411 1412 /** 1413 * @param {string} rgbChunk 1414 * 1415 * @return {string} 1416 * @private 1417 */ 1418 function sanitizeRGBChunk (rgbChunk) { 1419 var numbers = rgbChunk.match(R_UNFORMATTED_VALUES); 1420 var numbersLength = numbers.length; 1421 var sanitizedString = rgbChunk.match(R_RGB_PREFIX)[0]; 1422 1423 for (var i = 0; i < numbersLength; i++) { 1424 sanitizedString += parseInt(numbers[i], 10) + ','; 1425 } 1426 1427 sanitizedString = sanitizedString.slice(0, -1) + ')'; 1428 1429 return sanitizedString; 1430 } 1431 1432 /** 1433 * @param {Object} stateObject 1434 * 1435 * @return {Object} An Object of formatManifests that correspond to 1436 * the string properties of stateObject 1437 * @private 1438 */ 1439 function getFormatManifests (stateObject) { 1440 var manifestAccumulator = {}; 1441 1442 Tweenable.each(stateObject, function (prop) { 1443 var currentProp = stateObject[prop]; 1444 1445 if (typeof currentProp === 'string') { 1446 var rawValues = getValuesFrom(currentProp); 1447 1448 manifestAccumulator[prop] = { 1449 'formatString': getFormatStringFrom(currentProp) 1450 ,'chunkNames': getFormatChunksFrom(rawValues, prop) 1451 }; 1452 } 1453 }); 1454 1455 return manifestAccumulator; 1456 } 1457 1458 /** 1459 * @param {Object} stateObject 1460 * @param {Object} formatManifests 1461 * @private 1462 */ 1463 function expandFormattedProperties (stateObject, formatManifests) { 1464 Tweenable.each(formatManifests, function (prop) { 1465 var currentProp = stateObject[prop]; 1466 var rawValues = getValuesFrom(currentProp); 1467 var rawValuesLength = rawValues.length; 1468 1469 for (var i = 0; i < rawValuesLength; i++) { 1470 stateObject[formatManifests[prop].chunkNames[i]] = +rawValues[i]; 1471 } 1472 1473 delete stateObject[prop]; 1474 }); 1475 } 1476 1477 /** 1478 * @param {Object} stateObject 1479 * @param {Object} formatManifests 1480 * @private 1481 */ 1482 function collapseFormattedProperties (stateObject, formatManifests) { 1483 Tweenable.each(formatManifests, function (prop) { 1484 var currentProp = stateObject[prop]; 1485 var formatChunks = extractPropertyChunks( 1486 stateObject, formatManifests[prop].chunkNames); 1487 var valuesList = getValuesList( 1488 formatChunks, formatManifests[prop].chunkNames); 1489 currentProp = getFormattedValues( 1490 formatManifests[prop].formatString, valuesList); 1491 stateObject[prop] = sanitizeRGBChunks(currentProp); 1492 }); 1493 } 1494 1495 /** 1496 * @param {Object} stateObject 1497 * @param {Array.<string>} chunkNames 1498 * 1499 * @return {Object} The extracted value chunks. 1500 * @private 1501 */ 1502 function extractPropertyChunks (stateObject, chunkNames) { 1503 var extractedValues = {}; 1504 var currentChunkName, chunkNamesLength = chunkNames.length; 1505 1506 for (var i = 0; i < chunkNamesLength; i++) { 1507 currentChunkName = chunkNames[i]; 1508 extractedValues[currentChunkName] = stateObject[currentChunkName]; 1509 delete stateObject[currentChunkName]; 1510 } 1511 1512 return extractedValues; 1513 } 1514 1515 var getValuesList_accumulator = []; 1516 /** 1517 * @param {Object} stateObject 1518 * @param {Array.<string>} chunkNames 1519 * 1520 * @return {Array.<number>} 1521 * @private 1522 */ 1523 function getValuesList (stateObject, chunkNames) { 1524 getValuesList_accumulator.length = 0; 1525 var chunkNamesLength = chunkNames.length; 1526 1527 for (var i = 0; i < chunkNamesLength; i++) { 1528 getValuesList_accumulator.push(stateObject[chunkNames[i]]); 1529 } 1530 1531 return getValuesList_accumulator; 1532 } 1533 1534 /** 1535 * @param {string} formatString 1536 * @param {Array.<number>} rawValues 1537 * 1538 * @return {string} 1539 * @private 1540 */ 1541 function getFormattedValues (formatString, rawValues) { 1542 var formattedValueString = formatString; 1543 var rawValuesLength = rawValues.length; 1544 1545 for (var i = 0; i < rawValuesLength; i++) { 1546 formattedValueString = formattedValueString.replace( 1547 VALUE_PLACEHOLDER, +rawValues[i].toFixed(4)); 1548 } 1549 1550 return formattedValueString; 1551 } 1552 1553 /** 1554 * Note: It's the duty of the caller to convert the Array elements of the 1555 * return value into numbers. This is a performance optimization. 1556 * 1557 * @param {string} formattedString 1558 * 1559 * @return {Array.<string>|null} 1560 * @private 1561 */ 1562 function getValuesFrom (formattedString) { 1563 return formattedString.match(R_UNFORMATTED_VALUES); 1564 } 1565 1566 /** 1567 * @param {Object} easingObject 1568 * @param {Object} tokenData 1569 * @private 1570 */ 1571 function expandEasingObject (easingObject, tokenData) { 1572 Tweenable.each(tokenData, function (prop) { 1573 var currentProp = tokenData[prop]; 1574 var chunkNames = currentProp.chunkNames;
1575 var chunkLength = chunkNames.length; 1576 1577 var easing = easingObject[prop]; 1578 var i; 1579 1580 if (typeof easing === 'string') { 1581 var easingChunks = easing.split(' '); 1582 var lastEasingChunk = easingChunks[easingChunks.length - 1]; 1583 1584 for (i = 0; i < chunkLength; i++) { 1585 easingObject[chunkNames[i]] = easingChunks[i] || lastEasingChunk; 1586 } 1587 1588 } else { 1589 for (i = 0; i < chunkLength; i++) { 1590 easingObject[chunkNames[i]] = easing; 1591 } 1592 } 1593 1594 delete easingObject[prop]; 1595 }); 1596 } 1597 1598 /** 1599 * @param {Object} easingObject 1600 * @param {Object} tokenData 1601 * @private 1602 */ 1603 function collapseEasingObject (easingObject, tokenData) { 1604 Tweenable.each(tokenData, function (prop) { 1605 var currentProp = tokenData[prop]; 1606 var chunkNames = currentProp.chunkNames; 1607 var chunkLength = chunkNames.length; 1608 1609 var firstEasing = easingObject[chunkNames[0]]; 1610 var typeofEasings = typeof firstEasing; 1611 1612 if (typeofEasings === 'string') { 1613 var composedEasingString = ''; 1614 1615 for (var i = 0; i < chunkLength; i++) { 1616 composedEasingString += ' ' + easingObject[chunkNames[i]]; 1617 delete easingObject[chunkNames[i]]; 1618 } 1619 1620 easingObject[prop] = composedEasingString.substr(1); 1621 } else { 1622 easingObject[prop] = firstEasing; 1623 } 1624 }); 1625 } 1626 1627 Tweenable.prototype.filter.token = { 1628 'tweenCreated': function (currentState, fromState, toState, easingObject) { 1629 sanitizeObjectForHexProps(currentState); 1630 sanitizeObjectForHexProps(fromState); 1631 sanitizeObjectForHexProps(toState); 1632 this._tokenData = getFormatManifests(currentState); 1633 }, 1634 1635 'beforeTween': function (currentState, fromState, toState, easingObject) { 1636 expandEasingObject(easingObject, this._tokenData); 1637 expandFormattedProperties(currentState, this._tokenData); 1638 expandFormattedProperties(fromState, this._tokenData); 1639 expandFormattedProperties(toState, this._tokenData); 1640 }, 1641 1642 'afterTween': function (currentState, fromState, toState, easingObject) { 1643 collapseFormattedProperties(currentState, this._tokenData); 1644 collapseFormattedProperties(fromState, this._tokenData); 1645 collapseFormattedProperties(toState, this._tokenData); 1646 collapseEasingObject(easingObject, this._tokenData); 1647 } 1648 }; 1649 1650} (Tweenable)); 1651 1652}).call(null); 1653 1654},{}],2:[function(require,module,exports){ 1655// Circle shaped progress bar 1656 1657var Shape = require('./shape'); 1658var utils = require('./utils'); 1659 1660var Circle = function Circle(container, options) { 1661 // Use two arcs to form a circle 1662 // See this answer http://stackoverflow.com/a/10477334/1446092 1663 this._pathTemplate = 1664 'M 50,50 m 0,-{radius}' + 1665 ' a {radius},{radius} 0 1 1 0,{2radius}' + 1666 ' a {radius},{radius} 0 1 1 0,-{2radius}'; 1667 1668 this.containerAspectRatio = 1; 1669 1670 Shape.apply(this, arguments); 1671}; 1672 1673Circle.prototype = new Shape(); 1674Circle.prototype.constructor = Circle; 1675 1676Circle.prototype._pathString = function _pathString(opts) { 1677 var widthOfWider = opts.strokeWidth; 1678 if (opts.trailWidth && opts.trailWidth > opts.strokeWidth) { 1679 widthOfWider = opts.trailWidth; 1680 } 1681 1682 var r = 50 - widthOfWider / 2; 1683 1684 return utils.render(this._pathTemplate, { 1685 radius: r, 1686 '2radius': r * 2 1687 }); 1688}; 1689 1690Circle.prototype._trailString = function _trailString(opts) { 1691 return this._pathString(opts); 1692}; 1693 1694module.exports = Circle; 1695 1696},{"./shape":7,"./utils":9}],3:[function(require,module,exports){ 1697// Line shaped progress bar 1698 1699var Shape = require('./shape'); 1700var utils = require('./utils'); 1701 1702var Line = function Line(container, options) { 1703 this._pathTemplate = 'M 0,{center} L 100,{center}'; 1704 Shape.apply(this, arguments); 1705}; 1706 1707Line.prototype = new Shape(); 1708Line.prototype.constructor = Line; 1709 1710Line.prototype._initializeSvg = function _initializeSvg(svg, opts) { 1711 svg.setAttribute('viewBox', '0 0 100 ' + opts.strokeWidth); 1712 svg.setAttribute('preserveAspectRatio', 'none'); 1713}; 1714 1715Line.prototype._pathString = function _pathString(opts) { 1716 return utils.render(this._pathTemplate, { 1717 center: opts.strokeWidth / 2 1718 }); 1719}; 1720 1721Line.prototype._trailString = function _trailString(opts) { 1722 return this._pathString(opts); 1723}; 1724 1725module.exports = Line; 1726 1727},{"./shape":7,"./utils":9}],4:[function(require,module,exports){ 1728module.exports = { 1729 // Higher level API, different shaped progress bars 1730 Line: require('./line'), 1731 Circle: require('./circle'), 1732 SemiCircle: require('./semicircle'), 1733 Square: require('./square'), 1734 1735 // Lower level API to use any SVG path 1736 Path: require('./path'), 1737 1738 // Base-class for creating new custom shapes 1739 // to be in line with the API of built-in shapes 1740 // Undocumented. 1741 Shape: require('./shape'), 1742 1743 // Internal utils, undocumented. 1744 utils: require('./utils') 1745}; 1746 1747},{"./circle":2,"./line":3,"./path":5,"./semicircle":6,"./shape":7,"./square":8,"./utils":9}],5:[function(require,module,exports){ 1748// Lower level API to animate any kind of svg path 1749 1750var Tweenable = require('shifty'); 1751var utils = require('./utils'); 1752 1753var EASING_ALIASES = { 1754 easeIn: 'easeInCubic', 1755 easeOut: 'easeOutCubic', 1756 easeInOut: 'easeInOutCubic' 1757}; 1758
vendor: 20,791 bytes, lines 1759-2484
1759var Path = function Path(path, opts) { 1760 // Throw a better error if not initialized with `new` keyword 1761 if (!(this instanceof Path)) { 1762 throw new Error('Constructor was called without new keyword'); 1763 } 1764 1765 // Default parameters for animation 1766 opts = utils.extend({ 1767 duration: 800, 1768 easing: 'linear', 1769 from: {}, 1770 to: {}, 1771 step: function() {} 1772 }, opts); 1773 1774 var element; 1775 if (utils.isString(path)) { 1776 element = document.querySelector(path); 1777 } else { 1778 element = path; 1779 } 1780 1781 // Reveal .path as public attribute 1782 this.path = element; 1783 this._opts = opts; 1784 this._tweenable = null; 1785 1786 // Set up the starting positions 1787 var length = this.path.getTotalLength(); 1788 this.path.style.strokeDasharray = length + ' ' + length; 1789 this.set(0); 1790}; 1791 1792Path.prototype.value = function value() { 1793 var offset = this._getComputedDashOffset(); 1794 var length = this.path.getTotalLength(); 1795 1796 var progress = 1 - offset / length; 1797 // Round number to prevent returning very small number like 1e-30, which 1798 // is practically 0 1799 return parseFloat(progress.toFixed(6), 10); 1800}; 1801 1802Path.prototype.set = function set(progress) { 1803 this.stop(); 1804 1805 this.path.style.strokeDashoffset = this._progressToOffset(progress); 1806 1807 var step = this._opts.step; 1808 if (utils.isFunction(step)) { 1809 var easing = this._easing(this._opts.easing); 1810 var values = this._calculateTo(progress, easing); 1811 var reference = this._opts.shape || this; 1812 step(values, reference, this._opts.attachment); 1813 } 1814}; 1815 1816Path.prototype.stop = function stop() { 1817 this._stopTween(); 1818 this.path.style.strokeDashoffset = this._getComputedDashOffset(); 1819}; 1820 1821// Method introduced here: 1822// http://jakearchibald.com/2013/animated-line-drawing-svg/ 1823Path.prototype.animate = function animate(progress, opts, cb) { 1824 opts = opts || {}; 1825 1826 if (utils.isFunction(opts)) { 1827 cb = opts; 1828 opts = {}; 1829 } 1830 1831 var passedOpts = utils.extend({}, opts); 1832 1833 // Copy default opts to new object so defaults are not modified 1834 var defaultOpts = utils.extend({}, this._opts); 1835 opts = utils.extend(defaultOpts, opts); 1836 1837 var shiftyEasing = this._easing(opts.easing); 1838 var values = this._resolveFromAndTo(progress, shiftyEasing, passedOpts); 1839 1840 this.stop(); 1841 1842 // Trigger a layout so styles are calculated & the browser 1843 // picks up the starting position before animating 1844 this.path.getBoundingClientRect(); 1845 1846 var offset = this._getComputedDashOffset(); 1847 var newOffset = this._progressToOffset(progress); 1848 1849 var self = this; 1850 this._tweenable = new Tweenable(); 1851 this._tweenable.tween({ 1852 from: utils.extend({ offset: offset }, values.from), 1853 to: utils.extend({ offset: newOffset }, values.to), 1854 duration: opts.duration, 1855 easing: shiftyEasing, 1856 step: function(state) { 1857 self.path.style.strokeDashoffset = state.offset; 1858 var reference = opts.shape || self; 1859 opts.step(state, reference, opts.attachment); 1860 }, 1861 finish: function(state) { 1862 if (utils.isFunction(cb)) { 1863 cb(); 1864 } 1865 } 1866 }); 1867}; 1868 1869Path.prototype._getComputedDashOffset = function _getComputedDashOffset() { 1870 var computedStyle = window.getComputedStyle(this.path, null); 1871 return parseFloat(computedStyle.getPropertyValue('stroke-dashoffset'), 10); 1872}; 1873 1874Path.prototype._progressToOffset = function _progressToOffset(progress) { 1875 var length = this.path.getTotalLength(); 1876 return length - progress * length; 1877}; 1878 1879// Resolves from and to values for animation. 1880Path.prototype._resolveFromAndTo = function _resolveFromAndTo(progress, easing, opts) { 1881 if (opts.from && opts.to) { 1882 return { 1883 from: opts.from, 1884 to: opts.to 1885 }; 1886 } 1887 1888 return { 1889 from: this._calculateFrom(easing), 1890 to: this._calculateTo(progress, easing) 1891 }; 1892}; 1893 1894// Calculate `from` values from options passed at initialization 1895Path.prototype._calculateFrom = function _calculateFrom(easing) { 1896 return Tweenable.interpolate(this._opts.from, this._opts.to, this.value(), easing); 1897}; 1898 1899// Calculate `to` values from options passed at initialization 1900Path.prototype._calculateTo = function _calculateTo(progress, easing) { 1901 return Tweenable.interpolate(this._opts.from, this._opts.to, progress, easing); 1902}; 1903 1904Path.prototype._stopTween = function _stopTween() { 1905 if (this._tweenable !== null) { 1906 this._tweenable.stop(); 1907 this._tweenable = null; 1908 } 1909}; 1910 1911Path.prototype._easing = function _easing(easing) { 1912 if (EASING_ALIASES.hasOwnProperty(easing)) { 1913 return EASING_ALIASES[easing]; 1914 } 1915 1916 return easing; 1917}; 1918 1919module.exports = Path; 1920 1921},{"./utils":9,"shifty":1}],6:[function(require,module,exports){ 1922// Semi-SemiCircle shaped progress bar 1923 1924var Shape = require('./shape'); 1925var Circle = require('./circle'); 1926var utils = require('./utils'); 1927 1928var SemiCircle = function SemiCircle(container, options) { 1929 // Use one arc to form a SemiCircle 1930 // See this answer http://stackoverflow.com/a/10477334/1446092 1931 this._pathTemplate = 1932 'M 50,50 m -{radius},0' + 1933 ' a {radius},{radius} 0 1 1 {2radius},0'; 1934 1935 this.containerAspectRatio = 2; 1936 1937 Shape.apply(this, arguments); 1938}; 1939 1940SemiCircle.prototype = new Shape(); 1941SemiCircle.prototype.constructor = SemiCircle; 1942 1943SemiCircle.prototype._initializeSvg = function _initializeSvg(svg, opts) { 1944 svg.setAttribute('viewBox', '0 0 100 50'); 1945}; 1946 1947SemiCircle.prototype._initializeTextContainer = function _initializeTextContainer( 1948 opts, 1949 container, 1950 textContainer 1951) { 1952 if (opts.text.style) { 1953 // Reset top style 1954 textContainer.style.top = 'auto'; 1955 textContainer.style.bottom = '0'; 1956 1957 if (opts.text.alignToBottom) { 1958 utils.setStyle(textContainer, 'transform', 'translate(-50%, 0)'); 1959 } else { 1960 utils.setStyle(textContainer, 'transform', 'translate(-50%, 50%)'); 1961 } 1962 } 1963}; 1964 1965// Share functionality with Circle, just have different path 1966SemiCircle.prototype._pathString = Circle.prototype._pathString; 1967SemiCircle.prototype._trailString = Circle.prototype._trailString; 1968 1969module.exports = SemiCircle; 1970 1971},{"./circle":2,"./shape":7,"./utils":9}],7:[function(require,module,exports){ 1972// Base object for different progress bar shapes 1973 1974var Path = require('./path'); 1975var utils = require('./utils'); 1976 1977var DESTROYED_ERROR = 'Object is destroyed'; 1978 1979var Shape = function Shape(container, opts) { 1980 // Throw a better error if progress bars are not initialized with `new` 1981 // keyword 1982 if (!(this instanceof Shape)) { 1983 throw new Error('Constructor was called without new keyword'); 1984 } 1985 1986 // Prevent calling constructor without parameters so inheritance 1987 // works correctly. To understand, this is how Shape is inherited: 1988 // 1989 // Line.prototype = new Shape(); 1990 // 1991 // We just want to set the prototype for Line. 1992 if (arguments.length === 0) { 1993 return; 1994 } 1995 1996 // Default parameters for progress bar creation 1997 this._opts = utils.extend({ 1998 color: '#555', 1999 strokeWidth: 1.0, 2000 trailColor: null, 2001 trailWidth: null, 2002 fill: null, 2003 text: { 2004 style: { 2005 color: null, 2006 position: 'absolute', 2007 left: '50%', 2008 top: '50%', 2009 padding: 0, 2010 margin: 0, 2011 transform: { 2012 prefix: true, 2013 value: 'translate(-50%, -50%)' 2014 } 2015 }, 2016 autoStyleContainer: true, 2017 alignToBottom: true, 2018 value: null, 2019 className: 'progressbar-text' 2020 }, 2021 svgStyle: { 2022 display: 'block', 2023 width: '100%' 2024 }, 2025 warnings: false 2026 }, opts, true); // Use recursive extend 2027 2028 // If user specifies e.g. svgStyle or text style, the whole object 2029 // should replace the defaults to make working with styles easier 2030 if (utils.isObject(opts) && opts.svgStyle !== undefined) { 2031 this._opts.svgStyle = opts.svgStyle; 2032 } 2033 if (utils.isObject(opts) && utils.isObject(opts.text) && opts.text.style !== undefined) { 2034 this._opts.text.style = opts.text.style; 2035 } 2036 2037 var svgView = this._createSvgView(this._opts); 2038 2039 var element; 2040 if (utils.isString(container)) { 2041 element = document.querySelector(container); 2042 } else { 2043 element = container; 2044 } 2045 2046 if (!element) { 2047 throw new Error('Container does not exist: ' + container); 2048 } 2049 2050 this._container = element; 2051 this._container.appendChild(svgView.svg); 2052 if (this._opts.warnings) { 2053 this._warnContainerAspectRatio(this._container); 2054 } 2055 2056 if (this._opts.svgStyle) { 2057 utils.setStyles(svgView.svg, this._opts.svgStyle); 2058 } 2059 2060 // Expose public attributes before Path initialization 2061 this.svg = svgView.svg; 2062 this.path = svgView.path; 2063 this.trail = svgView.trail; 2064 this.text = null; 2065 2066 var newOpts = utils.extend({ 2067 attachment: undefined, 2068 shape: this 2069 }, this._opts); 2070 this._progressPath = new Path(svgView.path, newOpts); 2071 2072 if (utils.isObject(this._opts.text) && this._opts.text.value !== null) { 2073 this.setText(this._opts.text.value); 2074 } 2075}; 2076 2077Shape.prototype.animate = function animate(progress, opts, cb) { 2078 if (this._progressPath === null) { 2079 throw new Error(DESTROYED_ERROR); 2080 } 2081 2082 this._progressPath.animate(progress, opts, cb); 2083}; 2084 2085Shape.prototype.stop = function stop() { 2086 if (this._progressPath === null) { 2087 throw new Error(DESTROYED_ERROR); 2088 } 2089 2090 // Don't crash if stop is called inside step function 2091 if (this._progressPath === undefined) { 2092 return; 2093 } 2094 2095 this._progressPath.stop(); 2096}; 2097 2098Shape.prototype.destroy = function destroy() { 2099 if (this._progressPath === null) { 2100 throw new Error(DESTROYED_ERROR); 2101 } 2102 2103 this.stop(); 2104 this.svg.parentNode.removeChild(this.svg); 2105 this.svg = null; 2106 this.path = null; 2107 this.trail = null; 2108 this._progressPath = null; 2109 2110 if (this.text !== null) { 2111 this.text.parentNode.removeChild(this.text); 2112 this.text = null; 2113 } 2114}; 2115 2116Shape.prototype.set = function set(progress) { 2117 if (this._progressPath === null) { 2118 throw new Error(DESTROYED_ERROR); 2119 } 2120 2121 this._progressPath.set(progress); 2122}; 2123 2124Shape.prototype.value = function value() { 2125 if (this._progressPath === null) { 2126 throw new Error(DESTROYED_ERROR); 2127 } 2128 2129 if (this._progressPath === undefined) { 2130 return 0; 2131 } 2132 2133 return this._progressPath.value(); 2134}; 2135 2136Shape.prototype.setText = function setText(newText) { 2137 if (this._progressPath === null) { 2138 throw new Error(DESTROYED_ERROR); 2139 } 2140 2141 if (this.text === null) { 2142 // Create new text node 2143 this.text = this._createTextContainer(this._opts, this._container); 2144 this._container.appendChild(this.text); 2145 } 2146 2147 // Remove previous text and add new 2148 if (utils.isObject(newText)) { 2149 utils.removeChildren(this.text); 2150 this.text.appendChild(newText); 2151 } else { 2152 this.text.innerHTML = newText; 2153 } 2154}; 2155 2156Shape.prototype._createSvgView = function _createSvgView(opts) { 2157 var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 2158 this._initializeSvg(svg, opts); 2159 2160 var trailPath = null; 2161 // Each option listed in the if condition are 'triggers' for creating 2162 // the trail path 2163 if (opts.trailColor || opts.trailWidth) { 2164 trailPath = this._createTrail(opts); 2165 svg.appendChild(trailPath); 2166 } 2167 2168 var path = this._createPath(opts); 2169 svg.appendChild(path); 2170 2171 return { 2172 svg: svg, 2173 path: path, 2174 trail: trailPath 2175 }; 2176}; 2177 2178Shape.prototype._initializeSvg = function _initializeSvg(svg, opts) { 2179 svg.setAttribute('viewBox', '0 0 100 100'); 2180}; 2181 2182Shape.prototype._createPath = function _createPath(opts) { 2183 var pathString = this._pathString(opts); 2184 return this._createPathElement(pathString, opts); 2185}; 2186 2187Shape.prototype._createTrail = function _createTrail(opts) { 2188 // Create path string with original passed options 2189 var pathString = this._trailString(opts); 2190 2191 // Prevent modifying original 2192 var newOpts = utils.extend({}, opts); 2193 2194 // Defaults for parameters which modify trail path 2195 if (!newOpts.trailColor) { 2196 newOpts.trailColor = '#eee'; 2197 } 2198 if (!newOpts.trailWidth) { 2199 newOpts.trailWidth = newOpts.strokeWidth; 2200 } 2201 2202 newOpts.color = newOpts.trailColor; 2203 newOpts.strokeWidth = newOpts.trailWidth; 2204 2205 // When trail path is set, fill must be set for it instead of the 2206 // actual path to prevent trail stroke from clipping 2207 newOpts.fill = null; 2208 2209 return this._createPathElement(pathString, newOpts); 2210}; 2211 2212Shape.prototype._createPathElement = function _createPathElement(pathString, opts) { 2213 var path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); 2214 path.setAttribute('d', pathString); 2215 path.setAttribute('stroke', opts.color); 2216 path.setAttribute('stroke-width', opts.strokeWidth); 2217 2218 if (opts.fill) { 2219 path.setAttribute('fill', opts.fill); 2220 } else { 2221 path.setAttribute('fill-opacity', '0'); 2222 } 2223 2224 return path; 2225}; 2226 2227Shape.prototype._createTextContainer = function _createTextContainer(opts, container) { 2228 var textContainer = document.createElement('div'); 2229 textContainer.className = opts.text.className; 2230 2231 var textStyle = opts.text.style; 2232 if (textStyle) { 2233 if (opts.text.autoStyleContainer) { 2234 container.style.position = 'relative'; 2235 } 2236 2237 utils.setStyles(textContainer, textStyle); 2238 // Default text color to progress bar's color 2239 if (!textStyle.color) { 2240 textContainer.style.color = opts.color; 2241 } 2242 } 2243 2244 this._initializeTextContainer(opts, container, textContainer); 2245 return textContainer; 2246}; 2247 2248// Give custom shapes possibility to modify text element 2249Shape.prototype._initializeTextContainer = function(opts, container, element) { 2250 // By default, no-op 2251 // Custom shapes should respect API options, such as text.style 2252}; 2253 2254Shape.prototype._pathString = function _pathString(opts) { 2255 throw new Error('Override this function for each progress bar'); 2256}; 2257 2258Shape.prototype._trailString = function _trailString(opts) { 2259 throw new Error('Override this function for each progress bar'); 2260}; 2261 2262Shape.prototype._warnContainerAspectRatio = function _warnContainerAspectRatio(container) { 2263 if (!this.containerAspectRatio) { 2264 return; 2265 } 2266 2267 var computedStyle = window.getComputedStyle(container, null); 2268 var width = parseFloat(computedStyle.getPropertyValue('width'), 10); 2269 var height = parseFloat(computedStyle.getPropertyValue('height'), 10); 2270 if (!utils.floatEquals(this.containerAspectRatio, width / height)) { 2271 console.warn( 2272 'Incorrect aspect ratio of container', 2273 '#' + container.id, 2274 'detected:', 2275 computedStyle.getPropertyValue('width') + '(width)', 2276 '/', 2277 computedStyle.getPropertyValue('height') + '(height)', 2278 '=', 2279 width / height 2280 ); 2281 2282 console.warn( 2283 'Aspect ratio of should be', 2284 this.containerAspectRatio 2285 ); 2286 } 2287}; 2288 2289module.exports = Shape; 2290 2291},{"./path":5,"./utils":9}],8:[function(require,module,exports){ 2292// Square shaped progress bar 2293// Note: Square is not core part of API anymore. It's left here 2294// for reference. square is not included to the progressbar 2295// build anymore 2296 2297var Shape = require('./shape'); 2298var utils = require('./utils'); 2299 2300var Square = function Square(container, options) { 2301 this._pathTemplate = 2302 'M 0,{halfOfStrokeWidth}' + 2303 ' L {width},{halfOfStrokeWidth}' + 2304 ' L {width},{width}' + 2305 ' L {halfOfStrokeWidth},{width}' + 2306 ' L {halfOfStrokeWidth},{strokeWidth}'; 2307 2308 this._trailTemplate = 2309 'M {startMargin},{halfOfStrokeWidth}' + 2310 ' L {width},{halfOfStrokeWidth}' + 2311 ' L {width},{width}' + 2312 ' L {halfOfStrokeWidth},{width}' + 2313 ' L {halfOfStrokeWidth},{halfOfStrokeWidth}'; 2314 2315 Shape.apply(this, arguments); 2316}; 2317 2318Square.prototype = new Shape(); 2319Square.prototype.constructor = Square; 2320 2321Square.prototype._pathString = function _pathString(opts) { 2322 var w = 100 - opts.strokeWidth / 2; 2323 2324 return utils.render(this._pathTemplate, { 2325 width: w, 2326 strokeWidth: opts.strokeWidth, 2327 halfOfStrokeWidth: opts.strokeWidth / 2 2328 }); 2329}; 2330 2331Square.prototype._trailString = function _trailString(opts) { 2332 var w = 100 - opts.strokeWidth / 2; 2333 2334 return utils.render(this._trailTemplate, { 2335 width: w, 2336 strokeWidth: opts.strokeWidth, 2337 halfOfStrokeWidth: opts.strokeWidth / 2, 2338 startMargin: opts.strokeWidth / 2 - opts.trailWidth / 2 2339 }); 2340}; 2341 2342module.exports = Square; 2343 2344},{"./shape":7,"./utils":9}],9:[function(require,module,exports){ 2345// Utility functions 2346 2347var PREFIXES = 'Webkit Moz O ms'.split(' '); 2348var FLOAT_COMPARISON_EPSILON = 0.001; 2349 2350// Copy all attributes from source object to destination object. 2351// destination object is mutated. 2352function extend(destination, source, recursive) { 2353 destination = destination || {}; 2354 source = source || {}; 2355 recursive = recursive || false; 2356 2357 for (var attrName in source) { 2358 if (source.hasOwnProperty(attrName)) { 2359 var destVal = destination[attrName]; 2360 var sourceVal = source[attrName]; 2361 if (recursive && isObject(destVal) && isObject(sourceVal)) { 2362 destination[attrName] = extend(destVal, sourceVal, recursive); 2363 } else { 2364 destination[attrName] = sourceVal; 2365 } 2366 } 2367 } 2368 2369 return destination; 2370} 2371 2372// Renders templates with given variables. Variables must be surrounded with 2373// braces without any spaces, e.g. {variable} 2374// All instances of variable placeholders will be replaced with given content 2375// Example: 2376// render('Hello, {message}!', {message: 'world'}) 2377function render(template, vars) { 2378 var rendered = template; 2379 2380 for (var key in vars) { 2381 if (vars.hasOwnProperty(key)) { 2382 var val = vars[key]; 2383 var regExpString = '\\{' + key + '\\}'; 2384 var regExp = new RegExp(regExpString, 'g'); 2385 2386 rendered = rendered.replace(regExp, val); 2387 } 2388 } 2389 2390 return rendered; 2391} 2392 2393function setStyle(element, style, value) { 2394 var elStyle = element.style; // cache for performance 2395 2396 for (var i = 0; i < PREFIXES.length; ++i) { 2397 var prefix = PREFIXES[i]; 2398 elStyle[prefix + capitalize(style)] = value; 2399 } 2400 2401 elStyle[style] = value; 2402} 2403 2404function setStyles(element, styles) { 2405 forEachObject(styles, function(styleValue, styleName) { 2406 // Allow disabling some individual styles by setting them 2407 // to null or undefined 2408 if (styleValue === null || styleValue === undefined) { 2409 return; 2410 } 2411 2412 // If style's value is {prefix: true, value: '50%'}, 2413 // Set also browser prefixed styles 2414 if (isObject(styleValue) && styleValue.prefix === true) { 2415 setStyle(element, styleName, styleValue.value); 2416 } else { 2417 element.style[styleName] = styleValue; 2418 } 2419 }); 2420} 2421 2422function capitalize(text) { 2423 return text.charAt(0).toUpperCase() + text.slice(1); 2424} 2425 2426function isString(obj) { 2427 return typeof obj === 'string' || obj instanceof String; 2428} 2429 2430function isFunction(obj) { 2431 return typeof obj === 'function'; 2432} 2433 2434function isArray(obj) { 2435 return Object.prototype.toString.call(obj) === '[object Array]'; 2436} 2437 2438// Returns true if `obj` is object as in {a: 1, b: 2}, not if it's function or 2439// array 2440function isObject(obj) { 2441 if (isArray(obj)) { 2442 return false; 2443 } 2444 2445 var type = typeof obj; 2446 return type === 'object' && !!obj; 2447} 2448 2449function forEachObject(object, callback) { 2450 for (var key in object) { 2451 if (object.hasOwnProperty(key)) { 2452 var val = object[key]; 2453 callback(val, key); 2454 } 2455 } 2456} 2457 2458function floatEquals(a, b) { 2459 return Math.abs(a - b) < FLOAT_COMPARISON_EPSILON; 2460} 2461 2462// https://coderwall.com/p/nygghw/don-t-use-innerhtml-to-empty-dom-elements 2463function removeChildren(el) { 2464 while (el.firstChild) { 2465 el.removeChild(el.firstChild); 2466 } 2467} 2468 2469module.exports = { 2470 extend: extend, 2471 render: render, 2472 setStyle: setStyle, 2473 setStyles: setStyles, 2474 capitalize: capitalize, 2475 isString: isString, 2476 isFunction: isFunction, 2477 isObject: isObject, 2478 forEachObject: forEachObject, 2479 floatEquals: floatEquals, 2480 removeChildren: removeChildren 2481}; 2482 2483},{}]},{},[4])(4) 2484});
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.