|
1 | | -/*! nouislider - 14.4.0 - 5/6/2020 */ |
| 1 | +/*! nouislider - 14.5.0 - 5/11/2020 */ |
2 | 2 | (function(factory) { |
3 | 3 | if (typeof define === "function" && define.amd) { |
4 | 4 | // AMD. Register as an anonymous module. |
|
13 | 13 | })(function() { |
14 | 14 | "use strict"; |
15 | 15 |
|
16 | | - var VERSION = "14.4.0"; |
| 16 | + var VERSION = "14.5.0"; |
17 | 17 |
|
18 | 18 | //region Helper Methods |
19 | 19 |
|
|
206 | 206 | } |
207 | 207 |
|
208 | 208 | // (percentage) How many percent is this value of this range? |
209 | | - function fromPercentage(range, value) { |
210 | | - return (value * 100) / (range[1] - range[0]); |
| 209 | + function fromPercentage(range, value, startRange) { |
| 210 | + return (value * 100) / (range[startRange + 1] - range[startRange]); |
211 | 211 | } |
212 | 212 |
|
213 | 213 | // (percentage) Where is this value on this range? |
214 | 214 | function toPercentage(range, value) { |
215 | | - return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0]); |
| 215 | + return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0], 0); |
216 | 216 | } |
217 | 217 |
|
218 | 218 | // (value) How much is this percentage on this range? |
|
348 | 348 |
|
349 | 349 | // Factor to range ratio |
350 | 350 | that.xSteps[i] = |
351 | | - fromPercentage([that.xVal[i], that.xVal[i + 1]], n) / subRangeRatio(that.xPct[i], that.xPct[i + 1]); |
| 351 | + fromPercentage([that.xVal[i], that.xVal[i + 1]], n, 0) / subRangeRatio(that.xPct[i], that.xPct[i + 1]); |
352 | 352 |
|
353 | 353 | var totalSteps = (that.xVal[i + 1] - that.xVal[i]) / that.xNumSteps[i]; |
354 | 354 | var highestStep = Math.ceil(Number(totalSteps.toFixed(3)) - 1); |
|
406 | 406 | } |
407 | 407 | } |
408 | 408 |
|
409 | | - Spectrum.prototype.getMargin = function(value) { |
410 | | - var step = this.xNumSteps[0]; |
| 409 | + Spectrum.prototype.getDistance = function(value) { |
| 410 | + var index; |
| 411 | + var distances = []; |
| 412 | + |
| 413 | + for (index = 0; index < this.xNumSteps.length - 1; index++) { |
| 414 | + // last "range" can't contain step size as it is purely an endpoint. |
| 415 | + var step = this.xNumSteps[index]; |
| 416 | + |
| 417 | + if (step && (value / step) % 1 !== 0) { |
| 418 | + throw new Error( |
| 419 | + "noUiSlider (" + |
| 420 | + VERSION + |
| 421 | + "): 'limit', 'margin' and 'padding' of " + |
| 422 | + this.xPct[index] + |
| 423 | + "% range must be divisible by step." |
| 424 | + ); |
| 425 | + } |
| 426 | + |
| 427 | + // Calculate percentual distance in current range of limit, margin or padding |
| 428 | + distances[index] = fromPercentage(this.xVal, value, index); |
| 429 | + } |
| 430 | + |
| 431 | + return distances; |
| 432 | + }; |
| 433 | + |
| 434 | + // Calculate the percentual distance over the whole scale of ranges. |
| 435 | + // direction: 0 = backwards / 1 = forwards |
| 436 | + Spectrum.prototype.getAbsoluteDistance = function(value, distances, direction) { |
| 437 | + var xPct_index = 0; |
| 438 | + |
| 439 | + // Calculate range where to start calculation |
| 440 | + if (value < this.xPct[this.xPct.length - 1]) { |
| 441 | + while (value > this.xPct[xPct_index + 1]) { |
| 442 | + xPct_index++; |
| 443 | + } |
| 444 | + } else if (value === this.xPct[this.xPct.length - 1]) { |
| 445 | + xPct_index = this.xPct.length - 2; |
| 446 | + } |
| 447 | + |
| 448 | + // If looking backwards and the value is exactly at a range separator then look one range further |
| 449 | + if (!direction && value === this.xPct[xPct_index + 1]) { |
| 450 | + xPct_index++; |
| 451 | + } |
| 452 | + |
| 453 | + var start_factor; |
| 454 | + var rest_factor = 1; |
| 455 | + |
| 456 | + var rest_rel_distance = distances[xPct_index]; |
| 457 | + |
| 458 | + var range_pct = 0; |
411 | 459 |
|
412 | | - if (step && (value / step) % 1 !== 0) { |
413 | | - throw new Error("noUiSlider (" + VERSION + "): 'limit', 'margin' and 'padding' must be divisible by step."); |
| 460 | + var rel_range_distance = 0; |
| 461 | + var abs_distance_counter = 0; |
| 462 | + var range_counter = 0; |
| 463 | + |
| 464 | + // Calculate what part of the start range the value is |
| 465 | + if (direction) { |
| 466 | + start_factor = (value - this.xPct[xPct_index]) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]); |
| 467 | + } else { |
| 468 | + start_factor = (this.xPct[xPct_index + 1] - value) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]); |
| 469 | + } |
| 470 | + |
| 471 | + // Do until the complete distance across ranges is calculated |
| 472 | + while (rest_rel_distance > 0) { |
| 473 | + // Calculate the percentage of total range |
| 474 | + range_pct = this.xPct[xPct_index + 1 + range_counter] - this.xPct[xPct_index + range_counter]; |
| 475 | + |
| 476 | + // Detect if the margin, padding or limit is larger then the current range and calculate |
| 477 | + if (distances[xPct_index + range_counter] * rest_factor + 100 - start_factor * 100 > 100) { |
| 478 | + // If larger then take the percentual distance of the whole range |
| 479 | + rel_range_distance = range_pct * start_factor; |
| 480 | + // Rest factor of relative percentual distance still to be calculated |
| 481 | + rest_factor = (rest_rel_distance - 100 * start_factor) / distances[xPct_index + range_counter]; |
| 482 | + // Set start factor to 1 as for next range it does not apply. |
| 483 | + start_factor = 1; |
| 484 | + } else { |
| 485 | + // If smaller or equal then take the percentual distance of the calculate percentual part of that range |
| 486 | + rel_range_distance = ((distances[xPct_index + range_counter] * range_pct) / 100) * rest_factor; |
| 487 | + // No rest left as the rest fits in current range |
| 488 | + rest_factor = 0; |
| 489 | + } |
| 490 | + |
| 491 | + if (direction) { |
| 492 | + abs_distance_counter = abs_distance_counter - rel_range_distance; |
| 493 | + // Limit range to first range when distance becomes outside of minimum range |
| 494 | + if (this.xPct.length + range_counter >= 1) { |
| 495 | + range_counter--; |
| 496 | + } |
| 497 | + } else { |
| 498 | + abs_distance_counter = abs_distance_counter + rel_range_distance; |
| 499 | + // Limit range to last range when distance becomes outside of maximum range |
| 500 | + if (this.xPct.length - range_counter >= 1) { |
| 501 | + range_counter++; |
| 502 | + } |
| 503 | + } |
| 504 | + |
| 505 | + // Rest of relative percentual distance still to be calculated |
| 506 | + rest_rel_distance = distances[xPct_index + range_counter] * rest_factor; |
414 | 507 | } |
415 | 508 |
|
416 | | - return this.xPct.length === 2 ? fromPercentage(this.xVal, value) : false; |
| 509 | + return value + abs_distance_counter; |
417 | 510 | }; |
418 | 511 |
|
419 | 512 | Spectrum.prototype.toStepping = function(value) { |
|
678 | 771 | return; |
679 | 772 | } |
680 | 773 |
|
681 | | - parsed.margin = parsed.spectrum.getMargin(entry); |
682 | | - |
683 | | - if (!parsed.margin) { |
684 | | - throw new Error("noUiSlider (" + VERSION + "): 'margin' option is only supported on linear sliders."); |
685 | | - } |
| 774 | + parsed.margin = parsed.spectrum.getDistance(entry); |
686 | 775 | } |
687 | 776 |
|
688 | 777 | function testLimit(parsed, entry) { |
689 | 778 | if (!isNumeric(entry)) { |
690 | 779 | throw new Error("noUiSlider (" + VERSION + "): 'limit' option must be numeric."); |
691 | 780 | } |
692 | 781 |
|
693 | | - parsed.limit = parsed.spectrum.getMargin(entry); |
| 782 | + parsed.limit = parsed.spectrum.getDistance(entry); |
694 | 783 |
|
695 | 784 | if (!parsed.limit || parsed.handles < 2) { |
696 | 785 | throw new Error( |
|
702 | 791 | } |
703 | 792 |
|
704 | 793 | function testPadding(parsed, entry) { |
| 794 | + var index; |
| 795 | + |
705 | 796 | if (!isNumeric(entry) && !Array.isArray(entry)) { |
706 | 797 | throw new Error( |
707 | 798 | "noUiSlider (" + VERSION + "): 'padding' option must be numeric or array of exactly 2 numbers." |
|
722 | 813 | entry = [entry, entry]; |
723 | 814 | } |
724 | 815 |
|
725 | | - // 'getMargin' returns false for invalid values. |
726 | | - parsed.padding = [parsed.spectrum.getMargin(entry[0]), parsed.spectrum.getMargin(entry[1])]; |
| 816 | + // 'getDistance' returns false for invalid values. |
| 817 | + parsed.padding = [parsed.spectrum.getDistance(entry[0]), parsed.spectrum.getDistance(entry[1])]; |
727 | 818 |
|
728 | | - if (parsed.padding[0] === false || parsed.padding[1] === false) { |
729 | | - throw new Error("noUiSlider (" + VERSION + "): 'padding' option is only supported on linear sliders."); |
| 819 | + for (index = 0; index < parsed.spectrum.xNumSteps.length - 1; index++) { |
| 820 | + // last "range" can't contain step size as it is purely an endpoint. |
| 821 | + if (parsed.padding[0][index] < 0 || parsed.padding[1][index] < 0) { |
| 822 | + throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be a positive number(s)."); |
| 823 | + } |
730 | 824 | } |
731 | 825 |
|
732 | | - if (parsed.padding[0] < 0 || parsed.padding[1] < 0) { |
733 | | - throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be a positive number(s)."); |
734 | | - } |
| 826 | + var totalPadding = entry[0] + entry[1]; |
| 827 | + var firstValue = parsed.spectrum.xVal[0]; |
| 828 | + var lastValue = parsed.spectrum.xVal[parsed.spectrum.xVal.length - 1]; |
735 | 829 |
|
736 | | - if (parsed.padding[0] + parsed.padding[1] > 100) { |
| 830 | + if (totalPadding / (lastValue - firstValue) > 1) { |
737 | 831 | throw new Error("noUiSlider (" + VERSION + "): 'padding' option must not exceed 100% of the range."); |
738 | 832 | } |
739 | 833 | } |
|
2008 | 2102 |
|
2009 | 2103 | // Split out the handle positioning logic so the Move event can use it, too |
2010 | 2104 | function checkHandlePosition(reference, handleNumber, to, lookBackward, lookForward, getValue) { |
| 2105 | + var distance; |
| 2106 | + |
2011 | 2107 | // For sliders with multiple handles, limit movement to the other handle. |
2012 | 2108 | // Apply the margin option by adding it to the handle positions. |
2013 | 2109 | if (scope_Handles.length > 1 && !options.events.unconstrained) { |
2014 | 2110 | if (lookBackward && handleNumber > 0) { |
2015 | | - to = Math.max(to, reference[handleNumber - 1] + options.margin); |
| 2111 | + distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.margin, 0); |
| 2112 | + to = Math.max(to, distance); |
2016 | 2113 | } |
2017 | 2114 |
|
2018 | 2115 | if (lookForward && handleNumber < scope_Handles.length - 1) { |
2019 | | - to = Math.min(to, reference[handleNumber + 1] - options.margin); |
| 2116 | + distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.margin, 1); |
| 2117 | + to = Math.min(to, distance); |
2020 | 2118 | } |
2021 | 2119 | } |
2022 | 2120 |
|
|
2025 | 2123 | // handles would be unmovable. |
2026 | 2124 | if (scope_Handles.length > 1 && options.limit) { |
2027 | 2125 | if (lookBackward && handleNumber > 0) { |
2028 | | - to = Math.min(to, reference[handleNumber - 1] + options.limit); |
| 2126 | + distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.limit, 0); |
| 2127 | + to = Math.min(to, distance); |
2029 | 2128 | } |
2030 | 2129 |
|
2031 | 2130 | if (lookForward && handleNumber < scope_Handles.length - 1) { |
2032 | | - to = Math.max(to, reference[handleNumber + 1] - options.limit); |
| 2131 | + distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.limit, 1); |
| 2132 | + to = Math.max(to, distance); |
2033 | 2133 | } |
2034 | 2134 | } |
2035 | 2135 |
|
2036 | 2136 | // The padding option keeps the handles a certain distance from the |
2037 | 2137 | // edges of the slider. Padding must be > 0. |
2038 | 2138 | if (options.padding) { |
2039 | 2139 | if (handleNumber === 0) { |
2040 | | - to = Math.max(to, options.padding[0]); |
| 2140 | + distance = scope_Spectrum.getAbsoluteDistance(0, options.padding[0], 0); |
| 2141 | + to = Math.max(to, distance); |
2041 | 2142 | } |
2042 | 2143 |
|
2043 | 2144 | if (handleNumber === scope_Handles.length - 1) { |
2044 | | - to = Math.min(to, 100 - options.padding[1]); |
| 2145 | + distance = scope_Spectrum.getAbsoluteDistance(100, options.padding[1], 1); |
| 2146 | + to = Math.min(to, distance); |
2045 | 2147 | } |
2046 | 2148 | } |
2047 | 2149 |
|
|
0 commit comments