From: Maarten Brouwers Date: Tue, 1 Nov 2016 16:59:08 +0000 (+0100) Subject: Adds pow and log transforms to the Slider component X-Git-Tag: v6.3-rc1~2^2~4^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be69656e88597dc393ae28400d25f6e7ca8593d2;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Adds pow and log transforms to the Slider component Introduces two settings, `nonLinearBase` and `positionValueFunction` which change the way in which the position of the slider is translated to an actual value. Besides the default value of ‘linear' for `positionValueFunction`, 'pow' and a 'log' can be used. *Example application* In example below we want to focus on the most recent years, hence we use a logarithmic transformation of the slider:
Since I didn't get the test-framework to run I submitting this for now without tests, if it is absolutely necessary to do so, and this functionality is desired, allow me some time to fix that. --- diff --git a/js/foundation.slider.js b/js/foundation.slider.js index ee539009b..31a9835a0 100644 --- a/js/foundation.slider.js +++ b/js/foundation.slider.js @@ -95,6 +95,63 @@ class Slider { } } + /** + * @function + * @private + * @param {Number} value - floating point (the value) to be transformed using to a relative position on the slider (the inverse of _value) + */ + _pctOfBar(value) { + var pctOfBar = percent(value - this.options.start, this.options.end - this.options.start) + + switch(this.options.positionValueFunction) { + case "pow": + pctOfBar = this._logTransform(pctOfBar); + break; + case "log": + pctOfBar = this._powTransform(pctOfBar); + break; + } + + return pctOfBar.toFixed(2) + } + + /** + * @function + * @private + * @param {Number} pctOfBar - floating point, the relative position of the slider (typically between 0-1) to be transformed to a value + */ + _value(pctOfBar) { + switch(this.options.positionValueFunction) { + case "pow": + pctOfBar = this._powTransform(pctOfBar); + break; + case "log": + pctOfBar = this._logTransform(pctOfBar); + break; + } + var value = (this.options.end - this.options.start) * pctOfBar + this.options.start; + + return value + } + + /** + * @function + * @private + * @param {Number} value - floating point (typically between 0-1) to be transformed using the log function + */ + _logTransform(value) { + return baseLog(this.options.nonLinearBase, ((value*(this.options.nonLinearBase-1))+1)) + } + + /** + * @function + * @private + * @param {Number} value - floating point (typically between 0-1) to be transformed using the power function + */ + _powTransform(value) { + return (Math.pow(this.options.nonLinearBase, value) - 1) / (this.options.nonLinearBase - 1) + } + /** * Sets the position of the selected handle and fill bar. * @function @@ -142,7 +199,7 @@ class Slider { handleDim = $hndl[0].getBoundingClientRect()[hOrW], elemDim = this.$element[0].getBoundingClientRect()[hOrW], //percentage of bar min/max value based on click or drag point - pctOfBar = percent(location - this.options.start, this.options.end - this.options.start).toFixed(2), + pctOfBar = this._pctOfBar(location), //number of actual pixels to shift the handle, based on the percentage obtained above pxToMove = (elemDim - handleDim) * pctOfBar, //percentage of bar to shift the handle @@ -296,7 +353,7 @@ class Slider { } var offsetPct = percent(barXY, barDim); - value = (this.options.end - this.options.start) * offsetPct + this.options.start; + value = this._value(offsetPct); // turn everything around for RTL, yay math! if (Foundation.rtl() && !this.options.vertical) {value = this.options.end - value;} @@ -560,7 +617,19 @@ Slider.defaults = { * @option * @example 500 */ - changedDelay: 500 + changedDelay: 500, + /** + * Basevalue for non-linear sliders + * @option + * @example 5 + */ + nonLinearBase: 5, + /** + * Basevalue for non-linear sliders, possible values are: 'linear', 'pow' & 'log'. Pow and Log use the nonLinearBase setting. + * @option + * @example 'linear' + */ + positionValueFunction: 'linear', }; function percent(frac, num) { @@ -569,6 +638,9 @@ function percent(frac, num) { function absPosition($handle, dir, clickPos, param) { return Math.abs(($handle.position()[dir] + ($handle[param]() / 2)) - clickPos); } +function baseLog(base, value) { + return Math.log(value)/Math.log(base) +} // Window exports Foundation.plugin(Slider, 'Slider');