From c0bb9d4e5f392927bb6d264224a75bc40a7e8f7a Mon Sep 17 00:00:00 2001 From: Nima Niazi Date: Fri, 6 Sep 2024 22:17:31 -0400 Subject: [PATCH] Add logValue method for logarithmic scaling of range inputs - Implemented a method called logValue on p5.Element prototype for elements - Allows slider values to be mapped to a logarithmic scale between min and max - Ensures that values reach exactly min at the lowest and max at the highest positions - Useful for applications such as audio volume control, brightness, and other parameters requiring logarithmic scaling --- src/dom/dom.js | 57 ++++++++++++++++++++++++++++++++++++++++++++ test/unit/dom/dom.js | 6 +++++ 2 files changed, 63 insertions(+) diff --git a/src/dom/dom.js b/src/dom/dom.js index d35a53bc74..9c1e10f72e 100644 --- a/src/dom/dom.js +++ b/src/dom/dom.js @@ -1,3 +1,4 @@ + /** * The web is much more than just canvas and the DOM functionality makes it easy to interact * with other HTML5 objects, including text, hyperlink, image, input, video, @@ -3476,6 +3477,62 @@ p5.Element.prototype.value = function(...args) { } }; +/** + * Returns the logarithmic value of a range input element. + * + * This method is particularly useful for creating logarithmic sliders, + * where the perceived change in value is proportional to the relative + * change rather than the absolute change. + * + * If the element is not a range input, it returns the regular value. + * + * @method logValue + * @return {Number} The logarithmic value of the range input, or the regular value for non-range inputs. + * + * @example + *
+ * + * let slider; + * let logValue; + * + * function setup() { + * createCanvas(200, 100); + * slider = createSlider(0, 1, 0.5, 0.01); + * slider.position(10, 10); + * slider.style('width', '180px'); + * + * describe('A slider that shows both its linear and logarithmic values.'); + * } + * + * function draw() { + * background(220); + * + * let linearValue = slider.value(); + * logValue = slider.logValue(); + * + * text('Linear: ' + linearValue, 10, 50); + * text('Log: ' + logValue.toFixed(2), 10, 70); + * } + * + *
+ */ + +p5.Element.prototype.logValue = function () { + if (this.elt.type === 'range') { + const min = parseFloat(this.elt.min); + const max = parseFloat(this.elt.max); + + let linearValue = parseFloat(this.elt.value); + let normalizedValue = (linearValue - min) / (max - min); + let logarithmicValue = (Math.pow(10, normalizedValue * 2) - 1) / 99; + + return min + logarithmicValue * (max - min); + } else { + return this.elt.value; + } +}; + + /** * Shows the current element. * diff --git a/test/unit/dom/dom.js b/test/unit/dom/dom.js index 0ab5bb66dd..532ae37ee1 100644 --- a/test/unit/dom/dom.js +++ b/test/unit/dom/dom.js @@ -585,6 +585,12 @@ suite('DOM', function() { testElement = myp5.createSlider(20, 80, 10, 5); assert.deepEqual(testElement.elt.step, '5'); }); + + test('should return logaritmic value when logValue() is called', function() { + testElement = myp5.createSlider(1, 100, 1, 1); + testElement.elt.value = 10; + assert.equal(testElement.logValue(), 1.5199110829529336); + }); }); suite('p5.prototype.createButton', function() {