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);