diff --git a/docs/parameterData.json b/docs/parameterData.json index bee74cb5d6..4f6e2f7413 100644 --- a/docs/parameterData.json +++ b/docs/parameterData.json @@ -243,7 +243,7 @@ [] ] }, - "mult": { + "multiply": { "overloads": [ [ "p5.Quat?" @@ -766,15 +766,6 @@ ] ] }, - "saveGif": { - "overloads": [ - [ - "String", - "Number", - "Object?" - ] - ] - }, "saveCanvas": { "overloads": [ [ @@ -788,6 +779,15 @@ ] ] }, + "saveGif": { + "overloads": [ + [ + "String", + "Number", + "Object?" + ] + ] + }, "resetMatrix": { "overloads": [ [] @@ -1050,29 +1050,6 @@ ] ] }, - "color": { - "overloads": [ - [ - "Number", - "Number?" - ], - [ - "Number", - "Number", - "Number", - "Number?" - ], - [ - "String" - ], - [ - "Number[]" - ], - [ - "p5.Color" - ] - ] - }, "atan": { "overloads": [ [ @@ -1153,6 +1130,29 @@ ] ] }, + "color": { + "overloads": [ + [ + "Number", + "Number?" + ], + [ + "Number", + "Number", + "Number", + "Number?" + ], + [ + "String" + ], + [ + "Number[]" + ], + [ + "p5.Color" + ] + ] + }, "createDiv": { "overloads": [ [ @@ -1356,13 +1356,6 @@ ] ] }, - "red": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "createSpan": { "overloads": [ [ @@ -1415,6 +1408,13 @@ [] ] }, + "red": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "cos": { "overloads": [ [ @@ -1535,13 +1535,6 @@ ] ] }, - "green": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "bezierVertex": { "overloads": [ [ @@ -1757,6 +1750,13 @@ ] ] }, + "green": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "windowResized": { "overloads": [ [ @@ -1814,13 +1814,6 @@ ] ] }, - "blue": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "createSlider": { "overloads": [ [ @@ -1931,13 +1924,6 @@ ] ] }, - "alpha": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "endShape": { "overloads": [ [ @@ -2018,6 +2004,13 @@ ] ] }, + "blue": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "updatePixels": { "overloads": [ [ @@ -2087,13 +2080,6 @@ ] ] }, - "hue": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "unhex": { "overloads": [ [ @@ -2179,6 +2165,13 @@ [] ] }, + "alpha": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "getURLPath": { "overloads": [ [] @@ -2369,18 +2362,18 @@ ] ] }, - "saturation": { + "model": { "overloads": [ [ - "p5.Color|Number[]|String" + "p5.Geometry", + "Number?" ] ] }, - "model": { + "hue": { "overloads": [ [ - "p5.Geometry", - "Number?" + "p5.Color|Number[]|String" ] ] }, @@ -2497,13 +2490,6 @@ ] ] }, - "brightness": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "translate": { "overloads": [ [ @@ -2850,6 +2836,13 @@ [] ] }, + "saturation": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "noLights": { "overloads": [ [] @@ -2862,13 +2855,6 @@ ] ] }, - "lightness": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "mouseReleased": { "overloads": [ [ @@ -2938,15 +2924,6 @@ ] ] }, - "lerpColor": { - "overloads": [ - [ - "p5.Color", - "p5.Color", - "Number" - ] - ] - }, "createAudio": { "overloads": [ [ @@ -2965,18 +2942,17 @@ ] ] }, - "paletteLerp": { + "sqrt": { "overloads": [ [ - "[p5.Color|String|Number|Number[], Number][]", "Number" ] ] }, - "sqrt": { + "brightness": { "overloads": [ [ - "Number" + "p5.Color|Number[]|String" ] ] }, @@ -3074,6 +3050,13 @@ [] ] }, + "lightness": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "doubleClicked": { "overloads": [ [ @@ -3151,6 +3134,20 @@ ] ] }, + "lerpColor": { + "overloads": [ + [ + "p5.Color", + "p5.Color", + "Number" + ], + [ + "p5.Color", + "p5.Color", + "Object" + ] + ] + }, "loadNormalShader": { "overloads": [ [ @@ -3165,6 +3162,14 @@ [] ] }, + "paletteLerp": { + "overloads": [ + [ + "[p5.Color|String|Number|Number[], Number][]", + "Number" + ] + ] + }, "baseNormalShader": { "overloads": [ [] diff --git a/src/color/creating_reading.js b/src/color/creating_reading.js index 39f16db09d..88c82cdf34 100644 --- a/src/color/creating_reading.js +++ b/src/color/creating_reading.js @@ -1683,7 +1683,7 @@ function creatingReading(p5, fn){ * interval [0, 1] will produce strange and unexpected colors. * * The way that colors are interpolated depends on the current - * colorMode(). + * colorMode() or on the passed `options` object. * * ```js example * function setup() { @@ -1722,6 +1722,63 @@ function creatingReading(p5, fn){ * } * ``` * + * Normally, colors are interpolated according to the current `colorMode()`. But you can override this by + * specifying a different color space to perform the interpolation in. Different color spaces will blend + * colors differently. + * + * ```js example + * function setup() { + * createCanvas(100, 100); + * + * background(200); + * + * // Create p5.Color objects to interpolate between. + * colorMode(HSL); + * let from = color(240, 100, 25); + * let to = color('white'); + * + * // Create intermediate colors + * let interA = lerpColor(from, to, 0.33); + * let interB = lerpColor(from, to, 0.66); + * + * let inter1 = lerpColor(from, to, { + * amount: 0.33, + * lerpMode: HSB // interpolate in the HSB color space + * }); + * let inter2 = lerpColor(from, to, { + * amount: 0.66, + * lerpMode: HSB + * }); + * + * // Draw the left rectangle. + * noStroke(); + * fill(from); + * rect(10, 20, 20, 60); + * + * // Draw the left-center rectangles. + * fill(interA); + * rect(30, 20, 20, 30); + * + * fill(inter1); + * rect(30, 50, 20, 30); + * + * // Draw the right-center rectangles. + * fill(interB); + * rect(50, 20, 20, 30); + * + * fill(inter2); + * rect(50, 50, 20, 30); + * + * // Draw the right rectangle. + * fill(to); + * rect(70, 20, 20, 60); + * + * describe( + * 'Two strips of four colors each. From left to right, the top strip begins with dark blue, followed by a lighter blue, a light blue and finally white. Meanwhile, the bottom strip begins with a dark blue, followed by purple, then pink and finally white.' + * ); + * } + * ``` + * * In p5.strands shader callbacks, `lerpColor()` interpolates between * `vec4` colors and returns a normalized `vec4` with RGBA components in * the 0–1 range. `colorMode()` has no effect inside shader callbacks. @@ -1757,9 +1814,33 @@ function creatingReading(p5, fn){ * @param {Number} amt number between 0 and 1. * @return {p5.Color} interpolated color. */ + /** + * @method lerpColor + * @param {p5.Color} c1 interpolate from this color. + * @param {p5.Color} c2 interpolate to this color. + * @param {Object} options interpolation options. + * @param {number} [options.amount] a number between 0 and 1. + * @param {RGB|HSB|HSL|RGBP3|HWB|LAB|LCH|OKLAB|OKLCH} [options.outputMode] the desired output color mode. + * @param {RGB|HSB|HSL|RGBP3|HWB|LAB|LCH|OKLAB|OKLCH} [options.lerpMode] the color mode (space) to perform the interpolation in. + * @return {p5.Color} interpolated color. + */ fn.lerpColor = function(c1, c2, amt) { + let outputMode = this._renderer.states.colorMode; + let lerpMode = outputMode; + + if (typeof amt === 'object') { + // Passing in options object + outputMode = amt.outputMode ?? outputMode; + lerpMode = amt.lerpMode ?? lerpMode; + amt = amt.amount; + } + // p5._validateParameters('lerpColor', arguments); - return c1.lerp(c2, amt, this._renderer.states.colorMode); + return c1.lerp(c2, { + amount: amt, + lerpMode, + outputMode + }); }; /** @@ -1818,4 +1899,4 @@ export default creatingReading; if(typeof p5 !== 'undefined'){ creatingReading(p5, p5.prototype); -} \ No newline at end of file +} diff --git a/src/color/p5.Color.js b/src/color/p5.Color.js index fb4b62a4f8..cc9dcb9fbb 100644 --- a/src/color/p5.Color.js +++ b/src/color/p5.Color.js @@ -302,26 +302,16 @@ class Color { } lerp(color, amt, mode){ - // Find the closest common ancestor color space - let spaceIndex = -1; - while( - ( - spaceIndex+1 < this._color.space.path.length || - spaceIndex+1 < color._color.space.path.length - ) && - this._color.space.path[spaceIndex+1] === - color._color.space.path[spaceIndex+1] - ){ - spaceIndex += 1; - } - - if (spaceIndex === -1) { - // This probably will not occur in practice - throw new Error('Cannot lerp colors. No common color space found'); + let lerpMode = mode; + if (typeof amt === 'object') { + // Passing in options object + mode = amt.outputMode; + lerpMode = amt.lerpMode; + amt = amt.amount; } const obj = range(this._color, color._color, { - space: this._color.space.path[spaceIndex].id + space: Color.colorMap[lerpMode] })(amt); return new Color(obj, mode || this.mode);