diff --git a/src/color/creating_reading.js b/src/color/creating_reading.js
index cda1d9bfcc..976aba3176 100644
--- a/src/color/creating_reading.js
+++ b/src/color/creating_reading.js
@@ -6,21 +6,91 @@
* @requires constants
*/
-import './p5.Color';
-import { range } from 'colorjs.io/fn';
+import { Color } from './p5.Color';
+
+export const RGB = 'rgb';
+export const RGBHDR = 'rgbhdr';
+export const HSB = 'hsb';
+export const HSL = 'hsl';
+export const HWB = 'hwb';
+
+export const LAB = 'lab';
+export const LCH = 'lch';
+
+export const OKLAB = 'oklab';
+export const OKLCH = 'oklch';
+
+export const RGBA = 'rgba';
function creatingReading(p5, fn){
+ fn.RGB = RGB;
+ fn.RGBHDR = RGBHDR;
+ fn.HSB = HSB;
+ fn.HSL = HSL;
+ fn.HWB = HWB;
+
+ fn.LAB = LAB;
+ fn.LCH = LCH;
+
+ fn.OKLAB = OKLAB;
+ fn.OKLCH = OKLCH;
+
+ fn.RGBA = RGBA;
+
+ // Add color states to renderer state machine
+ p5.Renderer.states.colorMode = RGB;
+ p5.Renderer.states.colorMaxes = {
+ [RGB]: [255, 255, 255, 255],
+ [RGBHDR]: [255, 255, 255, 255],
+ [HSB]: [360, 100, 100, 1],
+ [HSL]: [360, 100, 100, 1],
+ [HWB]: [360, 100, 100, 1],
+
+ [LAB]: [100, [-125, 125], [-125, 125], 1],
+ [LCH]: [100, 150, 360, 1],
+
+ [OKLAB]: [100, [-125, 125], [-125, 125], 1],
+ [OKLCH]: [100, 150, 360, 1],
+ clone: function(){
+ let ret = {};
+ for(const key in this){
+ if(typeof this[key] !== 'function'){
+ ret[key] = structuredClone(this[key]);
+ }else{
+ ret[key] = this[key];
+ }
+ }
+ return ret;
+ }
+ };
+
/**
- * Gets the alpha (transparency) value of a color.
+ * Creates a p5.Color object.
*
- * `alpha()` extracts the alpha value from a
- * p5.Color object, an array of color components, or
- * a CSS color string.
+ * By default, the parameters are interpreted as RGB values. Calling
+ * `color(255, 204, 0)` will return a bright yellow color. The way these
+ * parameters are interpreted may be changed with the
+ * colorMode() function.
*
- * @method alpha
- * @param {p5.Color|Number[]|String} color p5.Color object, array of
- * color components, or CSS color string.
- * @return {Number} the alpha value.
+ * The version of `color()` with one parameter interprets the value one of two
+ * ways. If the parameter is a number, it's interpreted as a grayscale value.
+ * If the parameter is a string, it's interpreted as a CSS color string.
+ *
+ * The version of `color()` with two parameters interprets the first one as a
+ * grayscale value. The second parameter sets the alpha (transparency) value.
+ *
+ * The version of `color()` with three parameters interprets them as RGB, HSB,
+ * or HSL colors, depending on the current `colorMode()`.
+ *
+ * The version of `color()` with four parameters interprets them as RGBA, HSBA,
+ * or HSLA colors, depending on the current `colorMode()`. The last parameter
+ * sets the alpha (transparency) value.
+ *
+ * @method color
+ * @param {Number} gray number specifying value between white and black.
+ * @param {Number} [alpha] alpha value relative to current color range
+ * (default is 0-255).
+ * @return {p5.Color} resulting color.
*
* @example
*
@@ -30,22 +100,15 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object.
- * let c = color(0, 126, 255, 102);
+ * // Create a p5.Color object using RGB values.
+ * let c = color(255, 204, 0);
*
- * // Draw the left rectangle.
- * noStroke();
+ * // Draw the square.
* fill(c);
- * rect(15, 15, 35, 70);
- *
- * // Set 'alphaValue' to 102.
- * let alphaValue = alpha(c);
- *
- * // Draw the right rectangle.
- * fill(alphaValue);
- * rect(50, 15, 35, 70);
+ * noStroke();
+ * square(30, 20, 55);
*
- * describe('Two rectangles. The left one is light blue and the right one is charcoal gray.');
+ * describe('A yellow square on a gray canvas.');
* }
*
*
@@ -58,22 +121,24 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a color array.
- * let c = [0, 126, 255, 102];
+ * // Create a p5.Color object using RGB values.
+ * let c1 = color(255, 204, 0);
*
- * // Draw the left rectangle.
+ * // Draw the left circle.
+ * fill(c1);
* noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
+ * circle(25, 25, 80);
*
- * // Set 'alphaValue' to 102.
- * let alphaValue = alpha(c);
+ * // Create a p5.Color object using a grayscale value.
+ * let c2 = color(65);
*
- * // Draw the left rectangle.
- * fill(alphaValue);
- * rect(50, 15, 35, 70);
+ * // Draw the right circle.
+ * fill(c2);
+ * circle(75, 75, 80);
*
- * describe('Two rectangles. The left one is light blue and the right one is charcoal gray.');
+ * describe(
+ * 'Two circles on a gray canvas. The circle in the top-left corner is yellow and the one at the bottom-right is gray.'
+ * );
* }
*
*
@@ -86,46 +151,46 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a CSS color string.
- * let c = 'rgba(0, 126, 255, 0.4)';
+ * // Create a p5.Color object using a named color.
+ * let c = color('magenta');
+ *
+ * // Draw the square.
+ * fill(c);
+ * noStroke();
+ * square(20, 20, 60);
+ *
+ * describe('A magenta square on a gray canvas.');
+ * }
+ *
+ *
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a p5.Color object using a hex color code.
+ * let c1 = color('#0f0');
*
* // Draw the left rectangle.
+ * fill(c1);
* noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
+ * rect(0, 10, 45, 80);
*
- * // Set 'alphaValue' to 102.
- * let alphaValue = alpha(c);
+ * // Create a p5.Color object using a hex color code.
+ * let c2 = color('#00ff00');
*
* // Draw the right rectangle.
- * fill(alphaValue);
- * rect(50, 15, 35, 70);
+ * fill(c2);
+ * rect(55, 10, 45, 80);
*
- * describe('Two rectangles. The left one is light blue and the right one is charcoal gray.');
+ * describe('Two bright green rectangles on a gray canvas.');
* }
*
*
- */
- fn.alpha = function(c) {
- p5._validateParameters('alpha', arguments);
- return this.color(c)._getAlpha();
- };
-
- /**
- * Gets the blue value of a color.
- *
- * `blue()` extracts the blue value from a
- * p5.Color object, an array of color components, or
- * a CSS color string.
- *
- * By default, `blue()` returns a color's blue value in the range 0
- * to 255. If the colorMode() is set to RGB, it
- * returns the blue value in the given range.
- *
- * @method blue
- * @param {p5.Color|Number[]|String} color p5.Color object, array of
- * color components, or CSS color string.
- * @return {Number} the blue value.
*
* @example
*
@@ -135,22 +200,35 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using RGB values.
- * let c = color(175, 100, 220);
+ * // Create a p5.Color object using a RGB color string.
+ * let c1 = color('rgb(0, 0, 255)');
*
- * // Draw the left rectangle.
- * noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
+ * // Draw the top-left square.
+ * fill(c1);
+ * square(10, 10, 35);
*
- * // Set 'blueValue' to 220.
- * let blueValue = blue(c);
+ * // Create a p5.Color object using a RGB color string.
+ * let c2 = color('rgb(0%, 0%, 100%)');
*
- * // Draw the right rectangle.
- * fill(0, 0, blueValue);
- * rect(50, 15, 35, 70);
+ * // Draw the top-right square.
+ * fill(c2);
+ * square(55, 10, 35);
*
- * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
+ * // Create a p5.Color object using a RGBA color string.
+ * let c3 = color('rgba(0, 0, 255, 1)');
+ *
+ * // Draw the bottom-left square.
+ * fill(c3);
+ * square(10, 55, 35);
+ *
+ * // Create a p5.Color object using a RGBA color string.
+ * let c4 = color('rgba(0%, 0%, 100%, 1)');
+ *
+ * // Draw the bottom-right square.
+ * fill(c4);
+ * square(55, 55, 35);
+ *
+ * describe('Four blue squares in the corners of a gray canvas.');
* }
*
*
@@ -163,27 +241,26 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a color array.
- * let c = [175, 100, 220];
+ * // Create a p5.Color object using a HSL color string.
+ * let c1 = color('hsl(160, 100%, 50%)');
*
* // Draw the left rectangle.
* noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
+ * fill(c1);
+ * rect(0, 10, 45, 80);
*
- * // Set 'blueValue' to 220.
- * let blueValue = blue(c);
+ * // Create a p5.Color object using a HSLA color string.
+ * let c2 = color('hsla(160, 100%, 50%, 0.5)');
*
* // Draw the right rectangle.
- * fill(0, 0, blueValue);
- * rect(50, 15, 35, 70);
+ * fill(c2);
+ * rect(55, 10, 45, 80);
*
- * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
+ * describe('Two sea green rectangles. A darker rectangle on the left and a brighter one on the right.');
* }
*
*
*
- * @example
*
*
* function setup() {
@@ -191,27 +268,26 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a CSS color string.
- * let c = 'rgb(175, 100, 220)';
+ * // Create a p5.Color object using a HSB color string.
+ * let c1 = color('hsb(160, 100%, 50%)');
*
* // Draw the left rectangle.
* noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
+ * fill(c1);
+ * rect(0, 10, 45, 80);
*
- * // Set 'blueValue' to 220.
- * let blueValue = blue(c);
+ * // Create a p5.Color object using a HSBA color string.
+ * let c2 = color('hsba(160, 100%, 50%, 0.5)');
*
* // Draw the right rectangle.
- * fill(0, 0, blueValue);
- * rect(50, 15, 35, 70);
+ * fill(c2);
+ * rect(55, 10, 45, 80);
*
- * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
+ * describe('Two green rectangles. A darker rectangle on the left and a brighter one on the right.');
* }
*
*
*
- * @example
*
*
* function setup() {
@@ -219,49 +295,89 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Use RGB color with values in the range 0-100.
- * colorMode(RGB, 100);
- *
* // Create a p5.Color object using RGB values.
- * let c = color(69, 39, 86);
+ * let c1 = color(50, 55, 100);
*
* // Draw the left rectangle.
- * noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
+ * fill(c1);
+ * rect(0, 10, 45, 80);
*
- * // Set 'blueValue' to 86.
- * let blueValue = blue(c);
+ * // Switch the color mode to HSB.
+ * colorMode(HSB, 100);
+ *
+ * // Create a p5.Color object using HSB values.
+ * let c2 = color(50, 55, 100);
*
* // Draw the right rectangle.
- * fill(0, 0, blueValue);
- * rect(50, 15, 35, 70);
+ * fill(c2);
+ * rect(55, 10, 45, 80);
*
- * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
+ * describe('Two blue rectangles. A darker rectangle on the left and a brighter one on the right.');
* }
*
*
*/
- fn.blue = function(c) {
- p5._validateParameters('blue', arguments);
- return this.color(c)._getBlue();
+
+ /**
+ * @method color
+ * @param {Number} v1 red or hue value relative to
+ * the current color range.
+ * @param {Number} v2 green or saturation value
+ * relative to the current color range.
+ * @param {Number} v3 blue or brightness value
+ * relative to the current color range.
+ * @param {Number} [alpha]
+ * @return {p5.Color}
+ */
+
+ /**
+ * @method color
+ * @param {String} value a color string.
+ * @return {p5.Color}
+ */
+
+ /**
+ * @method color
+ * @param {Number[]} values an array containing the red, green, blue,
+ * and alpha components of the color.
+ * @return {p5.Color}
+ */
+
+ /**
+ * @method color
+ * @param {p5.Color} color
+ * @return {p5.Color}
+ */
+ fn.color = function(...args) {
+ p5._validateParameters('color', args);
+ if (args[0] instanceof Color) {
+ // TODO: perhaps change color mode to match instance mode?
+ return args[0]; // Do nothing if argument is already a color object.
+ }
+
+ const arg = Array.isArray(args[0]) ? args[0] : args;
+ return new Color(
+ arg,
+ this._renderer.states.colorMode,
+ this._renderer.states.colorMaxes[this._renderer.states.colorMode]
+ );
};
/**
- * Gets the brightness value of a color.
+ * Gets the red value of a color.
*
- * `brightness()` extracts the HSB brightness value from a
+ * `red()` extracts the red value from a
* p5.Color object, an array of color components, or
* a CSS color string.
*
- * By default, `brightness()` returns a color's HSB brightness in the range 0
- * to 100. If the colorMode() is set to HSB, it
- * returns the brightness value in the given range.
+ * By default, `red()` returns a color's red value in the range 0
+ * to 255. If the colorMode() is set to RGB, it
+ * returns the red value in the given range.
*
- * @method brightness
+ * @method red
* @param {p5.Color|Number[]|String} color p5.Color object, array of
* color components, or CSS color string.
- * @return {Number} the brightness value.
+ * @return {Number} the red value.
*
* @example
*
@@ -271,25 +387,22 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Use HSB color.
- * colorMode(HSB);
- *
* // Create a p5.Color object.
- * let c = color(0, 50, 100);
+ * let c = color(175, 100, 220);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'brightValue' to 100.
- * let brightValue = brightness(c);
+ * // Set 'redValue' to 175.
+ * let redValue = red(c);
*
* // Draw the right rectangle.
- * fill(brightValue);
+ * fill(redValue, 0, 0);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is white.');
+ * describe('Two rectangles. The left one is light purple and the right one is red.');
* }
*
*
@@ -302,25 +415,22 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Use HSB color.
- * colorMode(HSB);
- *
* // Create a color array.
- * let c = [0, 50, 100];
+ * let c = [175, 100, 220];
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'brightValue' to 100.
- * let brightValue = brightness(c);
+ * // Set 'redValue' to 175.
+ * let redValue = red(c);
*
* // Draw the right rectangle.
- * fill(brightValue);
+ * fill(redValue, 0, 0);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is white.');
+ * describe('Two rectangles. The left one is light purple and the right one is red.');
* }
*
*
@@ -333,25 +443,22 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Use HSB color.
- * colorMode(HSB);
- *
* // Create a CSS color string.
- * let c = 'rgb(255, 128, 128)';
+ * let c = 'rgb(175, 100, 220)';
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'brightValue' to 100.
- * let brightValue = brightness(c);
+ * // Set 'redValue' to 175.
+ * let redValue = red(c);
*
* // Draw the right rectangle.
- * fill(brightValue);
+ * fill(redValue, 0, 0);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is white.');
+ * describe('Two rectangles. The left one is light purple and the right one is red.');
* }
*
*
@@ -364,61 +471,50 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Use HSB color with values in the range 0-255.
- * colorMode(HSB, 255);
+ * // Use RGB color with values in the range 0-100.
+ * colorMode(RGB, 100);
*
* // Create a p5.Color object.
- * let c = color(0, 127, 255);
+ * let c = color(69, 39, 86);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'brightValue' to 255.
- * let brightValue = brightness(c);
+ * // Set 'redValue' to 69.
+ * let redValue = red(c);
*
* // Draw the right rectangle.
- * fill(brightValue);
+ * fill(redValue, 0, 0);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is white.');
+ * describe('Two rectangles. The left one is light purple and the right one is red.');
* }
*
*
*/
- fn.brightness = function(c) {
- p5._validateParameters('brightness', arguments);
- return this.color(c)._getBrightness();
+ fn.red = function(c) {
+ p5._validateParameters('red', arguments);
+ // Get current red max
+ return this.color(c)._getRed();
};
/**
- * Creates a p5.Color object.
- *
- * By default, the parameters are interpreted as RGB values. Calling
- * `color(255, 204, 0)` will return a bright yellow color. The way these
- * parameters are interpreted may be changed with the
- * colorMode() function.
- *
- * The version of `color()` with one parameter interprets the value one of two
- * ways. If the parameter is a number, it's interpreted as a grayscale value.
- * If the parameter is a string, it's interpreted as a CSS color string.
- *
- * The version of `color()` with two parameters interprets the first one as a
- * grayscale value. The second parameter sets the alpha (transparency) value.
+ * Gets the green value of a color.
*
- * The version of `color()` with three parameters interprets them as RGB, HSB,
- * or HSL colors, depending on the current `colorMode()`.
+ * `green()` extracts the green value from a
+ * p5.Color object, an array of color components, or
+ * a CSS color string.
*
- * The version of `color()` with four parameters interprets them as RGBA, HSBA,
- * or HSLA colors, depending on the current `colorMode()`. The last parameter
- * sets the alpha (transparency) value.
+ * By default, `green()` returns a color's green value in the range 0
+ * to 255. If the colorMode() is set to RGB, it
+ * returns the green value in the given range.
*
- * @method color
- * @param {Number} gray number specifying value between white and black.
- * @param {Number} [alpha] alpha value relative to current color range
- * (default is 0-255).
- * @return {p5.Color} resulting color.
+ * @method green
+ * @param {p5.Color|Number[]|String} color p5.Color object, array of
+ * color components, or CSS color string.
+ * @return {Number} the green value.
*
* @example
*
@@ -428,15 +524,22 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using RGB values.
- * let c = color(255, 204, 0);
+ * // Create a p5.Color object.
+ * let c = color(175, 100, 220);
*
- * // Draw the square.
- * fill(c);
+ * // Draw the left rectangle.
* noStroke();
- * square(30, 20, 55);
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * describe('A yellow square on a gray canvas.');
+ * // Set 'greenValue' to 100.
+ * let greenValue = green(c);
+ *
+ * // Draw the right rectangle.
+ * fill(0, greenValue, 0);
+ * rect(50, 15, 35, 70);
+ *
+ * describe('Two rectangles. The left one is light purple and the right one is dark green.');
* }
*
*
@@ -449,24 +552,22 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using RGB values.
- * let c1 = color(255, 204, 0);
+ * // Create a color array.
+ * let c = [175, 100, 220];
*
- * // Draw the left circle.
- * fill(c1);
+ * // Draw the left rectangle.
* noStroke();
- * circle(25, 25, 80);
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * // Create a p5.Color object using a grayscale value.
- * let c2 = color(65);
+ * // Set 'greenValue' to 100.
+ * let greenValue = green(c);
*
- * // Draw the right circle.
- * fill(c2);
- * circle(75, 75, 80);
+ * // Draw the right rectangle.
+ * fill(0, greenValue, 0);
+ * rect(50, 15, 35, 70);
*
- * describe(
- * 'Two circles on a gray canvas. The circle in the top-left corner is yellow and the one at the bottom-right is gray.'
- * );
+ * describe('Two rectangles. The left one is light purple and the right one is dark green.');
* }
*
*
@@ -479,15 +580,22 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using a named color.
- * let c = color('magenta');
+ * // Create a CSS color string.
+ * let c = 'rgb(175, 100, 220)';
*
- * // Draw the square.
- * fill(c);
+ * // Draw the left rectangle.
* noStroke();
- * square(20, 20, 60);
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * describe('A magenta square on a gray canvas.');
+ * // Set 'greenValue' to 100.
+ * let greenValue = green(c);
+ *
+ * // Draw the right rectangle.
+ * fill(0, greenValue, 0);
+ * rect(50, 15, 35, 70);
+ *
+ * describe('Two rectangles. The left one is light purple and the right one is dark green.');
* }
*
*
@@ -500,25 +608,50 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using a hex color code.
- * let c1 = color('#0f0');
+ * // Use RGB color with values in the range 0-100.
+ * colorMode(RGB, 100);
+ *
+ * // Create a p5.Color object using RGB values.
+ * let c = color(69, 39, 86);
*
* // Draw the left rectangle.
- * fill(c1);
* noStroke();
- * rect(0, 10, 45, 80);
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * // Create a p5.Color object using a hex color code.
- * let c2 = color('#00ff00');
+ * // Set 'greenValue' to 39.
+ * let greenValue = green(c);
*
* // Draw the right rectangle.
- * fill(c2);
- * rect(55, 10, 45, 80);
+ * fill(0, greenValue, 0);
+ * rect(50, 15, 35, 70);
*
- * describe('Two bright green rectangles on a gray canvas.');
+ * describe('Two rectangles. The left one is light purple and the right one is dark green.');
* }
*
*
+ */
+ fn.green = function(c) {
+ p5._validateParameters('green', arguments);
+ // Get current green max
+ return this.color(c)._getGreen();
+ };
+
+ /**
+ * Gets the blue value of a color.
+ *
+ * `blue()` extracts the blue value from a
+ * p5.Color object, an array of color components, or
+ * a CSS color string.
+ *
+ * By default, `blue()` returns a color's blue value in the range 0
+ * to 255. If the colorMode() is set to RGB, it
+ * returns the blue value in the given range.
+ *
+ * @method blue
+ * @param {p5.Color|Number[]|String} color p5.Color object, array of
+ * color components, or CSS color string.
+ * @return {Number} the blue value.
*
* @example
*
@@ -528,35 +661,22 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using a RGB color string.
- * let c1 = color('rgb(0, 0, 255)');
- *
- * // Draw the top-left square.
- * fill(c1);
- * square(10, 10, 35);
- *
- * // Create a p5.Color object using a RGB color string.
- * let c2 = color('rgb(0%, 0%, 100%)');
- *
- * // Draw the top-right square.
- * fill(c2);
- * square(55, 10, 35);
- *
- * // Create a p5.Color object using a RGBA color string.
- * let c3 = color('rgba(0, 0, 255, 1)');
+ * // Create a p5.Color object using RGB values.
+ * let c = color(175, 100, 220);
*
- * // Draw the bottom-left square.
- * fill(c3);
- * square(10, 55, 35);
+ * // Draw the left rectangle.
+ * noStroke();
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * // Create a p5.Color object using a RGBA color string.
- * let c4 = color('rgba(0%, 0%, 100%, 1)');
+ * // Set 'blueValue' to 220.
+ * let blueValue = blue(c);
*
- * // Draw the bottom-right square.
- * fill(c4);
- * square(55, 55, 35);
+ * // Draw the right rectangle.
+ * fill(0, 0, blueValue);
+ * rect(50, 15, 35, 70);
*
- * describe('Four blue squares in the corners of a gray canvas.');
+ * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
* }
*
*
@@ -569,26 +689,27 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using a HSL color string.
- * let c1 = color('hsl(160, 100%, 50%)');
+ * // Create a color array.
+ * let c = [175, 100, 220];
*
* // Draw the left rectangle.
* noStroke();
- * fill(c1);
- * rect(0, 10, 45, 80);
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * // Create a p5.Color object using a HSLA color string.
- * let c2 = color('hsla(160, 100%, 50%, 0.5)');
+ * // Set 'blueValue' to 220.
+ * let blueValue = blue(c);
*
* // Draw the right rectangle.
- * fill(c2);
- * rect(55, 10, 45, 80);
+ * fill(0, 0, blueValue);
+ * rect(50, 15, 35, 70);
*
- * describe('Two sea green rectangles. A darker rectangle on the left and a brighter one on the right.');
+ * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
* }
*
*
*
+ * @example
*
*
* function setup() {
@@ -596,26 +717,27 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Create a p5.Color object using a HSB color string.
- * let c1 = color('hsb(160, 100%, 50%)');
+ * // Create a CSS color string.
+ * let c = 'rgb(175, 100, 220)';
*
* // Draw the left rectangle.
* noStroke();
- * fill(c1);
- * rect(0, 10, 45, 80);
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * // Create a p5.Color object using a HSBA color string.
- * let c2 = color('hsba(160, 100%, 50%, 0.5)');
+ * // Set 'blueValue' to 220.
+ * let blueValue = blue(c);
*
* // Draw the right rectangle.
- * fill(c2);
- * rect(55, 10, 45, 80);
+ * fill(0, 0, blueValue);
+ * rect(50, 15, 35, 70);
*
- * describe('Two green rectangles. A darker rectangle on the left and a brighter one on the right.');
+ * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
* }
*
*
*
+ * @example
*
*
* function setup() {
@@ -623,84 +745,46 @@ function creatingReading(p5, fn){
*
* background(200);
*
+ * // Use RGB color with values in the range 0-100.
+ * colorMode(RGB, 100);
+ *
* // Create a p5.Color object using RGB values.
- * let c1 = color(50, 55, 100);
+ * let c = color(69, 39, 86);
*
* // Draw the left rectangle.
- * fill(c1);
- * rect(0, 10, 45, 80);
- *
- * // Switch the color mode to HSB.
- * colorMode(HSB, 100);
+ * noStroke();
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * // Create a p5.Color object using HSB values.
- * let c2 = color(50, 55, 100);
+ * // Set 'blueValue' to 86.
+ * let blueValue = blue(c);
*
* // Draw the right rectangle.
- * fill(c2);
- * rect(55, 10, 45, 80);
+ * fill(0, 0, blueValue);
+ * rect(50, 15, 35, 70);
*
- * describe('Two blue rectangles. A darker rectangle on the left and a brighter one on the right.');
+ * describe('Two rectangles. The left one is light purple and the right one is royal blue.');
* }
*
*
*/
-
- /**
- * @method color
- * @param {Number} v1 red or hue value relative to
- * the current color range.
- * @param {Number} v2 green or saturation value
- * relative to the current color range.
- * @param {Number} v3 blue or brightness value
- * relative to the current color range.
- * @param {Number} [alpha]
- * @return {p5.Color}
- */
-
- /**
- * @method color
- * @param {String} value a color string.
- * @return {p5.Color}
- */
-
- /**
- * @method color
- * @param {Number[]} values an array containing the red, green, blue,
- * and alpha components of the color.
- * @return {p5.Color}
- */
-
- /**
- * @method color
- * @param {p5.Color} color
- * @return {p5.Color}
- */
- fn.color = function(...args) {
- p5._validateParameters('color', args);
- if (args[0] instanceof p5.Color) {
- return args[0]; // Do nothing if argument is already a color object.
- }
-
- const arg = Array.isArray(args[0]) ? args[0] : args;
- return new p5.Color(arg, this._colorMode, this._colorMaxes);
+ fn.blue = function(c) {
+ p5._validateParameters('blue', arguments);
+ // Get current blue max
+ return this.color(c)._getBlue();
};
/**
- * Gets the green value of a color.
+ * Gets the alpha (transparency) value of a color.
*
- * `green()` extracts the green value from a
+ * `alpha()` extracts the alpha value from a
* p5.Color object, an array of color components, or
* a CSS color string.
*
- * By default, `green()` returns a color's green value in the range 0
- * to 255. If the colorMode() is set to RGB, it
- * returns the green value in the given range.
- *
- * @method green
+ * @method alpha
* @param {p5.Color|Number[]|String} color p5.Color object, array of
* color components, or CSS color string.
- * @return {Number} the green value.
+ * @return {Number} the alpha value.
*
* @example
*
@@ -711,21 +795,21 @@ function creatingReading(p5, fn){
* background(200);
*
* // Create a p5.Color object.
- * let c = color(175, 100, 220);
+ * let c = color(0, 126, 255, 102);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'greenValue' to 100.
- * let greenValue = green(c);
+ * // Set 'alphaValue' to 102.
+ * let alphaValue = alpha(c);
*
* // Draw the right rectangle.
- * fill(0, greenValue, 0);
+ * fill(alphaValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is light purple and the right one is dark green.');
+ * describe('Two rectangles. The left one is light blue and the right one is charcoal gray.');
* }
*
*
@@ -739,49 +823,21 @@ function creatingReading(p5, fn){
* background(200);
*
* // Create a color array.
- * let c = [175, 100, 220];
+ * let c = [0, 126, 255, 102];
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'greenValue' to 100.
- * let greenValue = green(c);
- *
- * // Draw the right rectangle.
- * fill(0, greenValue, 0);
- * rect(50, 15, 35, 70);
- *
- * describe('Two rectangles. The left one is light purple and the right one is dark green.');
- * }
- *
- *
- *
- * @example
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Create a CSS color string.
- * let c = 'rgb(175, 100, 220)';
+ * // Set 'alphaValue' to 102.
+ * let alphaValue = alpha(c);
*
* // Draw the left rectangle.
- * noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
- *
- * // Set 'greenValue' to 100.
- * let greenValue = green(c);
- *
- * // Draw the right rectangle.
- * fill(0, greenValue, 0);
+ * fill(alphaValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is light purple and the right one is dark green.');
+ * describe('Two rectangles. The left one is light blue and the right one is charcoal gray.');
* }
*
*
@@ -794,32 +850,30 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Use RGB color with values in the range 0-100.
- * colorMode(RGB, 100);
- *
- * // Create a p5.Color object using RGB values.
- * let c = color(69, 39, 86);
+ * // Create a CSS color string.
+ * let c = 'rgba(0, 126, 255, 0.4)';
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'greenValue' to 39.
- * let greenValue = green(c);
+ * // Set 'alphaValue' to 102.
+ * let alphaValue = alpha(c);
*
* // Draw the right rectangle.
- * fill(0, greenValue, 0);
+ * fill(alphaValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is light purple and the right one is dark green.');
+ * describe('Two rectangles. The left one is light blue and the right one is charcoal gray.');
* }
*
*
*/
- fn.green = function(c) {
- p5._validateParameters('green', arguments);
- return this.color(c)._getGreen();
+ fn.alpha = function(c) {
+ p5._validateParameters('alpha', arguments);
+ // Get current alpha max
+ return this.color(c)._getAlpha();
};
/**
@@ -944,23 +998,21 @@ function creatingReading(p5, fn){
};
/**
- * Blends two colors to find a third color between them.
+ * Gets the saturation value of a color.
*
- * The `amt` parameter specifies the amount to interpolate between the two
- * values. 0 is equal to the first color, 0.1 is very near the first color,
- * 0.5 is halfway between the two colors, and so on. Negative numbers are set
- * to 0. Numbers greater than 1 are set to 1. This differs from the behavior of
- * lerp. It's necessary because numbers outside of the
- * interval [0, 1] will produce strange and unexpected colors.
+ * `saturation()` extracts the saturation value from a
+ * p5.Color object, an array of color components, or
+ * a CSS color string.
*
- * The way that colors are interpolated depends on the current
- * colorMode().
+ * Saturation is scaled differently in HSB and HSL. By default, `saturation()`
+ * returns a color's HSL saturation in the range 0 to 100. If the
+ * colorMode() is set to HSB or HSL, it returns the
+ * saturation value in the given mode.
*
- * @method lerpColor
- * @param {p5.Color} c1 interpolate from this color.
- * @param {p5.Color} c2 interpolate to this color.
- * @param {Number} amt number between 0 and 1.
- * @return {p5.Color} interpolated color.
+ * @method saturation
+ * @param {p5.Color|Number[]|String} color p5.Color object, array of
+ * color components, or CSS color string.
+ * @return {Number} the saturation value
*
* @example
*
@@ -968,83 +1020,30 @@ function creatingReading(p5, fn){
* function setup() {
* createCanvas(100, 100);
*
- * background(200);
+ * background(50);
*
- * // Create p5.Color objects to interpolate between.
- * let from = color(218, 165, 32);
- * let to = color(72, 61, 139);
+ * // Use HSB color.
+ * colorMode(HSB);
*
- * // Create intermediate colors.
- * let interA = lerpColor(from, to, 0.33);
- * let interB = lerpColor(from, to, 0.66);
+ * // Create a p5.Color object.
+ * let c = color(0, 50, 100);
*
* // Draw the left rectangle.
* noStroke();
- * fill(from);
- * rect(10, 20, 20, 60);
- *
- * // Draw the left-center rectangle.
- * fill(interA);
- * rect(30, 20, 20, 60);
+ * fill(c);
+ * rect(15, 15, 35, 70);
*
- * // Draw the right-center rectangle.
- * fill(interB);
- * rect(50, 20, 20, 60);
+ * // Set 'satValue' to 50.
+ * let satValue = saturation(c);
*
* // Draw the right rectangle.
- * fill(to);
- * rect(70, 20, 20, 60);
+ * fill(satValue);
+ * rect(50, 15, 35, 70);
*
- * describe(
- * 'Four rectangles. From left to right, the rectangles are tan, brown, brownish purple, and purple.'
- * );
+ * describe('Two rectangles. The left one is salmon pink and the right one is dark gray.');
* }
*
*
- */
- fn.lerpColor = function(c1, c2, amt) {
- p5._validateParameters('lerpColor', arguments);
-
- // Find the closest common ancestor color space
- let spaceIndex = -1;
- while(
- (
- spaceIndex+1 < c1.color.space.path.length ||
- spaceIndex+1 < c2.color.space.path.length
- ) &&
- c1.color.space.path[spaceIndex+1] === c2.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');
- }
-
- // Get lerp value as a color in the common ancestor color space
- const lerpColor = range(c1.color, c2.color, {
- space: c1.color.space.path[spaceIndex].id
- })(amt);
-
- return new p5.Color(lerpColor, this._colorMode, this._colorMaxes);
- };
-
- /**
- * Gets the lightness value of a color.
- *
- * `lightness()` extracts the HSL lightness value from a
- * p5.Color object, an array of color components, or
- * a CSS color string.
- *
- * By default, `lightness()` returns a color's HSL lightness in the range 0
- * to 100. If the colorMode() is set to HSL, it
- * returns the lightness value in the given range.
- *
- * @method lightness
- * @param {p5.Color|Number[]|String} color p5.Color object, array of
- * color components, or CSS color string.
- * @return {Number} the lightness value.
*
* @example
*
@@ -1054,22 +1053,22 @@ function creatingReading(p5, fn){
*
* background(50);
*
- * // Use HSL color.
- * colorMode(HSL);
+ * // Use HSB color.
+ * colorMode(HSB);
*
- * // Create a p5.Color object using HSL values.
- * let c = color(0, 100, 75);
+ * // Create a color array.
+ * let c = [0, 50, 100];
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'lightValue' to 75.
- * let lightValue = lightness(c);
+ * // Set 'satValue' to 100.
+ * let satValue = saturation(c);
*
* // Draw the right rectangle.
- * fill(lightValue);
+ * fill(satValue);
* rect(50, 15, 35, 70);
*
* describe('Two rectangles. The left one is salmon pink and the right one is gray.');
@@ -1085,22 +1084,22 @@ function creatingReading(p5, fn){
*
* background(50);
*
- * // Use HSL color.
- * colorMode(HSL);
+ * // Use HSB color.
+ * colorMode(HSB);
*
- * // Create a color array.
- * let c = [0, 100, 75];
+ * // Create a CSS color string.
+ * let c = 'rgb(255, 128, 128)';
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'lightValue' to 75.
- * let lightValue = lightness(c);
+ * // Set 'satValue' to 100.
+ * let satValue = saturation(c);
*
* // Draw the right rectangle.
- * fill(lightValue);
+ * fill(satValue);
* rect(50, 15, 35, 70);
*
* describe('Two rectangles. The left one is salmon pink and the right one is gray.');
@@ -1119,22 +1118,22 @@ function creatingReading(p5, fn){
* // Use HSL color.
* colorMode(HSL);
*
- * // Create a CSS color string.
- * let c = 'rgb(255, 128, 128)';
+ * // Create a p5.Color object.
+ * let c = color(0, 100, 75);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'lightValue' to 75.
- * let lightValue = lightness(c);
+ * // Set 'satValue' to 100.
+ * let satValue = saturation(c);
*
* // Draw the right rectangle.
- * fill(lightValue);
+ * fill(satValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is gray.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is white.');
* }
*
*
@@ -1150,7 +1149,7 @@ function creatingReading(p5, fn){
* // Use HSL color with values in the range 0-255.
* colorMode(HSL, 255);
*
- * // Create a p5.Color object using HSL values.
+ * // Create a p5.Color object.
* let c = color(0, 255, 191.5);
*
* // Draw the left rectangle.
@@ -1158,38 +1157,38 @@ function creatingReading(p5, fn){
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'lightValue' to 191.5.
- * let lightValue = lightness(c);
+ * // Set 'satValue' to 255.
+ * let satValue = saturation(c);
*
* // Draw the right rectangle.
- * fill(lightValue);
+ * fill(satValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is gray.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is white.');
* }
*
*
*/
- fn.lightness = function(c) {
- p5._validateParameters('lightness', arguments);
- return this.color(c)._getLightness();
+ fn.saturation = function(c) {
+ p5._validateParameters('saturation', arguments);
+ return this.color(c)._getSaturation();
};
/**
- * Gets the red value of a color.
+ * Gets the brightness value of a color.
*
- * `red()` extracts the red value from a
+ * `brightness()` extracts the HSB brightness value from a
* p5.Color object, an array of color components, or
* a CSS color string.
*
- * By default, `red()` returns a color's red value in the range 0
- * to 255. If the colorMode() is set to RGB, it
- * returns the red value in the given range.
+ * By default, `brightness()` returns a color's HSB brightness in the range 0
+ * to 100. If the colorMode() is set to HSB, it
+ * returns the brightness value in the given range.
*
- * @method red
+ * @method brightness
* @param {p5.Color|Number[]|String} color p5.Color object, array of
* color components, or CSS color string.
- * @return {Number} the red value.
+ * @return {Number} the brightness value.
*
* @example
*
@@ -1199,22 +1198,25 @@ function creatingReading(p5, fn){
*
* background(200);
*
+ * // Use HSB color.
+ * colorMode(HSB);
+ *
* // Create a p5.Color object.
- * let c = color(175, 100, 220);
+ * let c = color(0, 50, 100);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'redValue' to 175.
- * let redValue = red(c);
+ * // Set 'brightValue' to 100.
+ * let brightValue = brightness(c);
*
* // Draw the right rectangle.
- * fill(redValue, 0, 0);
+ * fill(brightValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is light purple and the right one is red.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is white.');
* }
*
*
@@ -1227,22 +1229,25 @@ function creatingReading(p5, fn){
*
* background(200);
*
+ * // Use HSB color.
+ * colorMode(HSB);
+ *
* // Create a color array.
- * let c = [175, 100, 220];
+ * let c = [0, 50, 100];
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'redValue' to 175.
- * let redValue = red(c);
+ * // Set 'brightValue' to 100.
+ * let brightValue = brightness(c);
*
* // Draw the right rectangle.
- * fill(redValue, 0, 0);
+ * fill(brightValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is light purple and the right one is red.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is white.');
* }
*
*
@@ -1255,22 +1260,25 @@ function creatingReading(p5, fn){
*
* background(200);
*
+ * // Use HSB color.
+ * colorMode(HSB);
+ *
* // Create a CSS color string.
- * let c = 'rgb(175, 100, 220)';
+ * let c = 'rgb(255, 128, 128)';
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'redValue' to 175.
- * let redValue = red(c);
+ * // Set 'brightValue' to 100.
+ * let brightValue = brightness(c);
*
* // Draw the right rectangle.
- * fill(redValue, 0, 0);
+ * fill(brightValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is light purple and the right one is red.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is white.');
* }
*
*
@@ -1283,50 +1291,49 @@ function creatingReading(p5, fn){
*
* background(200);
*
- * // Use RGB color with values in the range 0-100.
- * colorMode(RGB, 100);
+ * // Use HSB color with values in the range 0-255.
+ * colorMode(HSB, 255);
*
* // Create a p5.Color object.
- * let c = color(69, 39, 86);
+ * let c = color(0, 127, 255);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'redValue' to 69.
- * let redValue = red(c);
+ * // Set 'brightValue' to 255.
+ * let brightValue = brightness(c);
*
* // Draw the right rectangle.
- * fill(redValue, 0, 0);
+ * fill(brightValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is light purple and the right one is red.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is white.');
* }
*
*
*/
- fn.red = function(c) {
- p5._validateParameters('red', arguments);
- return this.color(c)._getRed();
+ fn.brightness = function(c) {
+ p5._validateParameters('brightness', arguments);
+ return this.color(c)._getBrightness();
};
/**
- * Gets the saturation value of a color.
+ * Gets the lightness value of a color.
*
- * `saturation()` extracts the saturation value from a
+ * `lightness()` extracts the HSL lightness value from a
* p5.Color object, an array of color components, or
* a CSS color string.
*
- * Saturation is scaled differently in HSB and HSL. By default, `saturation()`
- * returns a color's HSL saturation in the range 0 to 100. If the
- * colorMode() is set to HSB or HSL, it returns the
- * saturation value in the given mode.
+ * By default, `lightness()` returns a color's HSL lightness in the range 0
+ * to 100. If the colorMode() is set to HSL, it
+ * returns the lightness value in the given range.
*
- * @method saturation
+ * @method lightness
* @param {p5.Color|Number[]|String} color p5.Color object, array of
* color components, or CSS color string.
- * @return {Number} the saturation value
+ * @return {Number} the lightness value.
*
* @example
*
@@ -1336,25 +1343,25 @@ function creatingReading(p5, fn){
*
* background(50);
*
- * // Use HSB color.
- * colorMode(HSB);
+ * // Use HSL color.
+ * colorMode(HSL);
*
- * // Create a p5.Color object.
- * let c = color(0, 50, 100);
+ * // Create a p5.Color object using HSL values.
+ * let c = color(0, 100, 75);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'satValue' to 50.
- * let satValue = saturation(c);
+ * // Set 'lightValue' to 75.
+ * let lightValue = lightness(c);
*
* // Draw the right rectangle.
- * fill(satValue);
+ * fill(lightValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is dark gray.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is gray.');
* }
*
*
@@ -1367,22 +1374,22 @@ function creatingReading(p5, fn){
*
* background(50);
*
- * // Use HSB color.
- * colorMode(HSB);
+ * // Use HSL color.
+ * colorMode(HSL);
*
* // Create a color array.
- * let c = [0, 50, 100];
+ * let c = [0, 100, 75];
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'satValue' to 100.
- * let satValue = saturation(c);
+ * // Set 'lightValue' to 75.
+ * let lightValue = lightness(c);
*
* // Draw the right rectangle.
- * fill(satValue);
+ * fill(lightValue);
* rect(50, 15, 35, 70);
*
* describe('Two rectangles. The left one is salmon pink and the right one is gray.');
@@ -1398,8 +1405,8 @@ function creatingReading(p5, fn){
*
* background(50);
*
- * // Use HSB color.
- * colorMode(HSB);
+ * // Use HSL color.
+ * colorMode(HSL);
*
* // Create a CSS color string.
* let c = 'rgb(255, 128, 128)';
@@ -1409,11 +1416,11 @@ function creatingReading(p5, fn){
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'satValue' to 100.
- * let satValue = saturation(c);
+ * // Set 'lightValue' to 75.
+ * let lightValue = lightness(c);
*
* // Draw the right rectangle.
- * fill(satValue);
+ * fill(lightValue);
* rect(50, 15, 35, 70);
*
* describe('Two rectangles. The left one is salmon pink and the right one is gray.');
@@ -1429,28 +1436,52 @@ function creatingReading(p5, fn){
*
* background(50);
*
- * // Use HSL color.
- * colorMode(HSL);
+ * // Use HSL color with values in the range 0-255.
+ * colorMode(HSL, 255);
*
- * // Create a p5.Color object.
- * let c = color(0, 100, 75);
+ * // Create a p5.Color object using HSL values.
+ * let c = color(0, 255, 191.5);
*
* // Draw the left rectangle.
* noStroke();
* fill(c);
* rect(15, 15, 35, 70);
*
- * // Set 'satValue' to 100.
- * let satValue = saturation(c);
+ * // Set 'lightValue' to 191.5.
+ * let lightValue = lightness(c);
*
* // Draw the right rectangle.
- * fill(satValue);
+ * fill(lightValue);
* rect(50, 15, 35, 70);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is white.');
+ * describe('Two rectangles. The left one is salmon pink and the right one is gray.');
* }
*
*
+ */
+ fn.lightness = function(c) {
+ p5._validateParameters('lightness', arguments);
+ return this.color(c)._getLightness();
+ };
+
+ /**
+ * Blends two colors to find a third color between them.
+ *
+ * The `amt` parameter specifies the amount to interpolate between the two
+ * values. 0 is equal to the first color, 0.1 is very near the first color,
+ * 0.5 is halfway between the two colors, and so on. Negative numbers are set
+ * to 0. Numbers greater than 1 are set to 1. This differs from the behavior of
+ * lerp. It's necessary because numbers outside of the
+ * interval [0, 1] will produce strange and unexpected colors.
+ *
+ * The way that colors are interpolated depends on the current
+ * colorMode().
+ *
+ * @method lerpColor
+ * @param {p5.Color} c1 interpolate from this color.
+ * @param {p5.Color} c2 interpolate to this color.
+ * @param {Number} amt number between 0 and 1.
+ * @return {p5.Color} interpolated color.
*
* @example
*
@@ -1458,34 +1489,43 @@ function creatingReading(p5, fn){
* function setup() {
* createCanvas(100, 100);
*
- * background(50);
+ * background(200);
*
- * // Use HSL color with values in the range 0-255.
- * colorMode(HSL, 255);
+ * // Create p5.Color objects to interpolate between.
+ * let from = color(218, 165, 32);
+ * let to = color(72, 61, 139);
*
- * // Create a p5.Color object.
- * let c = color(0, 255, 191.5);
+ * // Create intermediate colors.
+ * let interA = lerpColor(from, to, 0.33);
+ * let interB = lerpColor(from, to, 0.66);
*
* // Draw the left rectangle.
* noStroke();
- * fill(c);
- * rect(15, 15, 35, 70);
+ * fill(from);
+ * rect(10, 20, 20, 60);
*
- * // Set 'satValue' to 255.
- * let satValue = saturation(c);
+ * // Draw the left-center rectangle.
+ * fill(interA);
+ * rect(30, 20, 20, 60);
+ *
+ * // Draw the right-center rectangle.
+ * fill(interB);
+ * rect(50, 20, 20, 60);
*
* // Draw the right rectangle.
- * fill(satValue);
- * rect(50, 15, 35, 70);
+ * fill(to);
+ * rect(70, 20, 20, 60);
*
- * describe('Two rectangles. The left one is salmon pink and the right one is white.');
+ * describe(
+ * 'Four rectangles. From left to right, the rectangles are tan, brown, brownish purple, and purple.'
+ * );
* }
*
*
*/
- fn.saturation = function(c) {
- p5._validateParameters('saturation', arguments);
- return this.color(c)._getSaturation();
+ fn.lerpColor = function(c1, c2, amt) {
+ p5._validateParameters('lerpColor', arguments);
+ return c1.lerp(c2, amt, this._renderer.states.colorMode);
};
}
diff --git a/src/color/p5.Color.culori.js b/src/color/p5.Color.culori.js
new file mode 100644
index 0000000000..0e184b13dc
--- /dev/null
+++ b/src/color/p5.Color.culori.js
@@ -0,0 +1,66 @@
+class Color {
+ _color;
+ maxes;
+ mode;
+ array;
+
+ static addColorMode(mode, definition){
+
+ }
+
+ constructor(vals){
+
+ }
+
+ toString(){
+
+ }
+
+ setRed(new_red){
+
+ }
+
+ setGreen(new_green){
+
+ }
+
+ setBlue(new_blue){
+
+ }
+
+ setAlpha(new_alpha){
+
+ }
+
+ _getRed(){
+
+ }
+
+ _getGreen(){
+
+ }
+
+ _getBlue(){
+
+ }
+
+ _getAlpha(){
+
+ }
+
+ _getHue(){
+
+ }
+
+ _getSaturation(){
+
+ }
+
+ _getBrightness(){
+
+ }
+
+ _getLightness(){
+
+ }
+}
diff --git a/src/color/p5.Color.js b/src/color/p5.Color.js
index 213821bf14..0df96a4abd 100644
--- a/src/color/p5.Color.js
+++ b/src/color/p5.Color.js
@@ -3,144 +3,198 @@
* @submodule Creating & Reading
* @for p5
* @requires core
- * @requires constants
* @requires color_conversion
*/
-import * as constants from '../core/constants';
+import { RGB, RGBHDR, HSL, HSB, HWB, LAB, LCH, OKLAB, OKLCH } from './creating_reading';
+
import {
ColorSpace,
to,
- // toGamut,
+ toGamut,
serialize,
parse,
- // range,
+ range,
- XYZ_D65,
- sRGB_Linear,
sRGB,
- HSL,
- HSV,
- HWB,
+ HSL as HSLSpace,
+ HWB as HWBSpace,
- XYZ_D50,
Lab,
- LCH,
+ LCH as LCHSpace,
OKLab,
- OKLCH,
-
- P3_Linear,
- P3,
+ OKLCH as OKLCHSpace,
- A98RGB_Linear,
- A98RGB
+ P3
} from 'colorjs.io/fn';
-import HSB from './color_spaces/hsb.js';
-
-ColorSpace.register(XYZ_D65);
-ColorSpace.register(sRGB_Linear);
-ColorSpace.register(sRGB);
-ColorSpace.register(HSL);
-ColorSpace.register(HSV);
-ColorSpace.register(HWB);
-ColorSpace.register(HSB);
-
-ColorSpace.register(XYZ_D50);
-ColorSpace.register(Lab);
-ColorSpace.register(LCH);
+import HSBSpace from './color_spaces/hsb.js';
-ColorSpace.register(OKLab);
-ColorSpace.register(OKLCH);
-
-ColorSpace.register(P3_Linear);
-ColorSpace.register(P3);
-
-ColorSpace.register(A98RGB_Linear);
-ColorSpace.register(A98RGB);
+const map = (n, start1, stop1, start2, stop2) =>
+ ((n - start1) / (stop1 - start1) * (stop2 - start2) + start2);
class Color {
- color;
- maxes;
+ // Reference to underlying color object depending on implementation
+ // Not meant to be used publicly unless the implementation is known for sure
+ _color;
+ // Color mode of the Color object, uses p5 color modes
mode;
- constructor(vals, colorMode='rgb', colorMaxes={rgb: [255, 255, 255, 255]}) {
- // This changes with the sketch's setting
- // NOTE: Maintaining separate maxes for different color space is awkward.
- // Consider just one universal maxes.
- // this.maxes = pInst._colorMaxes;
- this.maxes = colorMaxes;
+ static colorMap = {};
+ static #colorjsMaxes = {};
+
+ // Used to add additional color modes to p5.js
+ // Uses underlying library's definition
+ static addColorMode(mode, definition){
+ ColorSpace.register(definition);
+ Color.colorMap[mode] = definition.id;
+ // Get colorjs maxes
+ Color.#colorjsMaxes[mode] = Object.values(definition.coords).reduce((acc, v) => {
+ acc.push(v.refRange || v.range);
+ return acc;
+ }, []);
+ Color.#colorjsMaxes[mode].push([0, 1]);
+ }
+
+ constructor(vals, colorMode, colorMaxes) {
// This changes with the color object
- // this.mode = pInst._colorMode;
- this.mode = colorMode;
+ this.mode = colorMode || RGB;
+
+ if(vals instanceof Color){
+ // Received Color object to be used for color mode conversion
+ const mode = colorMode ?
+ Color.colorMap[colorMode] :
+ Color.colorMap[vals.mode];
+ this._color = to(vals._color, mode);
+ this.mode = mode;
+
+ }else if (typeof vals === 'object' && !Array.isArray(vals) && vals !== null){
+ // Received color.js object to be used internally
+ const mode = colorMode ?
+ Color.colorMap[colorMode] :
+ vals.spaceId;
+ this._color = to(vals, mode);
+ this.mode = colorMode || Object.entries(Color.colorMap).find(([key, val]) => {
+ return val === this._color.spaceId;
+ });
- if (typeof vals === 'object' && !Array.isArray(vals) && vals !== null){
- this.color = vals;
} else if(typeof vals[0] === 'string') {
+ // Received string
try{
- // NOTE: this will not necessarily have the right color mode
- this.color = parse(vals[0]);
+ this._color = parse(vals[0]);
+ const [mode] = Object.entries(Color.colorMap).find(([key, val]) => {
+ return val === this._color.spaceId;
+ });
+ this.mode = mode;
+ this._color = to(this._color, this._color.spaceId);
}catch(err){
// TODO: Invalid color string
console.error('Invalid color string');
}
}else{
- let alpha;
-
- if(vals.length === 4){
- alpha = vals[vals.length-1];
- }else if (vals.length === 2){
- alpha = vals[1];
- vals = [vals[0], vals[0], vals[0]];
- }else if(vals.length === 1){
- vals = [vals[0], vals[0], vals[0]];
- }
- alpha = alpha !== undefined
- ? alpha / this.maxes[this.mode][3]
- : 1;
-
- // _colorMode can be 'rgb', 'hsb', or 'hsl'
- // These should map to color.js color space
- let space = 'srgb';
- let coords = vals;
- switch(this.mode){
- case 'rgb':
- space = 'srgb';
- coords = [
- vals[0] / this.maxes[this.mode][0],
- vals[1] / this.maxes[this.mode][1],
- vals[2] / this.maxes[this.mode][2]
- ];
- break;
- case 'hsb':
- // TODO: need implementation
- space = 'hsb';
- coords = [
- vals[0] / this.maxes[this.mode][0] * 360,
- vals[1] / this.maxes[this.mode][1] * 100,
- vals[2] / this.maxes[this.mode][2] * 100
- ];
- break;
- case 'hsl':
- space = 'hsl';
- coords = [
- vals[0] / this.maxes[this.mode][0] * 360,
- vals[1] / this.maxes[this.mode][1] * 100,
- vals[2] / this.maxes[this.mode][2] * 100
- ];
- break;
- default:
- console.error('Invalid color mode');
+ // Received individual channel values
+ let mappedVals;
+
+ if(colorMaxes){
+ if(vals.length === 4){
+ mappedVals = Color.mapColorRange(vals, this.mode, colorMaxes);
+ }else if(vals.length === 3){
+ mappedVals = Color.mapColorRange([vals[0], vals[1], vals[2]], this.mode, colorMaxes);
+ mappedVals.push(1);
+ }else if(vals.length === 2){
+ mappedVals = Color.mapColorRange([vals[0], vals[0], vals[0], vals[1]], this.mode, colorMaxes);
+ }else if(vals.length === 1){
+ mappedVals = Color.mapColorRange([vals[0], vals[0], vals[0]], this.mode, colorMaxes);
+ mappedVals.push(1);
+ }
+ }else{
+ mappedVals = vals;
}
+ const space = Color.colorMap[this.mode] || console.error('Invalid color mode');
+ const coords = mappedVals.slice(0, 3);
+
const color = {
space,
coords,
- alpha
+ alpha: mappedVals[3]
};
- this.color = to(color, space);
+ this._color = to(color, space);
+ }
+ }
+
+ // Convert from p5 color range to color.js color range
+ static mapColorRange(origin, mode, maxes){
+ const p5Maxes = maxes.map((max) => {
+ if(!Array.isArray(max)){
+ return [0, max];
+ }else{
+ return max;
+ }
+ });
+ const colorjsMaxes = Color.#colorjsMaxes[mode];
+
+ return origin.map((channel, i) => {
+ const newval = map(channel, p5Maxes[i][0], p5Maxes[i][1], colorjsMaxes[i][0], colorjsMaxes[i][1]);
+ return newval;
+ });
+ }
+
+ // Convert from color.js color range to p5 color range
+ static unmapColorRange(origin, mode, maxes){
+ const p5Maxes = maxes.map((max) => {
+ if(!Array.isArray(max)){
+ return [0, max];
+ }else{
+ return max;
+ }
+ });
+ const colorjsMaxes = Color.#colorjsMaxes[mode];
+
+ return origin.map((channel, i) => {
+ const newval = map(channel, colorjsMaxes[i][0], colorjsMaxes[i][1], p5Maxes[i][0], p5Maxes[i][1]);
+ return newval;
+ });
+ }
+
+ // Will do conversion in-Gamut as out of Gamut conversion is only really useful for futher conversions
+ #toColorMode(mode){
+ return new Color(this._color, mode);
+ }
+
+ // Get raw coordinates of underlying library, can differ between libraries
+ get _array() {
+ return [...this._color.coords, this._color.alpha];
+ }
+
+ array(){
+ return this._array;
+ }
+
+ 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');
+ }
+
+ const obj = range(this._color, color._color, {
+ space: this._color.space.path[spaceIndex].id
+ })(amt);
+
+ return new Color(obj, mode || this.mode);
}
/**
@@ -186,7 +240,7 @@ class Color {
*/
toString(format) {
// NOTE: memoize
- return serialize(this.color, {
+ return serialize(this._color, {
format
});
}
@@ -227,16 +281,22 @@ class Color {
*
*
*/
- setRed(new_red) {
- const red_val = new_red / this.maxes[constants.RGB][0];
- if(this.mode === constants.RGB){
- this.color.coords[0] = red_val;
+ setRed(new_red, max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ const colorjsMax = Color.#colorjsMaxes[RGB][0];
+ const newval = map(new_red, max[0], max[1], colorjsMax[0], colorjsMax[1]);
+
+ if(this.mode === RGB || this.mode === RGBHDR){
+ this._color.coords[0] = newval;
}else{
// Will do an imprecise conversion to 'srgb', not recommended
- const space = this.color.space.id;
- const representation = to(this.color, 'srgb');
- representation.coords[0] = red_val;
- this.color = to(representation, space);
+ const space = this._color.space.id;
+ const representation = to(this._color, 'srgb');
+ representation.coords[0] = newval;
+ this._color = to(representation, space);
}
}
@@ -276,16 +336,22 @@ class Color {
*
*
**/
- setGreen(new_green) {
- const green_val = new_green / this.maxes[constants.RGB][1];
- if(this.mode === constants.RGB){
- this.color.coords[1] = green_val;
+ setGreen(new_green, max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ const colorjsMax = Color.#colorjsMaxes[RGB][1];
+ const newval = map(new_green, max[0], max[1], colorjsMax[0], colorjsMax[1]);
+
+ if(this.mode === RGB || this.mode === RGBHDR){
+ this._color.coords[1] = newval;
}else{
// Will do an imprecise conversion to 'srgb', not recommended
- const space = this.color.space.id;
- const representation = to(this.color, 'srgb');
- representation.coords[1] = green_val;
- this.color = to(representation, space);
+ const space = this._color.space.id;
+ const representation = to(this._color, 'srgb');
+ representation.coords[1] = newval;
+ this._color = to(representation, space);
}
}
@@ -325,16 +391,22 @@ class Color {
*
*
**/
- setBlue(new_blue) {
- const blue_val = new_blue / this.maxes[constants.RGB][2];
- if(this.mode === constants.RGB){
- this.color.coords[2] = blue_val;
+ setBlue(new_blue, max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ const colorjsMax = Color.#colorjsMaxes[RGB][2];
+ const newval = map(new_blue, max[0], max[1], colorjsMax[0], colorjsMax[1]);
+
+ if(this.mode === RGB || this.mode === RGBHDR){
+ this._color.coords[2] = newval;
}else{
// Will do an imprecise conversion to 'srgb', not recommended
- const space = this.color.space.id;
- const representation = to(this.color, 'srgb');
- representation.coords[2] = blue_val;
- this.color = to(representation, space);
+ const space = this._color.space.id;
+ const representation = to(this._color, 'srgb');
+ representation.coords[2] = newval;
+ this._color = to(representation, space);
}
}
@@ -375,47 +447,96 @@ class Color {
*
*
**/
- setAlpha(new_alpha) {
- this.color.alpha = new_alpha / this.maxes[this.mode][3];
+ setAlpha(new_alpha, max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ const colorjsMax = Color.#colorjsMaxes[this.mode][3];
+ const newval = map(new_alpha, max[0], max[1], colorjsMax[0], colorjsMax[1]);
+
+ this._color.alpha = newval;
+ }
+
+ _getRGBA(maxes=[1, 1, 1, 1]) {
+ // Get colorjs maxes
+ const colorjsMaxes = Color.#colorjsMaxes[this.mode];
+
+ // Normalize everything to 0,1 or the provided range (map)
+ let coords = structuredClone(to(this._color, 'srgb').coords);
+ coords.push(this._color.alpha);
+
+ const rangeMaxes = maxes.map((v) => {
+ if(!Array.isArray(v)){
+ return [0, v];
+ }else{
+ return v
+ }
+ });
+
+ coords = coords.map((coord, i) => {
+ return map(coord, colorjsMaxes[i][0], colorjsMaxes[i][1], rangeMaxes[i][0], rangeMaxes[i][1]);
+ });
+
+ return coords;
}
- _getRed() {
- if(this.mode === constants.RGB){
- return this.color.coords[0] * this.maxes[constants.RGB][0];
+ _getMode() {
+ return this.mode;
+ }
+
+ _getRed(max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ if(this.mode === RGB || this.mode === RGBHDR){
+ const colorjsMax = Color.#colorjsMaxes[this.mode][0];
+ return map(this._color.coords[0], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}else{
// Will do an imprecise conversion to 'srgb', not recommended
- return to(this.color, 'srgb').coords[0] * this.maxes[constants.RGB][0];
+ const colorjsMax = Color.#colorjsMaxes[RGB][0];
+ return map(to(this._color, 'srgb').coords[0], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}
}
- _getGreen() {
- if(this.mode === constants.RGB){
- return this.color.coords[1] * this.maxes[constants.RGB][1];
+ _getGreen(max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ if(this.mode === RGB || this.mode === RGBHDR){
+ const colorjsMax = Color.#colorjsMaxes[this.mode][1];
+ return map(this._color.coords[1], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}else{
// Will do an imprecise conversion to 'srgb', not recommended
- return to(this.color, 'srgb').coords[1] * this.maxes[constants.RGB][1];
+ const colorjsMax = Color.#colorjsMaxes[RGB][1];
+ return map(to(this._color, 'srgb').coords[1], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}
}
- _getBlue() {
- if(this.mode === constants.RGB){
- return this.color.coords[2] * this.maxes[constants.RGB][2];
+ _getBlue(max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ if(this.mode === RGB || this.mode === RGBHDR){
+ const colorjsMax = Color.#colorjsMaxes[this.mode][2];
+ return map(this._color.coords[2], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}else{
// Will do an imprecise conversion to 'srgb', not recommended
- return to(this.color, 'srgb').coords[2] * this.maxes[constants.RGB][2];
+ const colorjsMax = Color.#colorjsMaxes[RGB][2];
+ return map(to(this._color, 'srgb').coords[2], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}
}
- _getAlpha() {
- return this.color.alpha * this.maxes[this.mode][3];
- }
-
- _getMode() {
- return this.mode;
- }
+ _getAlpha(max=[0, 1]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
- _getMaxes() {
- return this.maxes;
+ const colorjsMax = Color.#colorjsMaxes[this.mode][3];
+ return map(this._color.alpha, colorjsMax[0], colorjsMax[1], max[0], max[1]);
}
/**
@@ -424,12 +545,18 @@ class Color {
* an HSB color object, but will default to the HSL-normalized saturation
* otherwise.
*/
- _getHue() {
- if(this.mode === constants.HSB || this.mode === constants.HSL){
- return this.color.coords[0] / 360 * this.maxes[this.mode][0];
+ _getHue(max=[0, 360]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ if(this.mode === HSB || this.mode === HSL){
+ const colorjsMax = Color.#colorjsMaxes[this.mode][0];
+ return map(this._color.coords[0], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}else{
// Will do an imprecise conversion to 'HSL', not recommended
- return to(this.color, 'hsl').coords[0] / 360 * this.maxes[this.mode][0];
+ const colorjsMax = Color.#colorjsMaxes[HSL][0];
+ return map(to(this._color, 'hsl').coords[0], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}
}
@@ -438,47 +565,53 @@ class Color {
* the HSB saturation when supplied with an HSB color object, but will default
* to the HSL saturation otherwise.
*/
- _getSaturation() {
- if(this.mode === constants.HSB || this.mode === constants.HSL){
- return this.color.coords[1] / 100 * this.maxes[this.mode][1];
+ _getSaturation(max=[0, 100]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
+
+ if(this.mode === HSB || this.mode === HSL){
+ const colorjsMax = Color.#colorjsMaxes[this.mode][1];
+ return map(this._color.coords[1], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}else{
// Will do an imprecise conversion to 'HSL', not recommended
- return to(this.color, 'hsl').coords[1] / 100 * this.maxes[this.mode][1];
+ const colorjsMax = Color.#colorjsMaxes[HSL][1];
+ return map(to(this._color, 'hsl').coords[1], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}
}
- _getBrightness() {
- if(this.mode === constants.HSB){
- return this.color.coords[2] / 100 * this.maxes[this.mode][2];
- }else{
- // Will do an imprecise conversion to 'HSB', not recommended
- return to(this.color, 'hsb').coords[2] / 100 * this.maxes[this.mode][2];
+ _getBrightness(max=[0, 100]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
}
- }
- _getLightness() {
- if(this.mode === constants.HSL){
- return this.color.coords[2] / 100 * this.maxes[this.mode][2];
+ if(this.mode === HSB){
+ const colorjsMax = Color.#colorjsMaxes[this.mode][2];
+ return map(this._color.coords[2], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}else{
// Will do an imprecise conversion to 'HSB', not recommended
- return to(this.color, 'hsl').coords[2] / 100 * this.maxes[this.mode][2];
+ const colorjsMax = Color.#colorjsMaxes[HSB][2];
+ return map(to(this._color, 'hsb').coords[2], colorjsMax[0], colorjsMax[1], max[0], max[1]);
}
}
- get _array() {
- return this.array();
- }
-
- array() {
- return [...this.color.coords, this.color.alpha];
- }
+ _getLightness(max=[0, 100]) {
+ if(!Array.isArray(max)){
+ max = [0, max];
+ }
- get levels() {
- return this._array.map(v => v * 255);
+ if(this.mode === HSL){
+ const colorjsMax = Color.#colorjsMaxes[this.mode][2];
+ return map(this._color.coords[2], colorjsMax[0], colorjsMax[1], max[0], max[1]);
+ }else{
+ // Will do an imprecise conversion to 'HSL', not recommended
+ const colorjsMax = Color.#colorjsMaxes[HSL][2];
+ return map(to(this._color, 'hsl').coords[2], colorjsMax[0], colorjsMax[1], max[0], max[1]);
+ }
}
}
-function color(p5, fn){
+function color(p5, fn, lifecycles){
/**
* A class to describe a color.
*
@@ -507,6 +640,89 @@ function color(p5, fn){
* or CSS color.
*/
p5.Color = Color;
+
+ // Register color modes and initialize Color maxes to what p5 has set for itself
+ p5.Color.addColorMode(RGB, sRGB);
+ p5.Color.addColorMode(RGBHDR, P3);
+ p5.Color.addColorMode(HSB, HSBSpace);
+ p5.Color.addColorMode(HSL, HSLSpace);
+ p5.Color.addColorMode(HWB, HWBSpace);
+ p5.Color.addColorMode(LAB, Lab);
+ p5.Color.addColorMode(LCH, LCHSpace);
+ p5.Color.addColorMode(OKLAB, OKLab);
+ p5.Color.addColorMode(OKLCH, OKLCHSpace);
+
+ lifecycles.presetup = function(){
+ const pInst = this;
+
+ // Decorate set methods
+ const setMethods = ['Red', 'Green', 'Blue', 'Alpha'];
+ for(let i in setMethods){
+ const method = setMethods[i];
+ const setCopy = p5.Color.prototype['set' + method];
+ p5.Color.prototype['set' + method] = function(newval, max){
+ max = max || pInst?._renderer?.states?.colorMaxes?.[RGB][i];
+ return setCopy.call(this, newval, max);
+ }
+ }
+
+ // Decorate get methods
+ function decorateGet(channel, modes){
+ const getCopy = p5.Color.prototype['_get' + channel];
+ p5.Color.prototype['_get' + channel] = function(max){
+ if(Object.keys(modes).includes(this.mode)){
+ max = max || pInst?._renderer?.states?.colorMaxes?.[this.mode][modes[this.mode]];
+ }else{
+ const defaultMode = Object.keys(modes)[0];
+ max = max || pInst?._renderer?.states?.colorMaxes?.[defaultMode][modes[defaultMode]];
+ }
+
+ return getCopy.call(this, max);
+ }
+ }
+
+ decorateGet('Red', {
+ [RGB]: 0,
+ [RGBHDR]: 0
+ });
+ decorateGet('Green', {
+ [RGB]: 1,
+ [RGBHDR]: 1
+ });
+ decorateGet('Blue', {
+ [RGB]: 2,
+ [RGBHDR]: 2
+ });
+ decorateGet('Alpha', {
+ [RGB]: 3,
+ [RGBHDR]: 3,
+ [HSB]: 3,
+ [HSL]: 3,
+ [HWB]: 3,
+ [LAB]: 3,
+ [LCH]: 3,
+ [OKLAB]: 3,
+ [OKLCH]: 3
+ });
+
+ decorateGet('Hue', {
+ [HSL]: 0,
+ [HSB]: 0,
+ [HWB]: 0,
+ [LCH]: 2,
+ [OKLCH]: 2
+ });
+ decorateGet('Saturation', {
+ [HSL]: 1,
+ [HSB]: 1
+ });
+ decorateGet('Brightness', {
+ [HSB]: 2
+ });
+ decorateGet('Lightness', {
+ [HSL]: 2
+ });
+ };
}
export default color;
diff --git a/src/color/setting.js b/src/color/setting.js
index 8103aae975..05f8f684ba 100644
--- a/src/color/setting.js
+++ b/src/color/setting.js
@@ -7,6 +7,7 @@
*/
import * as constants from '../core/constants';
+import { RGB, RGBHDR, HSL, HSB, HWB, LAB, LCH, OKLAB, OKLCH } from './creating_reading';
function setting(p5, fn){
/**
@@ -944,20 +945,29 @@ function setting(p5, fn){
* @param {Number} max3 range for the blue or brightness/lightness
* depending on the current color mode.
* @param {Number} [maxA] range for the alpha.
- * @chainable
+ *
+ * @return {String} The current color mode.
*/
fn.colorMode = function(mode, max1, max2, max3, maxA) {
p5._validateParameters('colorMode', arguments);
if (
- mode === constants.RGB ||
- mode === constants.HSB ||
- mode === constants.HSL
+ [
+ RGB,
+ RGBHDR,
+ HSB,
+ HSL,
+ HWB,
+ LAB,
+ LCH,
+ OKLAB,
+ OKLCH
+ ].includes(mode)
) {
// Set color mode.
- this._colorMode = mode;
+ this._renderer.states.colorMode = mode;
// Set color maxes.
- const maxes = this._colorMaxes[mode];
+ const maxes = this._renderer.states.colorMaxes[mode];
if (arguments.length === 2) {
maxes[0] = max1; // Red
maxes[1] = max1; // Green
@@ -975,7 +985,7 @@ function setting(p5, fn){
}
}
- return this;
+ return this._renderer.states.colorMode;
};
/**
@@ -1577,7 +1587,6 @@ function setting(p5, fn){
* @param {p5.Color} color the stroke color.
* @chainable
*/
-
fn.stroke = function(...args) {
this._renderer.stroke(...args);
return this;
diff --git a/src/core/constants.js b/src/core/constants.js
index 8142772026..ff9c873433 100644
--- a/src/core/constants.js
+++ b/src/core/constants.js
@@ -21,6 +21,9 @@ export const VERSION = 'VERSION_WILL_BE_REPLACED_BY_BUILD';
* @final
*/
export const P2D = Symbol('p2d');
+
+export const P2DHDR = 'p2d-hdr';
+
/**
* One of the two render modes in p5.js, used for computationally intensive tasks like 3D rendering and shaders.
*
@@ -841,7 +844,7 @@ export const MITER = 'miter';
* @property {RGB} RGB
* @final
*/
-export const RGB = 'rgb';
+// export const RGB = 'rgb';
/**
* HSB (hue, saturation, brightness) is a type of color model.
* You can learn more about it at
@@ -851,13 +854,19 @@ export const RGB = 'rgb';
* @property {HSB} HSB
* @final
*/
-export const HSB = 'hsb';
+// export const HSB = 'hsb';
/**
* @typedef {'hsl'} HSL
* @property {HSL} HSL
* @final
*/
-export const HSL = 'hsl';
+// export const HSL = 'hsl';
+/**
+ * @typedef {'rgba'} RGBA
+ * @property {RGBA} RGBA
+ * @final
+ */
+// export const RGBA = 'rgba';
// DOM EXTENSION
/**
@@ -1337,13 +1346,6 @@ export const FLOAT = 'float';
*/
export const HALF_FLOAT = 'half-float';
-/**
- * @typedef {'rgba'} RGBA
- * @property {RGBA} RGBA
- * @final
- */
-export const RGBA = 'rgba';
-
/**
* The `splineEnds` mode where splines curve through
* their first and last points.
diff --git a/src/core/main.js b/src/core/main.js
index b7b935dbb0..af2b37f68c 100644
--- a/src/core/main.js
+++ b/src/core/main.js
@@ -413,14 +413,6 @@ class p5 {
};
this._styles = [];
-
- this._colorMode = constants.RGB;
- this._colorMaxes = {
- rgb: [255, 255, 255, 255],
- hsb: [360, 100, 100, 1],
- hsl: [360, 100, 100, 1]
- };
-
this._downKeys = {}; //Holds the key codes of currently pressed keys
}
}
diff --git a/src/core/p5.Graphics.js b/src/core/p5.Graphics.js
index eda81d8ba3..403f934e2c 100644
--- a/src/core/p5.Graphics.js
+++ b/src/core/p5.Graphics.js
@@ -4,8 +4,8 @@
* @for p5
*/
-// import p5 from './main';
import * as constants from './constants';
+import { RGB, HSB, HSL } from '../color/creating_reading';
import primitives2D from '../shape/2d_primitives';
import attributes from '../shape/attributes';
import curves from '../shape/curves';
@@ -576,12 +576,12 @@ class Graphics {
this._bezierDetail = 20;
this._curveDetail = 20;
- this._colorMode = constants.RGB;
- this._colorMaxes = {
- rgb: [255, 255, 255, 255],
- hsb: [360, 100, 100, 1],
- hsl: [360, 100, 100, 1]
- };
+ // this._colorMode = RGB;
+ // this._colorMaxes = {
+ // rgb: [255, 255, 255, 255],
+ // hsb: [360, 100, 100, 1],
+ // hsl: [360, 100, 100, 1]
+ // };
this._downKeys = {}; //Holds the key codes of currently pressed keys
}
diff --git a/src/core/p5.Renderer.js b/src/core/p5.Renderer.js
index 61d6ea0c2f..bcc69ed086 100644
--- a/src/core/p5.Renderer.js
+++ b/src/core/p5.Renderer.js
@@ -11,6 +11,37 @@ import { Vector } from '../math/p5.Vector';
import { Shape } from '../shape/custom_shapes';
class Renderer {
+ static states = {
+ strokeColor: null,
+ strokeSet: false,
+ fillColor: null,
+ fillSet: false,
+ tint: null,
+
+ imageMode: constants.CORNER,
+ rectMode: constants.CORNER,
+ ellipseMode: constants.CENTER,
+ strokeWeight: 1,
+
+ textFont: { family: 'sans-serif' },
+ textLeading: 15,
+ leadingSet: false,
+ textSize: 12,
+ textAlign: constants.LEFT,
+ textBaseline: constants.BASELINE,
+ bezierOrder: 3,
+ splineEnds: constants.INCLUDE,
+ textWrap: constants.WORD,
+
+ // added v2.0
+ fontStyle: constants.NORMAL, // v1: textStyle
+ fontStretch: constants.NORMAL,
+ fontWeight: constants.NORMAL,
+ lineHeight: constants.NORMAL,
+ fontVariant: constants.NORMAL,
+ direction: 'inherit'
+ }
+
constructor(pInst, w, h, isMainCanvas) {
this._pInst = pInst;
this._isMainCanvas = isMainCanvas;
@@ -27,36 +58,19 @@ class Renderer {
}
// Renderer state machine
- this.states = {
- strokeColor: new Color([0, 0, 0]),
- strokeSet: false,
- fillColor: new Color([255, 255, 255]),
- fillSet: false,
- tint: null,
- imageMode: constants.CORNER,
- rectMode: constants.CORNER,
- ellipseMode: constants.CENTER,
- strokeWeight: 1,
-
- textFont: { family: 'sans-serif' },
- textLeading: 15,
- leadingSet: false,
- textSize: 12,
- textAlign: constants.LEFT,
- textBaseline: constants.BASELINE,
- bezierOrder: 3,
- splineEnds: constants.INCLUDE,
-
- textWrap: constants.WORD,
-
- // added v2.0
- fontStyle: constants.NORMAL, // v1: textStyle
- fontStretch: constants.NORMAL,
- fontWeight: constants.NORMAL,
- lineHeight: constants.NORMAL,
- fontVariant: constants.NORMAL,
- direction: 'inherit'
- };
+ this.states = Object.assign({}, Renderer.states);
+ // Clone properties that support it
+ for (const key in this.states) {
+ if (this.states[key] instanceof Array) {
+ this.states[key] = this.states[key].slice();
+ } else if (this.states[key] && this.states[key].clone instanceof Function) {
+ this.states[key] = this.states[key].clone();
+ }
+ }
+
+ this.states.strokeColor = new Color([0, 0, 0]);
+ this.states.fillColor = new Color([255, 255, 255]);
+
this._pushPopStack = [];
// NOTE: can use the length of the push pop stack instead
this._pushPopDepth = 0;
diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js
index d914c52439..6367fb9fdb 100644
--- a/src/core/p5.Renderer2D.js
+++ b/src/core/p5.Renderer2D.js
@@ -5,9 +5,8 @@ import { Graphics } from './p5.Graphics';
import { Image } from '../image/p5.Image';
import { Element } from '../dom/p5.Element';
import { MediaElement } from '../dom/p5.MediaElement';
-
+import { RGBHDR } from '../color/creating_reading';
import FilterRenderer2D from '../image/filterRenderer2D';
-
import { PrimitiveToPath2DConverter } from '../shape/custom_shapes';
@@ -15,7 +14,7 @@ const styleEmpty = 'rgba(0,0,0,0)';
// const alphaThreshold = 0.00125; // minimum visible
class Renderer2D extends Renderer {
- constructor(pInst, w, h, isMainCanvas, elt) {
+ constructor(pInst, w, h, isMainCanvas, elt, attributes = {}) {
super(pInst, w, h, isMainCanvas);
this.canvas = this.elt = elt || document.createElement('canvas');
@@ -33,7 +32,6 @@ class Renderer2D extends Renderer {
this.elt.classList.add('p5Canvas');
// Extend renderer with methods of p5.Element with getters
- // this.wrappedElt = new p5.Element(elt, pInst);
for (const p of Object.getOwnPropertyNames(Element.prototype)) {
if (p !== 'constructor' && p[0] !== '_') {
Object.defineProperty(this, p, {
@@ -65,7 +63,10 @@ class Renderer2D extends Renderer {
}
// Get and store drawing context
- this.drawingContext = this.canvas.getContext('2d');
+ this.drawingContext = this.canvas.getContext('2d', attributes);
+ if(attributes.colorSpace === 'display-p3'){
+ this.states.colorMode = RGBHDR;
+ }
if (isMainCanvas) {
this._pInst.drawingContext = this.drawingContext;
}
@@ -181,7 +182,7 @@ class Renderer2D extends Renderer {
//accessible Outputs
if (this._pInst._addAccsOutput()) {
- this._pInst._accsBackground(color.levels);
+ this._pInst._accsBackground(color._getRGBA([255, 255, 255, 255]));
}
const newFill = color.toString();
@@ -216,7 +217,7 @@ class Renderer2D extends Renderer {
//accessible Outputs
if (this._pInst._addAccsOutput()) {
- this._pInst._accsCanvasColors('fill', color.levels);
+ this._pInst._accsCanvasColors('fill', color._getRGBA([255, 255, 255, 255]));
}
}
@@ -227,7 +228,7 @@ class Renderer2D extends Renderer {
//accessible Outputs
if (this._pInst._addAccsOutput()) {
- this._pInst._accsCanvasColors('stroke', color.levels);
+ this._pInst._accsCanvasColors('stroke', color._getRGBA([255, 255, 255, 255]));
}
}
@@ -580,10 +581,7 @@ class Renderer2D extends Renderer {
}
} else if (imgOrCol instanceof p5.Color) {
if (idx < this.pixels.length) {
- r = imgOrCol.levels[0];
- g = imgOrCol.levels[1];
- b = imgOrCol.levels[2];
- a = imgOrCol.levels[3];
+ [r, g, b, a] = imgOrCol._getRGBA([255, 255, 255, 255]);
//this.updatePixels.call(this);
}
}
@@ -1224,6 +1222,11 @@ function renderer2D(p5, fn){
*/
p5.Renderer2D = Renderer2D;
p5.renderers[constants.P2D] = Renderer2D;
+ p5.renderers['p2d-hdr'] = new Proxy(Renderer2D, {
+ construct(target, [pInst, w, h, isMainCanvas, elt]){
+ return new target(pInst, w, h, isMainCanvas, elt, {colorSpace: "display-p3"})
+ }
+ })
}
export default renderer2D;
diff --git a/src/dom/dom.js b/src/dom/dom.js
index 76265cffcb..50713d327b 100644
--- a/src/dom/dom.js
+++ b/src/dom/dom.js
@@ -1716,6 +1716,8 @@ function dom(p5, fn){
*/
fn.createColorPicker = function (value) {
p5._validateParameters('createColorPicker', arguments);
+ // TODO: This implementation needs to be rechecked or reimplemented
+ // The way it worked with color is a bit too complex
const elt = document.createElement('input');
let self;
elt.type = 'color';
@@ -1723,29 +1725,27 @@ function dom(p5, fn){
if (value instanceof p5.Color) {
elt.value = value.toString('#rrggbb');
} else {
- fn._colorMode = 'rgb';
- fn._colorMaxes = {
- rgb: [255, 255, 255, 255],
- hsb: [360, 100, 100, 1],
- hsl: [360, 100, 100, 1]
- };
- elt.value = fn.color(value).toString('#rrggbb');
+ this.push();
+ this.colorMode('rgb');
+ elt.value = this.color(value).toString('#rrggbb');
+ this.pop();
}
} else {
elt.value = '#000000';
}
self = addElement(elt, this);
// Method to return a p5.Color object for the given color.
+ const inst = this;
self.color = function () {
+ inst.push();
if (value) {
if (value.mode) {
- fn._colorMode = value.mode;
- }
- if (value.maxes) {
- fn._colorMaxes = value.maxes;
+ inst.colorMode(value.mode, ...value?.maxes[value.mode]);
}
}
- return fn.color(this.elt.value);
+ const c = inst.color(this.elt.value);
+ inst.pop();
+ return c;
};
return self;
};
diff --git a/src/dom/p5.Element.js b/src/dom/p5.Element.js
index 3a896af89a..6ecb74f5b6 100644
--- a/src/dom/p5.Element.js
+++ b/src/dom/p5.Element.js
@@ -1215,16 +1215,7 @@ class Element {
const self = this;
if (val instanceof Color) {
- val =
- 'rgba(' +
- val.levels[0] +
- ',' +
- val.levels[1] +
- ',' +
- val.levels[2] +
- ',' +
- val.levels[3] / 255 +
- ')';
+ val = val.toString();
}
if (typeof val === 'undefined') {
diff --git a/src/image/loading_displaying.js b/src/image/loading_displaying.js
index e46f901c51..b8fa13db81 100644
--- a/src/image/loading_displaying.js
+++ b/src/image/loading_displaying.js
@@ -1293,7 +1293,7 @@ function loadingDisplaying(p5, fn){
fn.tint = function(...args) {
p5._validateParameters('tint', args);
const c = this.color(...args);
- this._renderer.states.tint = c.levels;
+ this._renderer.states.tint = c._getRGBA([255, 255, 255, 255]);
};
/**
diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js
index b87827be81..e550501e03 100644
--- a/src/image/p5.Image.js
+++ b/src/image/p5.Image.js
@@ -668,10 +668,7 @@ class Image {
}
} else if (imgOrCol instanceof p5.Color) {
if (idx < pixelsState.pixels.length) {
- r = imgOrCol.levels[0];
- g = imgOrCol.levels[1];
- b = imgOrCol.levels[2];
- a = imgOrCol.levels[3];
+ [r, g, b, a] = imgOrCol._getRGBA([255, 255, 255, 255]);
//this.updatePixels.call(this);
}
}
diff --git a/src/shape/custom_shapes.js b/src/shape/custom_shapes.js
index ce718f9f3c..84724486c4 100644
--- a/src/shape/custom_shapes.js
+++ b/src/shape/custom_shapes.js
@@ -650,17 +650,15 @@ class Shape {
} else if (original instanceof Vector) {
return new Vector(queue.shift(), queue.shift(), queue.shift());
} else if (original instanceof Color) {
+ // NOTE: Not sure what intention here is, `Color` constructor signature
+ // has changed so needed to be reviewed
const array = [
queue.shift(),
queue.shift(),
queue.shift(),
queue.shift()
];
- return new Color(
- array.map((v, i) => v * original.maxes[original.mode][i]),
- original.mode,
- original.maxes
- );
+ return new Color(array);
}
}
diff --git a/src/webgl/material.js b/src/webgl/material.js
index 1768e0cfaa..d63b9a6b69 100644
--- a/src/webgl/material.js
+++ b/src/webgl/material.js
@@ -3626,7 +3626,7 @@ function material(p5, fn){
this.states.drawMode = constants.TEXTURE;
this.states._useNormalMaterial = false;
this.states._tex = tex;
- this.states.fillColor = new Color(255);
+ this.states.fillColor = new Color([1, 1, 1]);
};
RendererGL.prototype.normalMaterial = function(...args) {
@@ -3635,7 +3635,7 @@ function material(p5, fn){
this.states._useEmissiveMaterial = false;
this.states._useNormalMaterial = true;
this.states.curFillColor = [1, 1, 1, 1];
- this.states.fillColor = new Color(255);
+ this.states.fillColor = new Color([1, 1, 1]);
this.states.strokeColor = null;
}
diff --git a/src/webgl/p5.Framebuffer.js b/src/webgl/p5.Framebuffer.js
index 2a5ced5f7a..37081f3b09 100644
--- a/src/webgl/p5.Framebuffer.js
+++ b/src/webgl/p5.Framebuffer.js
@@ -4,6 +4,7 @@
*/
import * as constants from '../core/constants';
+import { RGB, RGBA } from '../color/creating_reading';
import { checkWebGLCapabilities } from './p5.Texture';
import { readPixelsWebGL, readPixelWebGL } from './p5.RendererGL';
import { Camera } from './p5.Camera';
@@ -63,8 +64,8 @@ class Framebuffer {
this.format = settings.format || constants.UNSIGNED_BYTE;
this.channels = settings.channels || (
this.renderer._pInst._glAttributes.alpha
- ? constants.RGBA
- : constants.RGB
+ ? RGBA
+ : RGB
);
this.useDepth = settings.depth === undefined ? true : settings.depth;
this.depthFormat = settings.depthFormat || constants.FLOAT;
@@ -449,14 +450,14 @@ class Framebuffer {
}
if (
- this.channels === constants.RGB &&
+ this.channels === RGB &&
[constants.FLOAT, constants.HALF_FLOAT].includes(this.format)
) {
console.warn(
'FLOAT and HALF_FLOAT formats do not work cross-platform with only ' +
'RGB channels. Falling back to RGBA.'
);
- this.channels = constants.RGBA;
+ this.channels = RGBA;
}
}
@@ -640,7 +641,7 @@ class Framebuffer {
type = gl.UNSIGNED_BYTE;
}
- if (this.channels === constants.RGBA) {
+ if (this.channels === RGBA) {
format = gl.RGBA;
} else {
format = gl.RGB;
diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js
index b929542869..6756ebc62d 100644
--- a/src/webgl/p5.RendererGL.js
+++ b/src/webgl/p5.RendererGL.js
@@ -1003,11 +1003,7 @@ class RendererGL extends Renderer {
*/
background(...args) {
const _col = this._pInst.color(...args);
- const _r = _col.levels[0] / 255;
- const _g = _col.levels[1] / 255;
- const _b = _col.levels[2] / 255;
- const _a = _col.levels[3] / 255;
- this.clear(_r, _g, _b, _a);
+ this.clear(..._col._getRGBA());
}
// Combines the model and view matrices to get the uMVMatrix
diff --git a/test/js/mocks.js b/test/js/mocks.js
index 63d0cc7951..80a4cd68f8 100644
--- a/test/js/mocks.js
+++ b/test/js/mocks.js
@@ -18,11 +18,15 @@ const httpMocks = [
export const httpMock = setupWorker(...httpMocks);
// p5.js module mocks
+const rendererStates = {};
export const mockP5 = vi.fn();
Object.assign(mockP5, {
_validateParameters: vi.fn(),
_friendlyFileLoadError: vi.fn(),
- _friendlyError: vi.fn()
+ _friendlyError: vi.fn(),
+ Renderer: {
+ states: rendererStates
+ }
});
const mockCanvas = document.createElement('canvas');
@@ -38,5 +42,8 @@ export const mockP5Prototype = {
canvas: {
id: 'myCanvasID'
},
- _elements: []
+ _elements: [],
+ _renderer: {
+ states: rendererStates
+ }
};
diff --git a/test/unit/color/color_conversion.js b/test/unit/color/color_conversion.js
index aa0e8b31c2..777ddee526 100644
--- a/test/unit/color/color_conversion.js
+++ b/test/unit/color/color_conversion.js
@@ -7,7 +7,7 @@ assert.arrayApproximately = function(arr1, arr2, delta) {
}
};
-suite('color/p5.ColorConversion', function() {
+suite.todo('color/p5.ColorConversion', function() {
var rgba = [1, 0, 0.4, 0.8];
var rgbaWithMaxHue = [1, 0, 0, 0.6];
var rgbaWithHighLightness = [0.969, 0.753, 0.122, 0.8];
diff --git a/test/unit/color/creating_reading.js b/test/unit/color/creating_reading.js
index da0d42abed..f4b134c204 100644
--- a/test/unit/color/creating_reading.js
+++ b/test/unit/color/creating_reading.js
@@ -1,21 +1,13 @@
-import p5 from '../../../src/app.js';
+import { mockP5, mockP5Prototype } from '../../js/mocks';
+import creatingReading from '../../../src/color/creating_reading';
+import setting from '../../../src/color/setting';
+import p5Color from '../../../src/color/p5.Color';
suite('color/CreatingReading', function() {
- var myp5;
-
- beforeEach(async function() {
- await new Promise(resolve => {
- new p5(function(p) {
- p.setup = function() {
- myp5 = p;
- resolve();
- };
- });
- });
- });
-
- afterEach(function() {
- myp5.remove();
+ beforeAll(async function() {
+ creatingReading(mockP5, mockP5Prototype);
+ setting(mockP5, mockP5Prototype);
+ p5Color(mockP5, mockP5Prototype, {});
});
var fromColor;
@@ -23,76 +15,76 @@ suite('color/CreatingReading', function() {
suite.todo('p5.prototype.alpha', function() {
beforeEach(function() {
- myp5.colorMode(myp5.RGB);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB);
});
});
suite.todo('p5.prototype.red, green, blue', function() {
beforeEach(function() {
- myp5.colorMode(myp5.RGB);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB);
});
});
suite.todo('p5.prototype.hue, brightness, lightness, saturation', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL);
});
});
suite('p5.prototype.lerpColor', function() {
beforeEach(function() {
- myp5.colorMode(myp5.RGB);
- fromColor = myp5.color(218, 165, 32);
- toColor = myp5.color(72, 61, 139);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB);
+ fromColor = mockP5Prototype.color(218, 165, 32);
+ toColor = mockP5Prototype.color(72, 61, 139);
});
test('should correctly get lerp colors in RGB', function() {
- var interA = myp5.lerpColor(fromColor, toColor, 0.33);
- var interB = myp5.lerpColor(fromColor, toColor, 0.66);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, 0.33);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 0.66);
- assert.closeTo(interA.color.coords[0] * 255, 170, 1);
- assert.closeTo(interA.color.coords[1] * 255, 131, 1);
- assert.closeTo(interA.color.coords[2] * 255, 67, 1);
+ assert.closeTo(interA._color.coords[0] * 255, 170, 1);
+ assert.closeTo(interA._color.coords[1] * 255, 131, 1);
+ assert.closeTo(interA._color.coords[2] * 255, 67, 1);
- assert.closeTo(interB.color.coords[0] * 255, 122, 1);
- assert.closeTo(interB.color.coords[1] * 255, 96, 1);
- assert.closeTo(interB.color.coords[2] * 255, 103, 1);
+ assert.closeTo(interB._color.coords[0] * 255, 122, 1);
+ assert.closeTo(interB._color.coords[1] * 255, 96, 1);
+ assert.closeTo(interB._color.coords[2] * 255, 103, 1);
});
test('should correctly get lerp colors in HSL', function() {
// NOTE: This is equivalent to RGB case so is testing nothing new
- myp5.colorMode(myp5.HSL);
- var interA = myp5.lerpColor(fromColor, toColor, 0.33);
- var interB = myp5.lerpColor(fromColor, toColor, 0.66);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, 0.33);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 0.66);
- assert.closeTo(interA.color.coords[0] * 255, 170, 1);
- assert.closeTo(interA.color.coords[1] * 255, 131, 1);
- assert.closeTo(interA.color.coords[2] * 255, 67, 1);
+ assert.closeTo(interA._color.coords[0], 37, 1);
+ assert.closeTo(interA._color.coords[1], 43, 1);
+ assert.closeTo(interA._color.coords[2], 46, 1);
- assert.closeTo(interB.color.coords[0] * 255, 122, 1);
- assert.closeTo(interB.color.coords[1] * 255, 96, 1);
- assert.closeTo(interB.color.coords[2] * 255, 103, 1);
+ assert.closeTo(interB._color.coords[0], 345, 1);
+ assert.closeTo(interB._color.coords[1], 12, 1);
+ assert.closeTo(interB._color.coords[2], 43, 1);
});
test('should correctly get lerp colors in HSB', function() {
// NOTE: This is equivalent to RGB case so is testing nothing new
- myp5.colorMode(myp5.HSB);
- var interA = myp5.lerpColor(fromColor, toColor, 0.33);
- var interB = myp5.lerpColor(fromColor, toColor, 0.66);
+ mockP5Prototype.colorMode(mockP5Prototype.HSB);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, 0.33);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 0.66);
- assert.closeTo(interA.color.coords[0] * 255, 170, 1);
- assert.closeTo(interA.color.coords[1] * 255, 131, 1);
- assert.closeTo(interA.color.coords[2] * 255, 67, 1);
+ assert.closeTo(interA._color.coords[0], 37, 1);
+ assert.closeTo(interA._color.coords[1], 60, 1);
+ assert.closeTo(interA._color.coords[2], 66, 1);
- assert.closeTo(interB.color.coords[0] * 255, 122, 1);
- assert.closeTo(interB.color.coords[1] * 255, 96, 1);
- assert.closeTo(interB.color.coords[2] * 255, 103, 1);
+ assert.closeTo(interB._color.coords[0], 345, 1);
+ assert.closeTo(interB._color.coords[1], 20, 1);
+ assert.closeTo(interB._color.coords[2], 47, 1);
});
test.todo('should not extrapolate', function() {
// NOTE: maybe it should extrapolate
- var interA = myp5.lerpColor(fromColor, toColor, -0.5);
- var interB = myp5.lerpColor(fromColor, toColor, 1.5);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, -0.5);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 1.5);
assert.deepEqual(interA.levels, [218, 165, 32, 255]);
assert.deepEqual(interB.levels, [72, 61, 139, 255]);
});
@@ -100,64 +92,62 @@ suite('color/CreatingReading', function() {
suite('p5.prototype.lerpColor with alpha', function() {
beforeEach(function() {
- myp5.colorMode(myp5.RGB);
- fromColor = myp5.color(218, 165, 32, 49);
- toColor = myp5.color(72, 61, 139, 200);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB);
+ fromColor = mockP5Prototype.color(218, 165, 32, 49);
+ toColor = mockP5Prototype.color(72, 61, 139, 200);
});
test('should correctly get lerp colors in RGB with alpha', function() {
- var interA = myp5.lerpColor(fromColor, toColor, 0.33);
- var interB = myp5.lerpColor(fromColor, toColor, 0.66);
-
- assert.closeTo(interA.color.coords[0] * 255, 170, 1);
- assert.closeTo(interA.color.coords[1] * 255, 131, 1);
- assert.closeTo(interA.color.coords[2] * 255, 67, 1);
- assert.closeTo(interA.color.alpha * 255, 99, 1);
-
- assert.closeTo(interB.color.coords[0] * 255, 122, 1);
- assert.closeTo(interB.color.coords[1] * 255, 96, 1);
- assert.closeTo(interB.color.coords[2] * 255, 103, 1);
- assert.closeTo(interB.color.alpha * 255, 149, 1);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, 0.33);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 0.66);
+
+ assert.closeTo(interA._color.coords[0], 0.66, 0.01);
+ assert.closeTo(interA._color.coords[1], 0.51, 0.01);
+ assert.closeTo(interA._color.coords[2], 0.26, 0.01);
+ assert.closeTo(interA._color.alpha, 0.38, 0.01);
+
+ assert.closeTo(interB._color.coords[0], 0.47, 0.01);
+ assert.closeTo(interB._color.coords[1], 0.37, 0.01);
+ assert.closeTo(interB._color.coords[2], 0.40, 0.01);
+ assert.closeTo(interB._color.alpha, 0.58, 0.01);
});
test('should correctly get lerp colors in HSL with alpha', function() {
- // NOTE: This is equivalent to RGBA case so is testing nothing new
- myp5.colorMode(myp5.HSL);
- var interA = myp5.lerpColor(fromColor, toColor, 0.33);
- var interB = myp5.lerpColor(fromColor, toColor, 0.66);
-
- assert.closeTo(interA.color.coords[0] * 255, 170, 1);
- assert.closeTo(interA.color.coords[1] * 255, 131, 1);
- assert.closeTo(interA.color.coords[2] * 255, 67, 1);
- assert.closeTo(interA.color.alpha * 255, 99, 1);
-
- assert.closeTo(interB.color.coords[0] * 255, 122, 1);
- assert.closeTo(interB.color.coords[1] * 255, 96, 1);
- assert.closeTo(interB.color.coords[2] * 255, 103, 1);
- assert.closeTo(interB.color.alpha * 255, 149, 1);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, 0.33);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 0.66);
+
+ assert.closeTo(interA._color.coords[0], 37, 1);
+ assert.closeTo(interA._color.coords[1], 43, 1);
+ assert.closeTo(interA._color.coords[2], 46, 1);
+ assert.closeTo(interA._color.alpha, 0.38, 0.01);
+
+ assert.closeTo(interB._color.coords[0], 345, 1);
+ assert.closeTo(interB._color.coords[1], 11, 1);
+ assert.closeTo(interB._color.coords[2], 42, 1);
+ assert.closeTo(interB._color.alpha, 0.58, 0.01);
});
test('should correctly get lerp colors in HSB with alpha', function() {
- // NOTE: This is equivalent to RGBA case so is testing nothing new
- myp5.colorMode(myp5.HSB);
- var interA = myp5.lerpColor(fromColor, toColor, 0.33);
- var interB = myp5.lerpColor(fromColor, toColor, 0.66);
-
- assert.closeTo(interA.color.coords[0] * 255, 170, 1);
- assert.closeTo(interA.color.coords[1] * 255, 131, 1);
- assert.closeTo(interA.color.coords[2] * 255, 67, 1);
- assert.closeTo(interA.color.alpha * 255, 99, 1);
-
- assert.closeTo(interB.color.coords[0] * 255, 122, 1);
- assert.closeTo(interB.color.coords[1] * 255, 96, 1);
- assert.closeTo(interB.color.coords[2] * 255, 103, 1);
- assert.closeTo(interB.color.alpha * 255, 149, 1);
+ mockP5Prototype.colorMode(mockP5Prototype.HSB);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, 0.33);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 0.66);
+
+ assert.closeTo(interA._color.coords[0], 37, 1);
+ assert.closeTo(interA._color.coords[1], 60, 1);
+ assert.closeTo(interA._color.coords[2], 66, 1);
+ assert.closeTo(interA._color.alpha, 0.38, 0.01);
+
+ assert.closeTo(interB._color.coords[0], 345, 1);
+ assert.closeTo(interB._color.coords[1], 20, 1);
+ assert.closeTo(interB._color.coords[2], 47, 1);
+ assert.closeTo(interB._color.alpha, 0.58, 0.01);
});
test.todo('should not extrapolate', function() {
// NOTE: maybe it should extrapolate
- var interA = myp5.lerpColor(fromColor, toColor, -0.5);
- var interB = myp5.lerpColor(fromColor, toColor, 1.5);
+ var interA = mockP5Prototype.lerpColor(fromColor, toColor, -0.5);
+ var interB = mockP5Prototype.lerpColor(fromColor, toColor, 1.5);
assert.deepEqual(interA.levels, [218, 165, 32, 49]);
assert.deepEqual(interB.levels, [72, 61, 139, 200]);
});
diff --git a/test/unit/color/p5.Color.js b/test/unit/color/p5.Color.js
index 45adc03987..12fc3e6648 100644
--- a/test/unit/color/p5.Color.js
+++ b/test/unit/color/p5.Color.js
@@ -1,49 +1,42 @@
-import p5 from '../../../src/app.js';
+import { mockP5, mockP5Prototype } from '../../js/mocks';
+import creatingReading from '../../../src/color/creating_reading';
+import setting from '../../../src/color/setting';
+import { Color } from '../../../src/color/p5.Color';
+import p5Color from '../../../src/color/p5.Color';
suite('p5.Color', function() {
- var myp5;
-
- beforeEach(async function() {
- await new Promise(resolve => {
- new p5(function(p) {
- p.setup = function() {
- myp5 = p;
- resolve();
- };
- });
- });
- });
-
- afterEach(function() {
- myp5.remove();
+ beforeAll(() => {
+ creatingReading(mockP5, mockP5Prototype);
+ setting(mockP5, mockP5Prototype);
+ p5Color(mockP5, mockP5Prototype, {});
});
var c;
suite('p5.prototype.color(r,g,b)', function() {
beforeEach(function() {
- c = myp5.color(255, 0, 102);
+ c = mockP5Prototype.color(255, 0, 102);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('p5.prototype.color(r,g,b,a)', function() {
beforeEach(function() {
- c = myp5.color(255, 0, 102, 204);
+ c = mockP5Prototype.color(255, 0, 102, 204);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 0.8);
});
});
@@ -52,200 +45,200 @@ suite('p5.Color', function() {
suite('p5.prototype.color(string)', function(){
suite('#rgb', function(){
beforeEach(function() {
- c = myp5.color('#f06');
+ c = mockP5Prototype.color('#f06');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('#rgba', function(){
beforeEach(function() {
- c = myp5.color('#f066');
+ c = mockP5Prototype.color('#f066');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 0.4);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 0.4);
});
});
suite('#rrggbb', function(){
beforeEach(function() {
- c = myp5.color('#ff0066');
+ c = mockP5Prototype.color('#ff0066');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('#rrggbbaa', function(){
beforeEach(function() {
- c = myp5.color('#f01dab1e');
+ c = mockP5Prototype.color('#f01dab1e');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [240, 29, 171].map(c => c/255));
- assert.equal(c.color.alpha, 30/255);
+ assert.deepEqual(c._color.coords, [240, 29, 171].map(c => c/255));
+ assert.equal(c._color.alpha, 30/255);
});
});
suite('rgb(r,g,b)', function(){
beforeEach(function() {
- c = myp5.color('rgb(255,0,102)');
+ c = mockP5Prototype.color('rgb(255,0,102)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('rgb(r%,g%,b%)', function(){
beforeEach(function() {
- c = myp5.color('rgb(100%, 0%, 40%)');
+ c = mockP5Prototype.color('rgb(100%, 0%, 40%)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('rgba(r,g,b,a)', function(){
beforeEach(function() {
- c = myp5.color('rgba(255,0,102,0.8)');
+ c = mockP5Prototype.color('rgba(255,0,102,0.8)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 0.8);
});
});
suite('rgba(r%,g%,b%,a)', function(){
beforeEach(function() {
- c = myp5.color('rgba(100.0%,0.0%,40%,0.8)');
+ c = mockP5Prototype.color('rgba(100.0%,0.0%,40%,0.8)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 0.8);
});
});
suite('hsl(h, s%, l%)', function(){
beforeEach(function() {
- c = myp5.color('hsl(336, 100%, 50%)');
+ c = mockP5Prototype.color('hsl(336, 100%, 50%)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
// NOTE: 0.5.2 of color.js uses `new Number` which is corrected in future version
// assert.deepEqual(c.color.coords, [336, 100, 50]);
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 50);
- assert.equal(c.color.alpha, 1);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 50);
+ assert.equal(c._color.alpha, 1);
});
});
suite('hsla(h, s%, l%, a)', function() {
beforeEach(function() {
- c = myp5.color('hsla(336, 100%, 50%, 0.8)');
+ c = mockP5Prototype.color('hsla(336, 100%, 50%, 0.8)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
// NOTE: 0.5.2 of color.js uses `new Number` which is corrected in future version
// assert.deepEqual(c.color.coords, [336, 100, 50]);
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 50);
- assert.equal(c.color.alpha, 0.8);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 50);
+ assert.equal(c._color.alpha, 0.8);
});
});
suite('hsb(h, s%, b%)', function() {
beforeEach(function() {
- c = myp5.color('hsb(336, 100%, 100%)');
+ c = mockP5Prototype.color('hsb(336, 100%, 100%)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
// NOTE: 0.5.2 of color.js uses `new Number` which is corrected in future version
// assert.deepEqual(c.color.coords, [336, 100, 100]);
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 100);
- assert.equal(c.color.alpha, 1);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 100);
+ assert.equal(c._color.alpha, 1);
});
});
suite('hsba(h, s%, b%, a)', function() {
beforeEach(function() {
- c = myp5.color('hsba(336, 100%, 100%, 0.8)');
+ c = mockP5Prototype.color('hsba(336, 100%, 100%, 0.8)');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
// NOTE: 0.5.2 of color.js uses `new Number` which is corrected in future version
// assert.deepEqual(c.color.coords, [336, 100, 50]);
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 100);
- assert.equal(c.color.alpha, 0.8);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 100);
+ assert.equal(c._color.alpha, 0.8);
});
});
suite('named colors', function() {
beforeEach(function() {
- c = myp5.color('papayawhip');
+ c = mockP5Prototype.color('papayawhip');
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [255, 239, 213].map(c => c/255));
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [255, 239, 213].map(c => c/255));
+ assert.equal(c._color.alpha, 1);
});
});
@@ -255,56 +248,56 @@ suite('p5.Color', function() {
suite('p5.prototype.color([])', function() {
beforeEach(function() {
- c = myp5.color([255, 0, 102]);
+ c = mockP5Prototype.color([255, 0, 102]);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 1);
});
});
// color level setters
suite('in default mode', function() {
test('can be modified with alpha setter', function() {
- let cc = myp5.color(255, 0, 102, 204);
- assert.deepEqual(cc.color.coords, [1, 0, 0.4]);
- assert.equal(cc.color.alpha, 0.8);
- cc.setAlpha(98);
- assert.deepEqual(cc.color.coords, [1, 0, 0.4]);
- assert.equal(cc.color.alpha, 98/255);
+ let cc = mockP5Prototype.color(255, 0, 102, 204);
+ assert.deepEqual(cc._color.coords, [1, 0, 0.4]);
+ assert.equal(cc._color.alpha, 0.8);
+ cc.setAlpha(98/255);
+ assert.deepEqual(cc._color.coords, [1, 0, 0.4]);
+ assert.equal(cc._color.alpha, 98/255);
});
test('can be modified with rgb setters', function() {
- var cc = myp5.color(255, 0, 102, 204);
- assert.deepEqual(cc.color.coords, [1, 0, 0.4]);
- assert.equal(cc.color.alpha, 0.8);
- cc.setRed(98);
- assert.deepEqual(cc.color.coords, [98/255, 0, 0.4]);
- assert.equal(cc.color.alpha, 0.8);
- cc.setGreen(44);
- assert.deepEqual(cc.color.coords, [98/255, 44/255, 0.4]);
- assert.equal(cc.color.alpha, 0.8);
- cc.setBlue(244);
- assert.deepEqual(cc.color.coords, [98/255, 44/255, 244/255]);
- assert.equal(cc.color.alpha, 0.8);
+ var cc = mockP5Prototype.color(255, 0, 102, 204);
+ assert.deepEqual(cc._color.coords, [1, 0, 0.4]);
+ assert.equal(cc._color.alpha, 0.8);
+ cc.setRed(98/255);
+ assert.deepEqual(cc._color.coords, [98/255, 0, 0.4]);
+ assert.equal(cc._color.alpha, 0.8);
+ cc.setGreen(44/255);
+ assert.deepEqual(cc._color.coords, [98/255, 44/255, 0.4]);
+ assert.equal(cc._color.alpha, 0.8);
+ cc.setBlue(244/255);
+ assert.deepEqual(cc._color.coords, [98/255, 44/255, 244/255]);
+ assert.equal(cc._color.alpha, 0.8);
});
});
// Color Mode
suite('p5.Color in RGB mode with custom range', function() {
beforeEach(function() {
- myp5.colorMode(myp5.RGB, 1);
- c = myp5.color(1, 0, 0.4, 0.8);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB, 1);
+ c = mockP5Prototype.color(1, 0, 0.4, 0.8);
});
test('should correctly convert to RGBA', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly get RGBA property', function() {
@@ -319,75 +312,75 @@ suite('p5.Color', function() {
});
test('should correctly get RGBA property after overwrite', function() {
- myp5.colorMode(myp5.RGB, 255, 255, 255, 255);
- assert.equal(c._getRed(), 255);
- assert.equal(c._getGreen(), 0);
- assert.equal(c._getBlue(), 102);
- assert.equal(c._getAlpha(), 204);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB, 255, 255, 255, 255);
+ assert.equal(c._getRed(), 255/255);
+ assert.equal(c._getGreen(), 0/255);
+ assert.equal(c._getBlue(), 102/255);
+ assert.equal(c._getAlpha(), 204/255);
});
});
suite('p5.Color in HSL mode', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL);
- c = myp5.color(336, 100, 50);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL);
+ c = mockP5Prototype.color(336, 100, 50);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [336, 100, 50]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [336, 100, 50]);
+ assert.equal(c._color.alpha, 1);
});
test('can be modified with alpha setter', function() {
- let cc = myp5.color(336, 100, 50);
+ let cc = mockP5Prototype.color(336, 100, 50);
cc.setAlpha(0.73);
- assert.deepEqual(cc.color.coords, [336, 100, 50]);
- assert.equal(cc.color.alpha, 0.73);
+ assert.deepEqual(cc._color.coords, [336, 100, 50]);
+ assert.equal(cc._color.alpha, 0.73);
});
test('can be modified with rgb setters', function() {
- let cc = myp5.color(336, 100, 50);
- assert.deepEqual(cc.color.coords, [336, 100, 50]);
- assert.equal(cc.color.alpha, 1);
+ let cc = mockP5Prototype.color(336, 100, 50);
+ assert.deepEqual(cc._color.coords, [336, 100, 50]);
+ assert.equal(cc._color.alpha, 1);
// TODO: separately check these values are correct (not in test here)
- cc.setRed(98);
- assert.closeTo(cc.color.coords[0], 297, 1);
- assert.closeTo(cc.color.coords[1], 100, 1);
- assert.closeTo(cc.color.coords[2], 20, 1);
- assert.equal(cc.color.alpha, 1);
-
- cc.setGreen(44);
- assert.closeTo(cc.color.coords[0], 295, 1);
- assert.closeTo(cc.color.coords[1], 39, 1);
- assert.closeTo(cc.color.coords[2], 28, 1);
- assert.equal(cc.color.alpha, 1);
-
- cc.setBlue(244);
- assert.closeTo(cc.color.coords[0], 256, 1);
- assert.closeTo(cc.color.coords[1], 90, 1);
- assert.closeTo(cc.color.coords[2], 56, 1);
- assert.equal(cc.color.alpha, 1);
+ cc.setRed(98/255);
+ assert.closeTo(cc._color.coords[0], 297, 1);
+ assert.closeTo(cc._color.coords[1], 100, 1);
+ assert.closeTo(cc._color.coords[2], 20, 1);
+ assert.equal(cc._color.alpha, 1);
+
+ cc.setGreen(44/255);
+ assert.closeTo(cc._color.coords[0], 295, 1);
+ assert.closeTo(cc._color.coords[1], 39, 1);
+ assert.closeTo(cc._color.coords[2], 28, 1);
+ assert.equal(cc._color.alpha, 1);
+
+ cc.setBlue(244/255);
+ assert.closeTo(cc._color.coords[0], 256, 1);
+ assert.closeTo(cc._color.coords[1], 90, 1);
+ assert.closeTo(cc._color.coords[2], 56, 1);
+ assert.equal(cc._color.alpha, 1);
});
});
suite('p5.Color in HSL mode with Alpha', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL);
- c = myp5.color(336, 100, 50, 0.8);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL);
+ c = mockP5Prototype.color(336, 100, 50, 0.8);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [336, 100, 50]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [336, 100, 50]);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly get hue/saturation/lightness/alpha', function() {
@@ -400,22 +393,22 @@ suite('p5.Color', function() {
suite('p5.Color in HSL mode with custom range', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL, 100, 200, 300, 10);
- c = myp5.color(93.33, 200, 150, 8);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL, 100, 200, 300, 10);
+ c = mockP5Prototype.color(93.33, 200, 150, 8);
});
test('should correctly get HSLA property', function() {
- assert.approximately(c._getHue(), 93, 0.5);
- assert.approximately(c._getSaturation(), 200, 0.5);
- assert.approximately(c._getLightness(), 150, 0.5);
- assert.approximately(c._getAlpha(), 8, 0.5);
+ assert.approximately(c._getHue(), 336, 0.5);
+ assert.approximately(c._getSaturation(), 100, 0.5);
+ assert.approximately(c._getLightness(), 50, 0.5);
+ assert.approximately(c._getAlpha(), 0.8, 0.5);
});
test('should correctly convert to RGBA', function() {
- assert.closeTo(c.color.coords[0], 336, 1);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 50);
- assert.equal(c.color.alpha, 0.8);
+ assert.closeTo(c._color.coords[0], 336, 1);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 50);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -423,46 +416,46 @@ suite('p5.Color', function() {
});
test('can be modified with alpha setter', function() {
- let cc = myp5.color(93.33, 200, 150, 8);
- cc.setAlpha(7.3);
- assert.closeTo(cc.color.coords[0], 336, 1);
- assert.equal(cc.color.coords[1], 100);
- assert.equal(cc.color.coords[2], 50);
- assert.equal(cc.color.alpha, 0.73);
+ let cc = mockP5Prototype.color(93.33, 200, 150, 8);
+ cc.setAlpha(0.73);
+ assert.closeTo(cc._color.coords[0], 336, 1);
+ assert.equal(cc._color.coords[1], 100);
+ assert.equal(cc._color.coords[2], 50);
+ assert.equal(cc._color.alpha, 0.73);
});
test('can be modified with rgb setters', function() {
- let cc = myp5.color(93.33, 200, 150, 8);
- assert.closeTo(c.color.coords[0], 336, 1);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 50);
- assert.equal(c.color.alpha, 0.8);
-
- cc.setRed(98);
- assert.closeTo(cc.color.coords[0], 297, 1);
- assert.closeTo(cc.color.coords[1], 100, 1);
- assert.closeTo(cc.color.coords[2], 20, 1);
- assert.equal(cc.color.alpha, 0.8);
-
- cc.setGreen(44);
- assert.closeTo(cc.color.coords[0], 295, 1);
- assert.closeTo(cc.color.coords[1], 39, 1);
- assert.closeTo(cc.color.coords[2], 28, 1);
- assert.equal(cc.color.alpha, 0.8);
-
- cc.setBlue(244);
- assert.closeTo(cc.color.coords[0], 256, 1);
- assert.closeTo(cc.color.coords[1], 90, 1);
- assert.closeTo(cc.color.coords[2], 56, 1);
- assert.equal(cc.color.alpha, 0.8);
+ let cc = mockP5Prototype.color(93.33, 200, 150, 8);
+ assert.closeTo(c._color.coords[0], 336, 1);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 50);
+ assert.equal(c._color.alpha, 0.8);
+
+ cc.setRed(98/255);
+ assert.closeTo(cc._color.coords[0], 297, 1);
+ assert.closeTo(cc._color.coords[1], 100, 1);
+ assert.closeTo(cc._color.coords[2], 20, 1);
+ assert.equal(cc._color.alpha, 0.8);
+
+ cc.setGreen(44/255);
+ assert.closeTo(cc._color.coords[0], 295, 1);
+ assert.closeTo(cc._color.coords[1], 39, 1);
+ assert.closeTo(cc._color.coords[2], 28, 1);
+ assert.equal(cc._color.alpha, 0.8);
+
+ cc.setBlue(244/255);
+ assert.closeTo(cc._color.coords[0], 256, 1);
+ assert.closeTo(cc._color.coords[1], 90, 1);
+ assert.closeTo(cc._color.coords[2], 56, 1);
+ assert.equal(cc._color.alpha, 0.8);
});
});
suite('p5.Color in HSL mode with RGB string', function() {
// NOTE: will still create a sRGB color in this case
beforeEach(function() {
- myp5.colorMode(myp5.HSL, 360, 100, 100, 1);
- c = myp5.color('rgba(255, 0, 102, 0.8)');
+ mockP5Prototype.colorMode(mockP5Prototype.HSL, 360, 100, 100, 1);
+ c = mockP5Prototype.color('rgba(255, 0, 102, 0.8)');
});
test.todo('should correctly get HSLA property', function() {
@@ -473,8 +466,8 @@ suite('p5.Color', function() {
});
test('should correctly convert to RGBA', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -484,8 +477,8 @@ suite('p5.Color', function() {
suite('p5.Color in HSL mode with HSL string', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL, 360, 100, 100, 1);
- c = myp5.color('hsla(336, 100%, 50%, 0.8)');
+ mockP5Prototype.colorMode(mockP5Prototype.HSL, 360, 100, 100, 1);
+ c = mockP5Prototype.color('hsla(336, 100%, 50%, 0.8)');
});
test.todo('should correctly get HSLA property', function() {
@@ -498,10 +491,10 @@ suite('p5.Color', function() {
test('should correctly convert to RGBA', function() {
// NOTE: 0.5.2 of color.js uses `new Number` which is corrected in future version
// assert.deepEqual(c.color.coords, [336, 100, 50]);
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 50);
- assert.equal(c.color.alpha, 0.8);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 50);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -511,8 +504,8 @@ suite('p5.Color', function() {
suite('p5.Color in HSL mode with HSB string', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL, 360, 100, 100, 1);
- c = myp5.color('hsba(336, 100%, 100%, 0.8)');
+ mockP5Prototype.colorMode(mockP5Prototype.HSL, 360, 100, 100, 1);
+ c = mockP5Prototype.color('hsba(336, 100%, 100%, 0.8)');
});
test.todo('should correctly get HSLA property', function() {
@@ -525,10 +518,10 @@ suite('p5.Color', function() {
test('should correctly convert to RGBA', function() {
// NOTE: 0.5.2 of color.js uses `new Number` which is corrected in future version
// assert.deepEqual(c.color.coords, [336, 100, 50]);
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 100);
- assert.equal(c.color.alpha, 0.8);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 100);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -538,62 +531,62 @@ suite('p5.Color', function() {
suite('p5.Color in HSB mode', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB);
- c = myp5.color(336, 100, 100);
+ mockP5Prototype.colorMode(mockP5Prototype.HSB);
+ c = mockP5Prototype.color(336, 100, 100);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [336, 100, 100]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [336, 100, 100]);
+ assert.equal(c._color.alpha, 1);
});
test('can be modified with alpha setter', function() {
- var cc = myp5.color(336, 100, 100);
+ var cc = mockP5Prototype.color(336, 100, 100);
cc.setAlpha(0.73);
- assert.deepEqual(cc.color.coords, [336, 100, 100]);
- assert.equal(cc.color.alpha, 0.73);
+ assert.deepEqual(cc._color.coords, [336, 100, 100]);
+ assert.equal(cc._color.alpha, 0.73);
});
test('can be modified with rgb setters', function() {
- var cc = myp5.color(336, 100, 100);
- assert.deepEqual(cc.color.coords, [336, 100, 100]);
- assert.equal(cc.color.alpha, 1);
-
- cc.setRed(98);
- assert.closeTo(cc.color.coords[0], 297, 1);
- assert.closeTo(cc.color.coords[1], 100, 1);
- assert.closeTo(cc.color.coords[2], 40, 1);
- assert.equal(cc.color.alpha, 1);
-
- cc.setGreen(44);
- assert.closeTo(cc.color.coords[0], 295, 1);
- assert.closeTo(cc.color.coords[1], 56, 1);
- assert.closeTo(cc.color.coords[2], 40, 1);
- assert.equal(cc.color.alpha, 1);
-
- cc.setBlue(244);
- assert.closeTo(cc.color.coords[0], 256, 1);
- assert.closeTo(cc.color.coords[1], 81, 1);
- assert.closeTo(cc.color.coords[2], 95, 1);
- assert.equal(cc.color.alpha, 1);
+ var cc = mockP5Prototype.color(336, 100, 100);
+ assert.deepEqual(cc._color.coords, [336, 100, 100]);
+ assert.equal(cc._color.alpha, 1);
+
+ cc.setRed(98/255);
+ assert.closeTo(cc._color.coords[0], 297, 1);
+ assert.closeTo(cc._color.coords[1], 100, 1);
+ assert.closeTo(cc._color.coords[2], 40, 1);
+ assert.equal(cc._color.alpha, 1);
+
+ cc.setGreen(44/255);
+ assert.closeTo(cc._color.coords[0], 295, 1);
+ assert.closeTo(cc._color.coords[1], 56, 1);
+ assert.closeTo(cc._color.coords[2], 40, 1);
+ assert.equal(cc._color.alpha, 1);
+
+ cc.setBlue(244/255);
+ assert.closeTo(cc._color.coords[0], 256, 1);
+ assert.closeTo(cc._color.coords[1], 81, 1);
+ assert.closeTo(cc._color.coords[2], 95, 1);
+ assert.equal(cc._color.alpha, 1);
});
});
suite('p5.Color in HSB mode with Alpha', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB);
- c = myp5.color(336, 100, 100, 0.8);
+ mockP5Prototype.colorMode(mockP5Prototype.HSB);
+ c = mockP5Prototype.color(336, 100, 100, 0.8);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGBA property', function() {
- assert.deepEqual(c.color.coords, [336, 100, 100]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [336, 100, 100]);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly get hue/saturation/brightness/alpha', function() {
@@ -606,22 +599,22 @@ suite('p5.Color', function() {
suite('p5.Color in HSB mode with custom range', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB, 100, 200, 300, 10);
- c = myp5.color(93.33, 200, 300, 8);
+ mockP5Prototype.colorMode(mockP5Prototype.HSB, 100, 200, 300, 10);
+ c = mockP5Prototype.color(93.33, 200, 300, 8);
});
test('should correctly get HSBA property', function() {
- assert.approximately(c._getHue(), 93, 0.5);
- assert.approximately(c._getSaturation(), 200, 0.5);
- assert.approximately(c._getBrightness(), 300, 0.5);
- assert.approximately(c._getAlpha(), 8, 0.5);
+ assert.approximately(c._getHue(), 336, 0.5);
+ assert.approximately(c._getSaturation(), 100, 0.5);
+ assert.approximately(c._getBrightness(), 100, 0.5);
+ assert.approximately(c._getAlpha(), 0.8, 0.5);
});
test('should correctly convert to RGBA', function() {
- assert.closeTo(c.color.coords[0], 336, 1);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 100);
- assert.equal(c.color.alpha, 0.8);
+ assert.closeTo(c._color.coords[0], 336, 1);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 100);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -631,8 +624,8 @@ suite('p5.Color', function() {
suite('p5.Color in HSB mode with RGB string', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB, 360, 100, 100, 1);
- c = myp5.color('rgba(255, 0, 102, 0.8)');
+ mockP5Prototype.colorMode(mockP5Prototype.HSB, 360, 100, 100, 1);
+ c = mockP5Prototype.color('rgba(255, 0, 102, 0.8)');
});
test.todo('should correctly get HSBA property', function() {
@@ -643,8 +636,8 @@ suite('p5.Color', function() {
});
test('should correctly convert to RGBA', function() {
- assert.deepEqual(c.color.coords, [1, 0, 0.4]);
- assert.equal(c.color.alpha, 0.8);
+ assert.deepEqual(c._color.coords, [1, 0, 0.4]);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -654,8 +647,8 @@ suite('p5.Color', function() {
suite('p5.Color in HSB mode with HSB string', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB, 360, 100, 100, 1);
- c = myp5.color('hsba(336, 100%, 100%, 0.8)');
+ mockP5Prototype.colorMode(mockP5Prototype.HSB, 360, 100, 100, 1);
+ c = mockP5Prototype.color('hsba(336, 100%, 100%, 0.8)');
});
test('should correctly get HSBA property', function() {
@@ -666,10 +659,10 @@ suite('p5.Color', function() {
});
test('should correctly convert to RGBA', function() {
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 100);
- assert.equal(c.color.alpha, 0.8);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 100);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -679,8 +672,8 @@ suite('p5.Color', function() {
suite('p5.Color in HSB mode with HSL string', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB, 360, 100, 100, 1);
- c = myp5.color('hsla(336, 100%, 50%, 0.8)');
+ mockP5Prototype.colorMode(mockP5Prototype.HSB, 360, 100, 100, 1);
+ c = mockP5Prototype.color('hsla(336, 100%, 50%, 0.8)');
});
test.todo('should correctly get HSBA property', function() {
@@ -691,10 +684,10 @@ suite('p5.Color', function() {
});
test('should correctly convert to RGBA', function() {
- assert.equal(+c.color.coords[0], 336);
- assert.equal(c.color.coords[1], 100);
- assert.equal(c.color.coords[2], 50);
- assert.equal(c.color.alpha, 0.8);
+ assert.equal(+c._color.coords[0], 336);
+ assert.equal(c._color.coords[1], 100);
+ assert.equal(c._color.coords[2], 50);
+ assert.equal(c._color.alpha, 0.8);
});
test('should correctly render color string', function() {
@@ -704,97 +697,97 @@ suite('p5.Color', function() {
suite('p5.Color in RGB mode with grayscale value', function() {
beforeEach(function() {
- myp5.colorMode(myp5.RGB);
- c = myp5.color(100);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB);
+ c = mockP5Prototype.color(100);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGB levels', function() {
- assert.deepEqual(c.color.coords, [100/255, 100/255, 100/255]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [100/255, 100/255, 100/255]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('p5.Color in RGB mode with grayscale value and alpha', function() {
beforeEach(function() {
- myp5.colorMode(myp5.RGB);
- c = myp5.color(100, 70);
+ mockP5Prototype.colorMode(mockP5Prototype.RGB);
+ c = mockP5Prototype.color(100, 70);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGB levels', function() {
- assert.deepEqual(c.color.coords, [100/255, 100/255, 100/255]);
- assert.equal(c.color.alpha, 70/255);
+ assert.deepEqual(c._color.coords, [100/255, 100/255, 100/255]);
+ assert.equal(c._color.alpha, 70/255);
});
});
suite('p5.Color in HSB mode with grayscale value', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB);
- c = myp5.color(39.3);
+ mockP5Prototype.colorMode(mockP5Prototype.HSB);
+ c = mockP5Prototype.color(39.3);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGB levels', function() {
- assert.deepEqual(c.color.coords, [39.3, 39.3, 39.3]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('p5.Color in HSB mode with grayscale value and alpha', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSB);
- c = myp5.color(39.3, 0.275);
+ mockP5Prototype.colorMode(mockP5Prototype.HSB);
+ c = mockP5Prototype.color(39.3, 0.275);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGB levels', function() {
- assert.deepEqual(c.color.coords, [39.3, 39.3, 39.3]);
- assert.equal(c.color.alpha, 0.275);
+ assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
+ assert.equal(c._color.alpha, 0.275);
});
});
suite('p5.Color in HSL mode with grayscale value', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL);
- c = myp5.color(39.3);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL);
+ c = mockP5Prototype.color(39.3);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGB levels', function() {
- assert.deepEqual(c.color.coords, [39.3, 39.3, 39.3]);
- assert.equal(c.color.alpha, 1);
+ assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
+ assert.equal(c._color.alpha, 1);
});
});
suite('p5.Color in HSL mode with grayscale value and alpha', function() {
beforeEach(function() {
- myp5.colorMode(myp5.HSL);
- c = myp5.color(39.3, 0.275);
+ mockP5Prototype.colorMode(mockP5Prototype.HSL);
+ c = mockP5Prototype.color(39.3, 0.275);
});
test('should create instance of p5.Color', function() {
- assert.instanceOf(c, p5.Color);
+ assert.instanceOf(c, Color);
});
test('should correctly set RGB levels', function() {
- assert.deepEqual(c.color.coords, [39.3, 39.3, 39.3]);
- assert.equal(c.color.alpha, 0.275);
+ assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
+ assert.equal(c._color.alpha, 0.275);
});
});
@@ -802,8 +795,8 @@ suite('p5.Color', function() {
// var colorStr;
// beforeEach(function() {
- // myp5.colorMode(myp5.RGB, 255, 255, 255, 255);
- // c = myp5.color(128, 0, 128, 128);
+ // mockP5Prototype.colorMode(mockP5Prototype.RGB, 255, 255, 255, 255);
+ // c = mockP5Prototype.color(128, 0, 128, 128);
// colorStr = c.toString();
// });
diff --git a/test/unit/color/setting.js b/test/unit/color/setting.js
index 6bf5dbcfc6..12a44f195d 100644
--- a/test/unit/color/setting.js
+++ b/test/unit/color/setting.js
@@ -1,10 +1,32 @@
import p5 from '../../../src/app.js';
+import { vi } from 'vitest';
+import { mockP5, mockP5Prototype } from '../../js/mocks';
+import creatingReading from '../../../src/color/creating_reading';
+import setting from '../../../src/color/setting';
+
// NOTE: Require ESM compatible libtess
suite('color/Setting', function() {
let myp5; // sketch without WEBGL Mode
let my3D; // sketch with WEBGL mode
+ beforeAll(() => {
+ creatingReading(mockP5, mockP5Prototype);
+ setting(mockP5, mockP5Prototype);
+ // mockP5Prototype.states = {
+ // colorMode: 'rgb',
+ // colorMaxes: {
+ // rgb: [255, 255, 255, 255],
+ // hsb: [360, 100, 100, 1],
+ // hsl: [360, 100, 100, 1]
+ // }
+ // }
+ });
+
+ afterAll(() => {
+ delete mockP5Prototype._colorMaxes;
+ });
+
beforeEach(async function() {
await new Promise(resolve => {
new p5(function(p) {
@@ -32,15 +54,35 @@ suite('color/Setting', function() {
});
suite('p5.prototype.erase', function() {
+ beforeEach(() => {
+ mockP5Prototype._renderer = {
+ erase: vi.fn(),
+ states: {
+ colorMode: 'rgb',
+ colorMaxes: {
+ rgb: [255, 255, 255, 255],
+ hsb: [360, 100, 100, 1],
+ hsl: [360, 100, 100, 1]
+ }
+ }
+ }
+ });
+
+ afterEach(() => {
+ vi.resetAllMocks();
+ });
+
test('should be a function', function() {
- assert.ok(myp5.erase);
+ assert.ok(mockP5Prototype.erase);
});
- test('should set renderer to erasing state', function() {
- myp5.erase();
- assert.isTrue(myp5._renderer._isErasing);
+ test('should call the renderer erase method with default arguments', function() {
+ mockP5Prototype.erase();
+ expect(mockP5Prototype._renderer.erase).toHaveBeenCalledWith(255, 255);
});
+ // TODO: test in renderer
+ test.todo('should set renderer to erasing state');
test.todo('should cache renderer fill', function() {
myp5.fill(255, 0, 0);
const fillStyle = myp5.drawingContext.fillStyle;
@@ -55,13 +97,13 @@ suite('color/Setting', function() {
assert.deepEqual(myp5._renderer._cachedStrokeStyle, strokeStyle);
});
- test('should cache renderer blend', function() {
+ test.todo('should cache renderer blend', function() {
myp5.blendMode(myp5.SCREEN);
myp5.erase();
assert.deepEqual(myp5._renderer._cachedBlendMode, myp5.SCREEN);
});
- test('should set fill strength', function() {
+ test.todo('should set fill strength', function() {
myp5.erase(125);
assert.equal(
myp5.color(myp5.drawingContext.fillStyle).array,
@@ -69,7 +111,7 @@ suite('color/Setting', function() {
);
});
- test('should set stroke strength', function() {
+ test.todo('should set stroke strength', function() {
myp5.erase(255, 50);
assert.equal(
myp5.color(myp5.drawingContext.strokeStyle).array,
@@ -123,7 +165,7 @@ suite('color/Setting', function() {
suite('p5.prototype.noErase', function() {
test('should be a function', function() {
- assert.ok(myp5.noErase);
+ assert.ok(mockP5Prototype.noErase);
});
test('should turn off renderer erasing state', function() {
@@ -175,123 +217,123 @@ suite('color/Setting', function() {
suite('p5.prototype.colorMode', function() {
test('should be a function', function() {
- assert.ok(myp5.colorMode);
+ assert.ok(mockP5Prototype.colorMode);
});
test('should set mode to RGB', function() {
- myp5.colorMode(myp5.RGB);
- assert.equal(myp5._colorMode, myp5.RGB);
+ mockP5Prototype.colorMode('rgb');
+ assert.equal(mockP5Prototype._renderer.states.colorMode, 'rgb');
});
test('should correctly set color RGB maxes', function() {
- assert.deepEqual(myp5._colorMaxes[myp5.RGB], [255, 255, 255, 255]);
- myp5.colorMode(myp5.RGB, 1, 1, 1);
- assert.deepEqual(myp5._colorMaxes[myp5.RGB], [1, 1, 1, 255]);
- myp5.colorMode(myp5.RGB, 1);
- assert.deepEqual(myp5._colorMaxes[myp5.RGB], [1, 1, 1, 1]);
- myp5.colorMode(myp5.RGB, 255, 255, 255, 1);
- assert.deepEqual(myp5._colorMaxes[myp5.RGB], [255, 255, 255, 1]);
- myp5.colorMode(myp5.RGB, 255);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['rgb'], [255, 255, 255, 255]);
+ mockP5Prototype.colorMode('rgb', 1, 1, 1);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['rgb'], [1, 1, 1, 255]);
+ mockP5Prototype.colorMode('rgb', 1);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['rgb'], [1, 1, 1, 1]);
+ mockP5Prototype.colorMode('rgb', 255, 255, 255, 1);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['rgb'], [255, 255, 255, 1]);
+ mockP5Prototype.colorMode('rgb', 255);
});
test('should set mode to HSL', function() {
- myp5.colorMode(myp5.HSL);
- assert.equal(myp5._colorMode, myp5.HSL);
+ mockP5Prototype.colorMode('hsl');
+ assert.equal(mockP5Prototype._renderer.states.colorMode, 'hsl');
});
test('should correctly set color HSL maxes', function() {
- assert.deepEqual(myp5._colorMaxes[myp5.HSL], [360, 100, 100, 1]);
- myp5.colorMode(myp5.HSL, 255, 255, 255);
- assert.deepEqual(myp5._colorMaxes[myp5.HSL], [255, 255, 255, 1]);
- myp5.colorMode(myp5.HSL, 360);
- assert.deepEqual(myp5._colorMaxes[myp5.HSL], [360, 360, 360, 360]);
- myp5.colorMode(myp5.HSL, 360, 100, 100, 1);
- assert.deepEqual(myp5._colorMaxes[myp5.HSL], [360, 100, 100, 1]);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsl'], [360, 100, 100, 1]);
+ mockP5Prototype.colorMode('hsl', 255, 255, 255);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsl'], [255, 255, 255, 1]);
+ mockP5Prototype.colorMode('hsl', 360);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsl'], [360, 360, 360, 360]);
+ mockP5Prototype.colorMode('hsl', 360, 100, 100, 1);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsl'], [360, 100, 100, 1]);
});
test('should set mode to HSB', function() {
- myp5.colorMode(myp5.HSB);
- assert.equal(myp5._colorMode, myp5.HSB);
+ mockP5Prototype.colorMode('hsb');
+ assert.equal(mockP5Prototype._renderer.states.colorMode, 'hsb');
});
test('should correctly set color HSB maxes', function() {
- assert.deepEqual(myp5._colorMaxes[myp5.HSB], [360, 100, 100, 1]);
- myp5.colorMode(myp5.HSB, 255, 255, 255);
- assert.deepEqual(myp5._colorMaxes[myp5.HSB], [255, 255, 255, 1]);
- myp5.colorMode(myp5.HSB, 360);
- assert.deepEqual(myp5._colorMaxes[myp5.HSB], [360, 360, 360, 360]);
- myp5.colorMode(myp5.HSB, 360, 100, 100, 1);
- assert.deepEqual(myp5._colorMaxes[myp5.HSB], [360, 100, 100, 1]);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsb'], [360, 100, 100, 1]);
+ mockP5Prototype.colorMode('hsb', 255, 255, 255);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsb'], [255, 255, 255, 1]);
+ mockP5Prototype.colorMode('hsb', 360);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsb'], [360, 360, 360, 360]);
+ mockP5Prototype.colorMode('hsb', 360, 100, 100, 1);
+ assert.deepEqual(mockP5Prototype._renderer.states.colorMaxes['hsb'], [360, 100, 100, 1]);
});
});
suite('p5.Color components', function() {
test('setRed() correctly sets red component', function() {
- myp5.colorMode(myp5.RGB, 255);
- const c = myp5.color(0, 162, 205, 255);
+ mockP5Prototype.colorMode('rgb', 255);
+ const c = mockP5Prototype.color(0, 162, 205, 255);
c.setRed(100);
- assert.equal(myp5.red(c), 100);
- assert.equal(myp5.green(c), 162);
- assert.equal(myp5.blue(c), 205);
- assert.equal(myp5.alpha(c), 255);
+ assert.equal(mockP5Prototype.red(c), 100);
+ assert.equal(mockP5Prototype.green(c), 162);
+ assert.equal(mockP5Prototype.blue(c), 205);
+ assert.equal(mockP5Prototype.alpha(c), 255);
});
test('setGreen() correctly sets green component', function() {
- myp5.colorMode(myp5.RGB, 255);
- const c = myp5.color(0, 162, 205, 255);
+ mockP5Prototype.colorMode('rgb', 255);
+ const c = mockP5Prototype.color(0, 162, 205, 255);
c.setGreen(100);
- assert.equal(myp5.red(c), 0);
- assert.equal(myp5.green(c), 100);
- assert.equal(myp5.blue(c), 205);
- assert.equal(myp5.alpha(c), 255);
+ assert.equal(mockP5Prototype.red(c), 0);
+ assert.equal(mockP5Prototype.green(c), 100);
+ assert.equal(mockP5Prototype.blue(c), 205);
+ assert.equal(mockP5Prototype.alpha(c), 255);
});
test('setBlue() correctly sets blue component', function() {
- myp5.colorMode(myp5.RGB, 255);
- const c = myp5.color(0, 162, 205, 255);
+ mockP5Prototype.colorMode('rgb', 255);
+ const c = mockP5Prototype.color(0, 162, 205, 255);
c.setBlue(100);
- assert.equal(myp5.red(c), 0);
- assert.equal(myp5.green(c), 162);
- assert.equal(myp5.blue(c), 100);
- assert.equal(myp5.alpha(c), 255);
+ assert.equal(mockP5Prototype.red(c), 0);
+ assert.equal(mockP5Prototype.green(c), 162);
+ assert.equal(mockP5Prototype.blue(c), 100);
+ assert.equal(mockP5Prototype.alpha(c), 255);
});
test('setAlpha correctly sets alpha component', function() {
- myp5.colorMode(myp5.RGB, 255);
- const c = myp5.color(0, 162, 205, 255);
+ mockP5Prototype.colorMode('rgb', 255);
+ const c = mockP5Prototype.color(0, 162, 205, 255);
c.setAlpha(100);
- assert.equal(myp5.red(c), 0);
- assert.equal(myp5.green(c), 162);
- assert.equal(myp5.blue(c), 205);
- assert.equal(myp5.alpha(c), 100);
+ assert.equal(mockP5Prototype.red(c), 0);
+ assert.equal(mockP5Prototype.green(c), 162);
+ assert.equal(mockP5Prototype.blue(c), 205);
+ assert.equal(mockP5Prototype.alpha(c), 100);
});
test('changing the red/green/blue/alpha components should clear the cached HSL/HSB values', function() {
- myp5.colorMode(myp5.RGB, 255);
- const c = myp5.color(0, 162, 205, 255);
+ mockP5Prototype.colorMode('rgb', 255);
+ const c = mockP5Prototype.color(0, 162, 205, 255);
// create HSL/HSB values
- myp5.lightness(c);
- myp5.brightness(c);
- c.setRed(100);
+ mockP5Prototype.lightness(c);
+ mockP5Prototype.brightness(c);
+ c.setRed(100/255);
assert(!c.hsba);
assert(!c.hsla);
- myp5.lightness(c);
- myp5.brightness(c);
- c.setGreen(100);
+ mockP5Prototype.lightness(c);
+ mockP5Prototype.brightness(c);
+ c.setGreen(100/255);
assert(!c.hsba);
assert(!c.hsla);
- myp5.lightness(c);
- myp5.brightness(c);
- c.setBlue(100);
+ mockP5Prototype.lightness(c);
+ mockP5Prototype.brightness(c);
+ c.setBlue(100/255);
assert(!c.hsba);
assert(!c.hsla);
- myp5.lightness(c);
- myp5.brightness(c);
- c.setAlpha(100);
+ mockP5Prototype.lightness(c);
+ mockP5Prototype.brightness(c);
+ c.setAlpha(100/255);
assert(!c.hsba);
assert(!c.hsla);
});
diff --git a/test/unit/core/rendering.js b/test/unit/core/rendering.js
index 9f0fa44762..47b2fc2240 100644
--- a/test/unit/core/rendering.js
+++ b/test/unit/core/rendering.js
@@ -25,21 +25,21 @@ suite('Rendering', function() {
suite('p5.prototype.createCanvas', function() {
test('should have correct initial colors', function() {
- var white = myp5.color(255, 255, 255).levels;
- var black = myp5.color(0, 0, 0).levels;
- assert.deepEqual(myp5.color(myp5._renderer._getFill()).levels, white);
- assert.deepEqual(myp5.color(myp5._renderer._getStroke()).levels, black);
- assert.deepEqual(myp5.color(myp5.drawingContext.fillStyle).levels, white);
+ var white = myp5.color(255, 255, 255)._array;
+ var black = myp5.color(0, 0, 0)._array;
+ assert.deepEqual(myp5.color(myp5._renderer._getFill())._array, white);
+ assert.deepEqual(myp5.color(myp5._renderer._getStroke())._array, black);
+ assert.deepEqual(myp5.color(myp5.drawingContext.fillStyle)._array, white);
assert.deepEqual(
- myp5.color(myp5.drawingContext.strokeStyle).levels,
+ myp5.color(myp5.drawingContext.strokeStyle)._array,
black
);
myp5.createCanvas(100, 100);
- assert.deepEqual(myp5.color(myp5._renderer._getFill()).levels, white);
- assert.deepEqual(myp5.color(myp5._renderer._getStroke()).levels, black);
- assert.deepEqual(myp5.color(myp5.drawingContext.fillStyle).levels, white);
+ assert.deepEqual(myp5.color(myp5._renderer._getFill())._array, white);
+ assert.deepEqual(myp5.color(myp5._renderer._getStroke())._array, black);
+ assert.deepEqual(myp5.color(myp5.drawingContext.fillStyle)._array, white);
assert.deepEqual(
- myp5.color(myp5.drawingContext.strokeStyle).levels,
+ myp5.color(myp5.drawingContext.strokeStyle)._array,
black
);
});
diff --git a/test/unit/data/local_storage.js b/test/unit/data/local_storage.js
index 75a9f94da0..6c8719c777 100644
--- a/test/unit/data/local_storage.js
+++ b/test/unit/data/local_storage.js
@@ -17,7 +17,7 @@ suite('local storage', function() {
beforeAll(function() {
storage(mockP5, mockP5Prototype);
- p5Color(mockP5, mockP5Prototype);
+ p5Color(mockP5, mockP5Prototype, {});
creatingReading(mockP5, mockP5Prototype);
p5Vector(mockP5, mockP5Prototype);
math(mockP5, mockP5Prototype);
diff --git a/test/unit/dom/dom.js b/test/unit/dom/dom.js
index 96c1a7ec81..e6a8df86ab 100644
--- a/test/unit/dom/dom.js
+++ b/test/unit/dom/dom.js
@@ -10,7 +10,7 @@ suite('DOM', function() {
beforeAll(() => {
dom(mockP5, mockP5Prototype);
creatingReading(mockP5, mockP5Prototype);
- p5Color(mockP5, mockP5Prototype);
+ p5Color(mockP5, mockP5Prototype, {});
});
// Selectors
diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js
index b857e1f904..b3abec9cd4 100644
--- a/test/unit/webgl/p5.RendererGL.js
+++ b/test/unit/webgl/p5.RendererGL.js
@@ -1316,7 +1316,7 @@ suite('p5.RendererGL', function() {
);
};
- for (const alpha of [255, 200]) {
+ for (const alpha of [1, 200/255]) {
const red = myp5.color('#F53');
const blue = myp5.color('#13F');
red.setAlpha(alpha);