UNPKG

p5

Version:

[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)

1,897 lines (1,865 loc) 63.4 kB
import { N as NORMAL, u as BLEND } from '../constants-BRcElHU3.js'; import { R as RGB, b as RGBHDR, H as HSB, d as HSL, e as HWB, L as LAB, f as LCH, O as OKLAB, g as OKLCH } from '../creating_reading-Cr8L2Jnm.js'; import 'colorjs.io/fn'; import './color_spaces/hsb.js'; /** * @module Color * @submodule Setting * @for p5 * @requires core * @requires constants */ function setting(p5, fn){ /** * Starts defining a shape that will mask any shapes drawn afterward. * * Any shapes drawn between `beginClip()` and * <a href="#/p5/endClip">endClip()</a> will add to the mask shape. The mask * will apply to anything drawn after <a href="#/p5/endClip">endClip()</a>. * * The parameter, `options`, is optional. If an object with an `invert` * property is passed, as in `beginClip({ invert: true })`, it will be used to * set the masking mode. `{ invert: true }` inverts the mask, creating holes * in shapes that are masked. `invert` is `false` by default. * * Masks can be contained between the * <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a> functions. * Doing so allows unmasked shapes to be drawn after masked shapes. * * Masks can also be defined in a callback function that's passed to * <a href="#/p5/clip">clip()</a>. * * @method beginClip * @param {Object} [options] an object containing clip settings. * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Create a mask. * beginClip(); * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * endClip(); * * // Draw a backing shape. * square(5, 5, 45); * * describe('A white triangle and circle on a gray background.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Create an inverted mask. * beginClip({ invert: true }); * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * endClip(); * * // Draw a backing shape. * square(5, 5, 45); * * describe('A white square at the top-left corner of a gray square. The white square has a triangle and a circle cut out of it.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * noStroke(); * * // Draw a masked shape. * push(); * // Create a mask. * beginClip(); * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * endClip(); * * // Draw a backing shape. * square(5, 5, 45); * pop(); * * // Translate the origin to the center. * translate(50, 50); * * // Draw an inverted masked shape. * push(); * // Create an inverted mask. * beginClip({ invert: true }); * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * endClip(); * * // Draw a backing shape. * square(5, 5, 45); * pop(); * * describe('In the top left, a white triangle and circle. In the bottom right, a white square with a triangle and circle cut out of it.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe('A silhouette of a rotating torus colored fuchsia.'); * } * * function draw() { * background(200); * * // Create a mask. * beginClip(); * push(); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * scale(0.5); * torus(30, 15); * pop(); * endClip(); * * // Draw a backing shape. * noStroke(); * fill('fuchsia'); * plane(100); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe('A silhouette of a rotating torus colored with a gradient from cyan to purple.'); * } * * function draw() { * background(200); * * // Create a mask. * beginClip(); * push(); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * scale(0.5); * torus(30, 15); * pop(); * endClip(); * * // Draw a backing shape. * noStroke(); * beginShape(QUAD_STRIP); * fill(0, 255, 255); * vertex(-width / 2, -height / 2); * vertex(width / 2, -height / 2); * fill(100, 0, 100); * vertex(-width / 2, height / 2); * vertex(width / 2, height / 2); * endShape(); * } * </code> * </div> */ fn.beginClip = function(options = {}) { this._renderer.beginClip(options); }; /** * Ends defining a mask that was started with * <a href="#/p5/beginClip">beginClip()</a>. * * @method endClip * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Create a mask. * beginClip(); * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * endClip(); * * // Draw a backing shape. * square(5, 5, 45); * * describe('A white triangle and circle on a gray background.'); * } * </code> * </div> */ fn.endClip = function() { this._renderer.endClip(); }; /** * Defines a shape that will mask any shapes drawn afterward. * * The first parameter, `callback`, is a function that defines the mask. * Any shapes drawn in `callback` will add to the mask shape. The mask * will apply to anything drawn after `clip()` is called. * * The second parameter, `options`, is optional. If an object with an `invert` * property is passed, as in `beginClip({ invert: true })`, it will be used to * set the masking mode. `{ invert: true }` inverts the mask, creating holes * in shapes that are masked. `invert` is `false` by default. * * Masks can be contained between the * <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a> functions. * Doing so allows unmasked shapes to be drawn after masked shapes. * * Masks can also be defined with <a href="#/p5/beginClip">beginClip()</a> * and <a href="#/p5/endClip">endClip()</a>. * * @method clip * @param {Function} callback a function that draws the mask shape. * @param {Object} [options] an object containing clip settings. * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Create a mask. * clip(mask); * * // Draw a backing shape. * square(5, 5, 45); * * describe('A white triangle and circle on a gray background.'); * } * * // Declare a function that defines the mask. * function mask() { * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Create an inverted mask. * clip(mask, { invert: true }); * * // Draw a backing shape. * square(5, 5, 45); * * describe('A white square at the top-left corner of a gray square. The white square has a triangle and a circle cut out of it.'); * } * * // Declare a function that defines the mask. * function mask() { * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * noStroke(); * * // Draw a masked shape. * push(); * // Create a mask. * clip(mask); * * // Draw a backing shape. * square(5, 5, 45); * pop(); * * // Translate the origin to the center. * translate(50, 50); * * // Draw an inverted masked shape. * push(); * // Create an inverted mask. * clip(mask, { invert: true }); * * // Draw a backing shape. * square(5, 5, 45); * pop(); * * describe('In the top left, a white triangle and circle. In the bottom right, a white square with a triangle and circle cut out of it.'); * } * * // Declare a function that defines the mask. * function mask() { * triangle(15, 37, 30, 13, 43, 37); * circle(45, 45, 7); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe('A silhouette of a rotating torus colored fuchsia.'); * } * * function draw() { * background(200); * * // Create a mask. * clip(mask); * * // Draw a backing shape. * noStroke(); * fill('fuchsia'); * plane(100); * } * * // Declare a function that defines the mask. * function mask() { * push(); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * scale(0.5); * torus(30, 15); * pop(); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe('A silhouette of a rotating torus colored with a gradient from cyan to purple.'); * } * * function draw() { * background(200); * * // Create a mask. * clip(mask); * * // Draw a backing shape. * noStroke(); * beginShape(QUAD_STRIP); * fill(0, 255, 255); * vertex(-width / 2, -height / 2); * vertex(width / 2, -height / 2); * fill(100, 0, 100); * vertex(-width / 2, height / 2); * vertex(width / 2, height / 2); * endShape(); * } * * // Declare a function that defines the mask. * function mask() { * push(); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * scale(0.5); * torus(30, 15); * pop(); * } * </code> * </div> */ fn.clip = function(callback, options) { this._renderer.beginClip(options); callback(); this._renderer.endClip(options); }; /** * Sets the color used for the background of the canvas. * * By default, the background is transparent. `background()` is typically used * within <a href="#/p5/draw">draw()</a> to clear the display window at the * beginning of each frame. It can also be used inside * <a href="#/p5/setup">setup()</a> to set the background on the first frame * of animation. * * The version of `background()` with one parameter interprets the value one * of four 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. * RGB, RGBA, HSL, HSLA, hex, and named color strings are supported. If the * parameter is a <a href="#/p5.Color">p5.Color</a> object, it will be used as * the background color. If the parameter is a * <a href="#/p5.Image">p5.Image</a> object, it will be used as the background * image. * * The version of `background()` with two parameters interprets the first one * as a grayscale value. The second parameter sets the alpha (transparency) * value. * * The version of `background()` with three parameters interprets them as RGB, * HSB, or HSL colors, depending on the current * <a href="#/p5/colorMode">colorMode()</a>. By default, colors are specified * in RGB values. Calling `background(255, 204, 0)` sets the background a bright * yellow color. * * @method background * @param {p5.Color} color any value created by the <a href="#/p5/color">color()</a> function * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * // A grayscale value. * background(51); * * describe('A canvas with a dark charcoal gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // A grayscale value and an alpha value. * background(51, 0.4); * describe('A canvas with a transparent gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // R, G & B values. * background(255, 204, 0); * * describe('A canvas with a yellow background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Use HSB color. * colorMode(HSB); * * // H, S & B values. * background(255, 204, 100); * * describe('A canvas with a royal blue background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // A CSS named color. * background('red'); * * describe('A canvas with a red background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Three-digit hex RGB notation. * background('#fae'); * * describe('A canvas with a pink background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Six-digit hex RGB notation. * background('#222222'); * * describe('A canvas with a black background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Integer RGB notation. * background('rgb(0, 255, 0)'); * * describe('A canvas with a bright green background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Integer RGBA notation. * background('rgba(0, 255, 0, 0.25)'); * * describe('A canvas with a transparent green background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Percentage RGB notation. * background('rgb(100%, 0%, 10%)'); * * describe('A canvas with a red background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Percentage RGBA notation. * background('rgba(100%, 0%, 100%, 0.5)'); * * describe('A canvas with a transparent purple background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // A p5.Color object. * let c = color(0, 0, 255); * background(c); * * describe('A canvas with a blue background.'); * } * </code> * </div> * */ /** * @method background * @param {String} colorstring color string, possible formats include: integer * rgb() or rgba(), percentage rgb() or rgba(), * 3-digit hex, 6-digit hex. * @param {Number} [a] opacity of the background relative to current * color range (default is 0-255). * @chainable */ /** * @method background * @param {Number} gray specifies a value between white and black. * @param {Number} [a] * @chainable */ /** * @method background * @param {Number} v1 red value if color mode is RGB, or hue value if color mode is HSB. * @param {Number} v2 green value if color mode is RGB, or saturation value if color mode is HSB. * @param {Number} v3 blue value if color mode is RGB, or brightness value if color mode is HSB. * @param {Number} [a] * @chainable */ /** * @method background * @param {Number[]} values an array containing the red, green, blue * and alpha components of the color. * @chainable */ /** * @method background * @param {p5.Image} image image created with <a href="#/p5/loadImage">loadImage()</a> * or <a href="#/p5/createImage">createImage()</a>, * to set as background. * (must be same size as the sketch window). * @param {Number} [a] * @chainable */ fn.background = function(...args) { this._renderer.background(...args); return this; }; /** * Clears the pixels on the canvas. * * `clear()` makes every pixel 100% transparent. Calling `clear()` doesn't * clear objects created by `createX()` functions such as * <a href="#/p5/createGraphics">createGraphics()</a>, * <a href="#/p5/createVideo">createVideo()</a>, and * <a href="#/p5/createImg">createImg()</a>. These objects will remain * unchanged after calling `clear()` and can be redrawn. * * In WebGL mode, this function can clear the screen to a specific color. It * interprets four numeric parameters as normalized RGBA color values. It also * clears the depth buffer. If you are not using the WebGL renderer, these * parameters will have no effect. * * @method clear * @chainable * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * describe('A gray square. White circles are drawn as the user moves the mouse. The circles disappear when the user presses the mouse.'); * } * * function draw() { * circle(mouseX, mouseY, 20); * } * * function mousePressed() { * clear(); * background(200); * } * </code> * </div> * * <div> * <code> * let pg; * * function setup() { * createCanvas(100, 100); * background(200); * * pg = createGraphics(60, 60); * pg.background(200); * pg.noStroke(); * pg.circle(pg.width / 2, pg.height / 2, 15); * image(pg, 20, 20); * * describe('A white circle drawn on a gray square. The square gets smaller when the mouse is pressed.'); * } * * function mousePressed() { * clear(); * image(pg, 20, 20); * } * </code> * </div> * * @param {Number} [r] normalized red value. * @param {Number} [g] normalized green value. * @param {Number} [b] normalized blue value. * @param {Number} [a] normalized alpha value. */ fn.clear = function(...args) { const _r = args[0] || 0; const _g = args[1] || 0; const _b = args[2] || 0; const _a = args[3] || 0; this._renderer.clear(_r, _g, _b, _a); return this; }; /** * Changes the way color values are interpreted. * * By default, the `Number` parameters for <a href="#/p5/fill">fill()</a>, * <a href="#/p5/stroke">stroke()</a>, * <a href="#/p5/background">background()</a>, and * <a href="#/p5/color">color()</a> are defined by values between 0 and 255 * using the RGB color model. This is equivalent to calling * `colorMode(RGB, 255)`. Pure red is `color(255, 0, 0)` in this model. * * Calling `colorMode(RGB, 100)` sets colors to use RGB color values * between 0 and 100. Pure red is `color(100, 0, 0)` in this model. * * Calling `colorMode(HSB)` or `colorMode(HSL)` changes to HSB or HSL systems instead of RGB. * Pure red is `color(0, 100, 100)` in HSB and `color(0, 100, 50)` in HSL. * * Some additional color modes that p5.js supports are: * * `RGBHDR` - High Dynamic Range RGB defined within the Display P3 color space. * Colors are expressed with an extended dynamic range. To render these colors * accurately, you must use the HDR canvas. * * `HWB` - Hue, Whiteness, Blackness. * Similar to HSB and HSL, this mode uses a hue angle. * Instead of saturation and lightness, HWB defines colors based on the percentage * of whiteness and blackness. This is the color model used by Chrome's GUI color picker. * Pure red in HWB is represented as `color(0, 0, 0)` (i.e., hue 0 with 0% whiteness and 0% blackness). * * <img src="assets/hwb.png"></img> * * `LAB` - Also known as CIE Lab, this color mode defines colors with Lightness, Alpha, and Beta. * It is widely used in professional color measurement contexts due to its perceptual uniformity. * * `LCH` - A more intuitive representation of the CIE Lab color space using Lightness, Chroma, and Hue. * This mode separates the color's chromatic intensity (chroma) from its lightness, * simplifying color selection and manipulation. * * `OKLAB` - A variant of the CIE Lab color space that corrects for non-uniformities inherent in LAB. * The adjustment provides a more perceptually accurate and uniform representation, * which is particularly beneficial for smooth color transitions. * * `OKLCH` - An easier-to-use representation of OKLAB, expressing colors in terms of Lightness, Chroma, and Hue. * This mode retains the perceptual benefits of OKLAB while offering a more intuitive format for color manipulation. * * <a href="#/p5.Color">p5.Color</a> objects remember the mode that they were * created in. Changing modes doesn't affect their appearance. * * `Single-value (Grayscale) Colors`: * When a color is specified with only one parameter (e.g., `color(g)`), p5.js will interpret it * as a grayscale color. However, how that single parameter translates into a grayscale value * depends on the color mode: * * - `RGB, HSB, and HSL`: In RGB, the single value is interpreted using the “blue” maximum * (i.e., the single parameter is mapped to the blue channel's max). * In HSB and HSL, the single value is mapped to Brightness and Lightness max respectively with hue=0 . * and saturation=0. * * - `LAB, LCH, OKLAB, and OKLCH`: The single value is taken to be the `lightness (L)` component, * with the specified max range for that channel. * * - `HWB`: Grayscale relies on both the `whiteness (W)` and `blackness (B)` channels. Since * a single value cannot directly account for two distinct channels, the library uses an * average of their max values to interpret the single grayscale parameter. For instance, * if W has a max of 50 and B has a max of 100, then the single grayscale parameter * is mapped using (50 + 100) / 2 = 75 as its effective maximum. More complex or negative * ranges are currently not handled, so results in those cases may be ambiguous. * * @method colorMode * @param {RGB|HSB|HSL|RGBHDR|HWB|LAB|LCH|OKLAB|OKLCH} mode either RGB, HSB, HSL, * or one of the extended modes described above. * @param {Number} [max] range for all values. * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Fill with pure red. * fill(255, 0, 0); * * circle(50, 50, 25); * * describe('A gray square with a red circle at its center.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Use RGB color with values in the range 0-100. * colorMode(RGB, 100); * * // Fill with pure red. * fill(100, 0, 0); * * circle(50, 50, 25); * * describe('A gray square with a red circle at its center.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Use HSB color. * colorMode(HSB); * * // Fill with pure red. * fill(0, 100, 100); * * circle(50, 50, 25); * * describe('A gray square with a red circle at its center.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Use HSL color. * colorMode(HSL); * * // Fill with pure red. * fill(0, 100, 50); * * circle(50, 50, 25); * * describe('A gray square with a red circle at its center.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Draw a neutral gray background using the default color mode. * background(200); * * // Switch to HWB color mode. * // (Assuming p5.js supports HWB with a range of: * // hue: 0–360, whiteness: 0–100, blackness: 0–100.) * colorMode(HWB); * * // Set fill to pure red in HWB. * // Pure red in HWB is: hue = 0°, whiteness = 0%, blackness = 0%. * fill(0, 0, 0); * * // Draw a circle at the center. * circle(50, 50, 25); * * describe('A gray square with a red circle at its center, drawn using HWB color mode.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Draw a neutral gray background using the default color mode. * background(200); * * // Switch to LAB color mode. * // In this mode, L typically ranges from 0 to 100 while a and b span roughly -128 to 127. * colorMode(LAB); * * // Set fill to pure red in LAB. * // The sRGB red (255, 0, 0) converts approximately to LAB as: * // L = 53, a = 80, b = 67. * fill(53, 80, 67); * * // Draw a circle at the center. * circle(50, 50, 25); * * describe('A gray square with a red circle at its center, drawn using LAB color mode.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Draw a neutral gray background. * background(200); * * // Switch to LCH color mode. * // In LCH, colors are defined by Lightness, Chroma, and Hue (in degrees). * colorMode(LCH); * * // Set fill to an approximation of pure red in LCH: * // Lightness ≈ 53, Chroma ≈ 104, Hue ≈ 40°. * fill(53, 104, 40); * * // Draw a circle at the center. * circle(50, 50, 25); * * describe('A gray square with a red circle at its center, drawn using LCH color mode.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Use RGB color with values in the range 0-100. * colorMode(RGB, 100); * * for (let x = 0; x < 100; x += 1) { * for (let y = 0; y < 100; y += 1) { * stroke(x, y, 0); * point(x, y); * } * } * * describe( * 'A diagonal green to red gradient from bottom-left to top-right with shading transitioning to black at top-left corner.' * ); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Use HSB color with values in the range 0-100. * colorMode(HSB, 100); * * for (let x = 0; x < 100; x += 1) { * for (let y = 0; y < 100; y += 1) { * stroke(x, y, 100); * point(x, y); * } * } * * describe('A rainbow gradient from left-to-right. Brightness transitions to white at the top.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Create a p5.Color object. * let myColor = color(180, 175, 230); * background(myColor); * * // Use RGB color with values in the range 0-1. * colorMode(RGB, 1); * * // Get the red, green, and blue color components. * let redValue = red(myColor); * let greenValue = green(myColor); * let blueValue = blue(myColor); * * // Round the color components for display. * redValue = round(redValue, 2); * greenValue = round(greenValue, 2); * blueValue = round(blueValue, 2); * * // Display the color components. * text(`Red: ${redValue}`, 10, 10, 80, 80); * text(`Green: ${greenValue}`, 10, 40, 80, 80); * text(`Blue: ${blueValue}`, 10, 70, 80, 80); * * describe('A purple canvas with the red, green, and blue decimal values of the color written on it.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(255); * * // Use RGB color with alpha values in the range 0-1. * colorMode(RGB, 255, 255, 255, 1); * * noFill(); * strokeWeight(4); * stroke(255, 0, 10, 0.3); * circle(40, 40, 50); * circle(50, 60, 50); * * describe('Two overlapping translucent pink circle outlines.'); * } * </code> * </div> * * @example * <div> * <code> * let hslGraphic, lchGraphic, oklchGraphic; * * function setup() { * createCanvas(600, 200); * noLoop(); * * // Create three graphics objects for HSL, LCH, and OKLCH color modes * hslGraphic = createGraphics(200, 200); * lchGraphic = createGraphics(200, 200); * oklchGraphic = createGraphics(200, 200); * * // Draw HSL color wheel * colorMode(HSL); * hslGraphic.translate(100, 100); * for (let i = 0; i < 1000; i++) { * hslGraphic.stroke(360 / 1000 * i, 70, 50); * hslGraphic.line(0, 0, hslGraphic.width / 2, 0); * hslGraphic.rotate(TAU / 1000); * } * * // Draw LCH color wheel * colorMode(LCH); * lchGraphic.translate(100, 100); * for (let i = 0; i < 1000; i++) { * lchGraphic.stroke(54, 106, 360 / 1000 * i); * lchGraphic.line(0, 0, lchGraphic.width / 2, 0); * lchGraphic.rotate(TAU / 1000); * } * * // Draw OKLCH color wheel * colorMode(OKLCH); * oklchGraphic.translate(100, 100); * for (let i = 0; i < 1000; i++) { * oklchGraphic.stroke(54, 106, 360 / 1000 * i); * oklchGraphic.line(0, 0, oklchGraphic.width / 2, 0); * oklchGraphic.rotate(TAU / 1000); * } * } * * function draw() { * // Set the styles * colorMode(RGB); * background(220); * * // Display the color wheels * image(hslGraphic, 0, 0); * image(lchGraphic, 200, 0); * image(oklchGraphic, 400, 0); * } * </code> * </div> * * @example * <div> * <code> * // Example: Single-value (Grayscale) colors in different color modes. * // The rectangle is filled with one parameter, but its final color depends * // on how that parameter is interpreted by the current color mode. * * function setup() { * createCanvas(100, 100); * noStroke(); * noLoop(); * } * * function draw() { * // Set color mode to RGB with range 0-255 * colorMode(RGB, 255); * * // Fill with single grayscale value * fill(128); * rect(0, 0, 100, 100); * * // Add text label * fill(0); // Switch to black text for clarity * textSize(14); * text("RGB (128)", 10, 20); * } * </code> * </div> */ /** * @method colorMode * @param {RGB|HSB|HSL|RGBHDR|HWB|LAB|LCH|OKLAB|OKLCH} mode * @param {Number} max1 range for the red or hue depending on the * current color mode. * @param {Number} max2 range for the green or saturation depending * on the current color mode. * @param {Number} max3 range for the blue or brightness/lightness * depending on the current color mode. * @param {Number} [maxA] range for the alpha. * * @return {String} The current color mode. */ fn.colorMode = function(mode, max1, max2, max3, maxA) { // p5._validateParameters('colorMode', arguments); if ( [ RGB, RGBHDR, HSB, HSL, HWB, LAB, LCH, OKLAB, OKLCH ].includes(mode) ) { // Set color mode. this._renderer.states.setValue('colorMode', mode); // Set color maxes. this._renderer.states.setValue('colorMaxes', this._renderer.states.colorMaxes.clone()); const maxes = this._renderer.states.colorMaxes[mode]; if (arguments.length === 2) { maxes[0] = max1; // Red maxes[1] = max1; // Green maxes[2] = max1; // Blue maxes[3] = max1; // Alpha } else if (arguments.length === 4) { maxes[0] = max1; // Red maxes[1] = max2; // Green maxes[2] = max3; // Blue } else if (arguments.length === 5) { maxes[0] = max1; // Red maxes[1] = max2; // Green maxes[2] = max3; // Blue maxes[3] = maxA; // Alpha } } return this._renderer.states.colorMode; }; /** * Sets the color used to fill shapes. * * Calling `fill(255, 165, 0)` or `fill('orange')` means all shapes drawn * after the fill command will be filled with the color orange. * * The version of `fill()` with one parameter interprets the value one of * three 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. A <a href="#/p5.Color">p5.Color</a> object can also be provided to * set the fill color. * * The version of `fill()` with three parameters interprets them as RGB, HSB, * or HSL colors, depending on the current * <a href="#/p5/colorMode">colorMode()</a>. The default color space is RGB, * with each value in the range from 0 to 255. * * @method fill * @param {Number} v1 red value if color mode is RGB or hue value if color mode is HSB. * @param {Number} v2 green value if color mode is RGB or saturation value if color mode is HSB. * @param {Number} v3 blue value if color mode is RGB or brightness value if color mode is HSB. * @param {Number} [alpha] alpha value, controls transparency (0 - transparent, 255 - opaque). * @chainable * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // A grayscale value. * fill(51); * square(20, 20, 60); * * describe('A dark charcoal gray square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // R, G & B values. * fill(255, 204, 0); * square(20, 20, 60); * * describe('A yellow square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(100); * * // Use HSB color. * colorMode(HSB); * * // H, S & B values. * fill(255, 204, 100); * square(20, 20, 60); * * describe('A royal blue square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // A CSS named color. * fill('red'); * square(20, 20, 60); * * describe('A red square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Three-digit hex RGB notation. * fill('#fae'); * square(20, 20, 60); * * describe('A pink square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Six-digit hex RGB notation. * fill('#A251FA'); * square(20, 20, 60); * * describe('A purple square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Integer RGB notation. * fill('rgb(0, 255, 0)'); * square(20, 20, 60); * * describe('A bright green square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Integer RGBA notation. * fill('rgba(0, 255, 0, 0.25)'); * square(20, 20, 60); * * describe('A soft green rectange with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Percentage RGB notation. * fill('rgb(100%, 0%, 10%)'); * square(20, 20, 60); * * describe('A red square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Percentage RGBA notation. * fill('rgba(100%, 0%, 100%, 0.5)'); * square(20, 20, 60); * * describe('A dark fuchsia square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // A p5.Color object. * let c = color(0, 0, 255); * fill(c); * square(20, 20, 60); * * describe('A blue square with a black outline.'); * } * </code> * </div> */ /** * @method fill * @param {String} value a color string. * @chainable */ /** * @method fill * @param {Number} gray a grayscale value. * @param {Number} [alpha] * @chainable */ /** * @method fill * @param {Number[]} values an array containing the red, green, blue & * and alpha components of the color. * @chainable */ /** * @method fill * @param {p5.Color} color the fill color. * @chainable */ fn.fill = function(...args) { this._renderer.fill(...args); return this; }; /** * Disables setting the fill color for shapes. * * Calling `noFill()` is the same as making the fill completely transparent, * as in `fill(0, 0)`. If both <a href="#/p5/noStroke">noStroke()</a> and * `noFill()` are called, nothing will be drawn to the screen. * * @method noFill * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Draw the top square. * square(32, 10, 35); * * // Draw the bottom square. * noFill(); * square(32, 55, 35); * * describe('A white square on above an empty square. Both squares have black outlines.'); * } * </code> * </div> * * <div modernizr='webgl'> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe('A purple cube wireframe spinning on a black canvas.'); * } * * function draw() { * background(0); * * // Style the box. * noFill(); * stroke(100, 100, 240); * * // Rotate the coordinates. * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * * // Draw the box. * box(45); * } * </code> * </div> */ fn.noFill = function() { this._renderer.noFill(); return this; }; /** * Disables drawing points, lines, and the outlines of shapes. * * Calling `noStroke()` is the same as making the stroke completely transparent, * as in `stroke(0, 0)`. If both `noStroke()` and * <a href="#/p5/noFill">noFill()</a> are called, nothing will be drawn to the * screen. * * @method noStroke * @chainable * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * noStroke(); * square(20, 20, 60); * * describe('A white square with no outline.'); * } * </code> * </div> * * <div modernizr='webgl'> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe('A pink cube with no edge outlines spinning on a black canvas.'); * } * * function draw() { * background(0); * * // Style the box. * noStroke(); * fill(240, 150, 150); * * // Rotate the coordinates. * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * * // Draw the box. * box(45); * } * </code> * </div> */ fn.noStroke = function() { this._renderer.states.setValue('strokeColor', null); return this; }; /** * Sets the color used to draw points, lines, and the outlines of shapes. * * Calling `stroke(255, 165, 0)` or `stroke('orange')` means all shapes drawn * after calling `stroke()` will be filled with the color orange. The way * these parameters are interpreted may be changed with the * <a href="#/p5/colorMode">colorMode()</a> function. * * The version of `stroke()` with one parameter interprets the value one of * three 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. A <a href="#/p5.Color">p5.Color</a> object can also be provided to * set the stroke color. * * The version of `stroke()` with two parameters interprets the first one as a * grayscale value. The second parameter sets the alpha (transparency) value. * * The version of `stroke()` with three parameters interprets them as RGB, HSB, * or HSL colors, depending on the current `colorMode()`. * * The version of `stroke()` 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 stroke * @param {Number} v1 red value if color mode is RGB or hue value if color mode is HSB. * @param {Number} v2 green value if color mode is RGB or saturation value if color mode is HSB. * @param {Number} v3 blue value if color mode is RGB or brightness value if color mode is HSB. * @param {Number} [alpha] alpha value, controls transparency (0 - transparent, 255 - opaque). * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // A grayscale value. * strokeWeight(4); * stroke(51); * square(20, 20, 60); * * describe('A white square with a dark charcoal gray outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // R, G & B values. * stroke(255, 204, 0); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a yellow outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Use HSB color. * colorMode(HSB); * * // H, S & B values. * strokeWeight(4); * stroke(255, 204, 100); * square(20, 20, 60); * * describe('A white square with a royal blue outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // A CSS named color. * stroke('red'); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a red outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Three-digit hex RGB notation. * stroke('#fae'); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a pink outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Six-digit hex RGB notation. * stroke('#222222'); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a black outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Integer RGB notation. * stroke('rgb(0, 255, 0)'); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a bright green outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Integer RGBA notation. * stroke('rgba(0, 255, 0, 0.25)'); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a soft green outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Percentage RGB notation. * stroke('rgb(100%, 0%, 10%)'); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a red outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Percentage RGBA notation. * stroke('rgba(100%, 0%, 100%, 0.5)'); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a dark fuchsia outline.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // A p5.Color object. * stroke(color(0, 0, 255)); * strokeWeight(4); * square(20, 20, 60); * * describe('A white square with a blue outline.'); * } * </code> * </div> */ /** * @method stroke * @param {String} value a color string. * @chainable */ /** * @method stroke * @param {Number} gray a grayscale value. * @param {Number} [alpha] * @chainable */ /** * @method stroke * @param {Number[]} values an array containing the red, green, blue, * and alpha components of the color. * @chainable */ /** * @method stroke * @param {p5.Color} color the stroke color. * @chainable */ fn.stroke = function(...args) { this._renderer.stroke(...args); return this; }; /** * Starts using shapes to erase parts of the canvas. * * All drawing that follows `erase()` will subtract from the canvas, revealing * the web page underneath. The erased areas will become transparent, allowing * the content behind the canvas to show through. The * <a href="#/p5/fill">fill()</a>, <a href="#/p5/stroke">stroke()</a>, and * <a href="#/p5/blendMode">blendMode()</a> have no effect once `erase()` is * called. * * The `erase()` function has two optional parameters. The first parameter * sets the strength of erasing by the shape's interior. A value of 0 means * that no erasing will occur. A value of 255 means that the shape's interior * will fully erase the content underneath. The default value is 255 * (full strength). * * The second parameter sets the strength of erasing by the shape's edge. A * value of 0 means that no erasing will occur. A value of 255 means that the * shape's edge will fully erase the content underneath. The default value is * 255 (full strength). * * To cancel the erasing effect, use the <a href="#/p5/noErase">noErase()</a> * function. * * `erase()` has no effect on drawing done with the * <a href="#/p5/image">image()</a> and * <a href="#/p5/background">background()</a> functions. * * @method erase * @param {Number} [strengthFill] a number (0-255) for the strength of erasing under a shape's interior. * Defaults to 255, which is full strength. * @param {Number} [strengthStroke] a number (0-255) for the strength of erasing under a shape's edge. * Defaults to 255, which is full strength. * * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(100, 100, 250); * * // Draw a pink square. * fill(250, 100, 100); * square(20, 20, 60); * * // Erase a circular area. * erase(); * circle(25, 30, 30); * noErase(); * * describe('A purple canvas with a pink square in the middle. A circle is erased from the top-left, leaving a hole.'); * } * </code> * </div> * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(100, 100, 250); * * // Draw a pink square. * fill(250, 100, 100); * square(20, 20, 60); * * // Erase a circular area. * strokeWeight(5); * erase(150, 255); * circle(25, 30, 30); * noErase(); * * describe('A purple canvas with a pink square in the middle. A circle at the top-left partially erases its interior and a fully erases its outline.'); * } * </code> * </div> */ fn.erase = function(opacityFill = 255, opacityStroke = 255) { this._renderer.erase(opacityFill, opacityStroke); return this; }; /** * Ends erasing that was started with <a href="#/p5/erase">erase()</a>. * * The <a href="#/p5/fill">fill()</a>, <a href="#/p5/stroke">stroke()</a>, and * <a href="#/p5/ble