UNPKG

p5

Version:

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

1,966 lines (1,905 loc) 4.19 MB
/*! p5.js v2.0.3 May 30, 2025 */ var p5 = (function () { 'use strict'; /** * @module Constants * @submodule Constants * @for p5 */ const _PI = Math.PI; /** * Version of this p5.js. * @property {String} VERSION * @final */ const VERSION = '2.0.3'; // GRAPHICS RENDERER /** * The default, two-dimensional renderer in p5.js. * * Use this when calling <a href="#/p5/createCanvas"> (for example, * `createCanvas(400, 400, P2D)`) to specify a 2D context. * * @typedef {'p2d'} P2D * @property {P2D} P2D * @final */ const P2D = 'p2d'; /** * A high-dynamic-range (HDR) variant of the default, two-dimensional renderer. * * When available, this mode can allow for extended color ranges and more * dynamic color representation. Use it similarly to `P2D`: * `createCanvas(400, 400, P2DHDR)`. * * @typedef {'p2d-hdr'} P2DHDR * @property {P2DHDR} P2DHDR * @final */ const P2DHDR = 'p2d-hdr'; /** * One of the two render modes in p5.js, used for computationally intensive tasks like 3D rendering and shaders. * * `WEBGL` differs from the default <a href="/reference/p5/P2D">`P2D`</a> renderer in the following ways: * * - **Coordinate System** - When drawing in `WEBGL` mode, the origin point (0,0,0) is located at the center of the screen, not the top-left corner. See <a href="https://p5js.org/tutorials/coordinates-and-transformations/">the tutorial page about coordinates and transformations</a>. * - **3D Shapes** - `WEBGL` mode can be used to draw 3-dimensional shapes like <a href="#/p5/box">box()</a>, <a href="#/p5/sphere">sphere()</a>, <a href="#/p5/cone">cone()</a>, and <a href="https://p5js.org/reference/#3D%20Primitives">more</a>. See <a href="https://p5js.org/tutorials/custom-geometry/">the tutorial page about custom geometry</a> to make more complex objects. * - **Shape Detail** - When drawing in `WEBGL` mode, you can specify how smooth curves should be drawn by using a `detail` parameter. See <a href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#3d-primitives-shapes">the wiki section about shapes</a> for a more information and an example. * - **Textures** - A texture is like a skin that wraps onto a shape. See <a href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#textures">the wiki section about textures</a> for examples of mapping images onto surfaces with textures. * - **Materials and Lighting** - `WEBGL` offers different types of lights like <a href="#/p5/ambientLight">ambientLight()</a> to place around a scene. Materials like <a href="#/p5/specularMaterial">specularMaterial()</a> reflect the lighting to convey shape and depth. See <a href="https://p5js.org/tutorials/lights-camera-materials/">the tutorial page for styling and appearance</a> to experiment with different combinations. * - **Camera** - The viewport of a `WEBGL` sketch can be adjusted by changing camera attributes. See <a href="https://p5js.org/tutorials/lights-camera-materials#camera-and-view">the tutorial page section about cameras</a> for an explanation of camera controls. * - **Text** - `WEBGL` requires opentype/truetype font files to be preloaded using <a href="#/p5/loadFont">loadFont()</a>. See <a href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text">the wiki section about text</a> for details, along with a workaround. * - **Shaders** - Shaders are hardware accelerated programs that can be used for a variety of effects and graphics. See the <a href="https://p5js.org/tutorials/intro-to-shaders/">introduction to shaders</a> to get started with shaders in p5.js. * - **Graphics Acceleration** - `WEBGL` mode uses the graphics card instead of the CPU, so it may help boost the performance of your sketch (example: drawing more shapes on the screen at once). * * To learn more about WEBGL mode, check out <a href="https://p5js.org/tutorials/#webgl">all the interactive WEBGL tutorials</a> in the "Tutorials" section of this website, or read the wiki article <a href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">"Getting started with WebGL in p5"</a>. * * @typedef {unique symbol} WEBGL * @property {WEBGL} WEBGL * @final */ const WEBGL = 'webgl'; /** * One of the two possible values of a WebGL canvas (either WEBGL or WEBGL2), * which can be used to determine what capabilities the rendering environment * has. * @typedef {unique symbol} WEBGL2 * @property {WEBGL2} WEBGL2 * @final */ const WEBGL2 = 'webgl2'; // ENVIRONMENT /** * @typedef {'default'} ARROW * @property {ARROW} ARROW * @final */ const ARROW = 'default'; /** * @property {String} SIMPLE * @final */ const SIMPLE = 'simple'; /** * @property {String} FULL * @final */ const FULL = 'full'; /** * @typedef {'crosshair'} CROSS * @property {CROSS} CROSS * @final */ const CROSS = 'crosshair'; /** * @typedef {'pointer'} HAND * @property {HAND} HAND * @final */ const HAND = 'pointer'; /** * @typedef {'move'} MOVE * @property {MOVE} MOVE * @final */ const MOVE = 'move'; /** * @typedef {'text'} TEXT * @property {TEXT} TEXT * @final */ const TEXT = 'text'; /** * @typedef {'wait'} WAIT * @property {WAIT} WAIT * @final */ const WAIT = 'wait'; // TRIGONOMETRY /** * A `Number` constant that's approximately 1.5708. * * `HALF_PI` is half the value of the mathematical constant π. It's useful for * many tasks that involve rotation and oscillation. For example, calling * `rotate(HALF_PI)` rotates the coordinate system `HALF_PI` radians, which is * a quarter turn (90˚). * * Note: `TWO_PI` radians equals 360˚, `PI` radians equals 180˚, `HALF_PI` * radians equals 90˚, and `QUARTER_PI` radians equals 45˚. * * @property {Number} HALF_PI * @final * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Draw an arc from 0 to HALF_PI. * arc(50, 50, 80, 80, 0, HALF_PI); * * describe('The bottom-right quarter of a circle drawn in white on a gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Draw a line. * line(0, 0, 40, 0); * * // Rotate a quarter turn. * rotate(HALF_PI); * * // Draw the same line, rotated. * line(0, 0, 40, 0); * * describe('Two black lines on a gray background. One line extends from the center to the right. The other line extends from the center to the bottom.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'A red circle and a blue circle oscillate from left to right on a gray background. The red circle appears to chase the blue circle.' * ); * } * * function draw() { * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Calculate the x-coordinates. * let x1 = 40 * sin(frameCount * 0.05); * let x2 = 40 * sin(frameCount * 0.05 + HALF_PI); * * // Style the oscillators. * noStroke(); * * // Draw the red oscillator. * fill(255, 0, 0); * circle(x1, 0, 20); * * // Draw the blue oscillator. * fill(0, 0, 255); * circle(x2, 0, 20); * } * </code> * </div> */ const HALF_PI = _PI / 2; /** * A `Number` constant that's approximately 3.1416. * * `PI` is the mathematical constant π. It's useful for many tasks that * involve rotation and oscillation. For example, calling `rotate(PI)` rotates * the coordinate system `PI` radians, which is a half turn (180˚). * * Note: `TWO_PI` radians equals 360˚, `PI` radians equals 180˚, `HALF_PI` * radians equals 90˚, and `QUARTER_PI` radians equals 45˚. * * @property {Number} PI * @final * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Draw an arc from 0 to PI. * arc(50, 50, 80, 80, 0, PI); * * describe('The bottom half of a circle drawn in white on a gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Draw a line. * line(0, 0, 40, 0); * * // Rotate a half turn. * rotate(PI); * * // Draw the same line, rotated. * line(0, 0, 40, 0); * * describe('A horizontal black line on a gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'A red circle and a blue circle oscillate from left to right on a gray background. The circles drift apart, then meet in the middle, over and over again.' * ); * } * * function draw() { * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Calculate the x-coordinates. * let x1 = 40 * sin(frameCount * 0.05); * let x2 = 40 * sin(frameCount * 0.05 + PI); * * // Style the oscillators. * noStroke(); * * // Draw the red oscillator. * fill(255, 0, 0); * circle(x1, 0, 20); * * // Draw the blue oscillator. * fill(0, 0, 255); * circle(x2, 0, 20); * } * </code> * </div> */ const PI = _PI; /** * A `Number` constant that's approximately 0.7854. * * `QUARTER_PI` is one-fourth the value of the mathematical constant π. It's * useful for many tasks that involve rotation and oscillation. For example, * calling `rotate(QUARTER_PI)` rotates the coordinate system `QUARTER_PI` * radians, which is an eighth of a turn (45˚). * * Note: `TWO_PI` radians equals 360˚, `PI` radians equals 180˚, `HALF_PI` * radians equals 90˚, and `QUARTER_PI` radians equals 45˚. * * @property {Number} QUARTER_PI * @final * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Draw an arc from 0 to QUARTER_PI. * arc(50, 50, 80, 80, 0, QUARTER_PI); * * describe('A one-eighth slice of a circle drawn in white on a gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Draw a line. * line(0, 0, 40, 0); * * // Rotate an eighth turn. * rotate(QUARTER_PI); * * // Draw the same line, rotated. * line(0, 0, 40, 0); * * describe('Two black lines that form a "V" opening towards the bottom-right corner of a gray square.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'A red circle and a blue circle oscillate from left to right on a gray background. The red circle appears to chase the blue circle.' * ); * } * * function draw() { * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Calculate the x-coordinates. * let x1 = 40 * sin(frameCount * 0.05); * let x2 = 40 * sin(frameCount * 0.05 + QUARTER_PI); * * // Style the oscillators. * noStroke(); * * // Draw the red oscillator. * fill(255, 0, 0); * circle(x1, 0, 20); * * // Draw the blue oscillator. * fill(0, 0, 255); * circle(x2, 0, 20); * } * </code> * </div> */ const QUARTER_PI = _PI / 4; /** * A `Number` constant that's approximately 6.2382. * * `TAU` is twice the value of the mathematical constant π. It's useful for * many tasks that involve rotation and oscillation. For example, calling * `rotate(TAU)` rotates the coordinate system `TAU` radians, which is one * full turn (360˚). `TAU` and `TWO_PI` are equal. * * Note: `TAU` radians equals 360˚, `PI` radians equals 180˚, `HALF_PI` * radians equals 90˚, and `QUARTER_PI` radians equals 45˚. * * @property {Number} TAU * @final * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Draw an arc from 0 to TAU. * arc(50, 50, 80, 80, 0, TAU); * * describe('A white circle drawn on a gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Draw a line. * line(0, 0, 40, 0); * * // Rotate a full turn. * rotate(TAU); * * // Style the second line. * strokeWeight(5); * * // Draw the same line, shorter and rotated. * line(0, 0, 20, 0); * * describe( * 'Two horizontal black lines on a gray background. A thick line extends from the center toward the right. A thin line extends from the end of the thick line.' * ); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'A red circle with a blue center oscillates from left to right on a gray background.' * ); * } * * function draw() { * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Calculate the x-coordinates. * let x1 = 40 * sin(frameCount * 0.05); * let x2 = 40 * sin(frameCount * 0.05 + TAU); * * // Style the oscillators. * noStroke(); * * // Draw the red oscillator. * fill(255, 0, 0); * circle(x1, 0, 20); * * // Draw the blue oscillator, smaller. * fill(0, 0, 255); * circle(x2, 0, 10); * } * </code> * </div> */ const TAU = _PI * 2; /** * A `Number` constant that's approximately 6.2382. * * `TWO_PI` is twice the value of the mathematical constant π. It's useful for * many tasks that involve rotation and oscillation. For example, calling * `rotate(TWO_PI)` rotates the coordinate system `TWO_PI` radians, which is * one full turn (360˚). `TWO_PI` and `TAU` are equal. * * Note: `TWO_PI` radians equals 360˚, `PI` radians equals 180˚, `HALF_PI` * radians equals 90˚, and `QUARTER_PI` radians equals 45˚. * * @property {Number} TWO_PI * @final * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Draw an arc from 0 to TWO_PI. * arc(50, 50, 80, 80, 0, TWO_PI); * * describe('A white circle drawn on a gray background.'); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Draw a line. * line(0, 0, 40, 0); * * // Rotate a full turn. * rotate(TWO_PI); * * // Style the second line. * strokeWeight(5); * * // Draw the same line, shorter and rotated. * line(0, 0, 20, 0); * * describe( * 'Two horizontal black lines on a gray background. A thick line extends from the center toward the right. A thin line extends from the end of the thick line.' * ); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'A red circle with a blue center oscillates from left to right on a gray background.' * ); * } * * function draw() { * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Calculate the x-coordinates. * let x1 = 40 * sin(frameCount * 0.05); * let x2 = 40 * sin(frameCount * 0.05 + TWO_PI); * * // Style the oscillators. * noStroke(); * * // Draw the red oscillator. * fill(255, 0, 0); * circle(x1, 0, 20); * * // Draw the blue oscillator, smaller. * fill(0, 0, 255); * circle(x2, 0, 10); * } * </code> * </div> */ const TWO_PI = _PI * 2; /** * A `String` constant that's used to set the * <a href="#/p5/angleMode">angleMode()</a>. * * By default, functions such as <a href="#/p5/rotate">rotate()</a> and * <a href="#/p5/sin">sin()</a> expect angles measured in units of radians. * Calling `angleMode(DEGREES)` ensures that angles are measured in units of * degrees. * * Note: `TWO_PI` radians equals 360˚. * * @typedef {unique symbol} DEGREES * @property {DEGREES} DEGREES * @final * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Draw a red arc from 0 to HALF_PI radians. * fill(255, 0, 0); * arc(50, 50, 80, 80, 0, HALF_PI); * * // Use degrees. * angleMode(DEGREES); * * // Draw a blue arc from 90˚ to 180˚. * fill(0, 0, 255); * arc(50, 50, 80, 80, 90, 180); * * describe('The bottom half of a circle drawn on a gray background. The bottom-right quarter is red. The bottom-left quarter is blue.'); * } * </code> * </div> */ // export const DEGREES = Symbol('degrees'); /** * A `String` constant that's used to set the * <a href="#/p5/angleMode">angleMode()</a>. * * By default, functions such as <a href="#/p5/rotate">rotate()</a> and * <a href="#/p5/sin">sin()</a> expect angles measured in units of radians. * Calling `angleMode(RADIANS)` ensures that angles are measured in units of * radians. Doing so can be useful if the * <a href="#/p5/angleMode">angleMode()</a> has been set to * <a href="#/p5/DEGREES">DEGREES</a>. * * Note: `TWO_PI` radians equals 360˚. * * @typedef {unique symbol} RADIANS * @property {RADIANS} RADIANS * @final * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * background(200); * * // Use degrees. * angleMode(DEGREES); * * // Draw a red arc from 0˚ to 90˚. * fill(255, 0, 0); * arc(50, 50, 80, 80, 0, 90); * * // Use radians. * angleMode(RADIANS); * * // Draw a blue arc from HALF_PI to PI. * fill(0, 0, 255); * arc(50, 50, 80, 80, HALF_PI, PI); * * describe('The bottom half of a circle drawn on a gray background. The bottom-right quarter is red. The bottom-left quarter is blue.'); * } * </code> * </div> */ // export const RADIANS = Symbol('radians'); const DEG_TO_RAD = _PI / 180.0; const RAD_TO_DEG = 180.0 / _PI; // SHAPE /** * @typedef {'corner'} CORNER * @property {CORNER} CORNER * @final */ const CORNER = 'corner'; /** * @typedef {'corners'} CORNERS * @property {CORNERS} CORNERS * @final */ const CORNERS = 'corners'; /** * @typedef {'radius'} RADIUS * @property {RADIUS} RADIUS * @final */ const RADIUS = 'radius'; /** * @typedef {'right'} RIGHT * @property {RIGHT} RIGHT * @final */ const RIGHT = 'right'; /** * @typedef {'left'} LEFT * @property {LEFT} LEFT * @final */ const LEFT = 'left'; /** * @typedef {'center'} CENTER * @property {CENTER} CENTER * @final */ const CENTER = 'center'; /** * @typedef {'top'} TOP * @property {TOP} TOP * @final */ const TOP = 'top'; /** * @typedef {'bottom'} BOTTOM * @property {BOTTOM} BOTTOM * @final */ const BOTTOM = 'bottom'; /** * @typedef {'alphabetic'} BASELINE * @property {BASELINE} BASELINE * @final */ const BASELINE = 'alphabetic'; /** * @typedef {0x0000} POINTS * @property {POINTS} POINTS * @final */ const POINTS = 0x0000; /** * @typedef {0x0001} LINES * @property {LINES} LINES * @final */ const LINES = 0x0001; /** * @property {0x0003} LINE_STRIP * @property {LINE_STRIP} LINE_STRIP * @final */ const LINE_STRIP = 0x0003; /** * @typedef {0x0002} LINE_LOOP * @property {LINE_LOOP} LINE_LOOP * @final */ const LINE_LOOP = 0x0002; /** * @typedef {0x0004} TRIANGLES * @property {TRIANGLES} TRIANGLES * @final */ const TRIANGLES = 0x0004; /** * @typedef {0x0006} TRIANGLE_FAN * @property {TRIANGLE_FAN} TRIANGLE_FAN * @final */ const TRIANGLE_FAN = 0x0006; /** * @typedef {0x0005} TRIANGLE_STRIP * @property {TRIANGLE_STRIP} TRIANGLE_STRIP * @final */ const TRIANGLE_STRIP = 0x0005; /** * @typedef {'quads'} QUADS * @property {QUADS} QUADS * @final */ const QUADS = 'quads'; /** * @typedef {'quad_strip'} QUAD_STRIP * @property {QUAD_STRIP} QUAD_STRIP * @final */ const QUAD_STRIP = 'quad_strip'; /** * @typedef {'tess'} TESS * @property {TESS} TESS * @final */ const TESS = 'tess'; /** * @typedef {0x0007} EMPTY_PATH * @property {EMPTY_PATH} EMPTY_PATH * @final */ const EMPTY_PATH = 0x0007; /** * @typedef {0x0008} PATH * @property {PATH} PATH * @final */ const PATH = 0x0008; /** * @typedef {'close'} CLOSE * @property {CLOSE} CLOSE * @final */ const CLOSE = 'close'; /** * @typedef {'open'} OPEN * @property {OPEN} OPEN * @final */ const OPEN = 'open'; /** * @typedef {'chord'} CHORD * @property {CHORD} CHORD * @final */ const CHORD = 'chord'; /** * @typedef {'pie'} PIE * @property {PIE} PIE * @final */ const PIE = 'pie'; /** * @typedef {'square'} PROJECT * @property {PROJECT} PROJECT * @final */ const PROJECT = 'square'; // PEND: careful this is counterintuitive /** * @typedef {'butt'} SQUARE * @property {SQUERE} SQUARE * @final */ const SQUARE = 'butt'; /** * @typedef {'round'} ROUND * @property {ROUND} ROUND * @final */ const ROUND = 'round'; /** * @typedef {'bevel'} BEVEL * @property {BEVEL} BEVEL * @final */ const BEVEL = 'bevel'; /** * @typedef {'miter'} MITER * @property {MITER} MITER * @final */ const MITER = 'miter'; // DOM EXTENSION /** * AUTO allows us to automatically set the width or height of an element (but not both), * based on the current height and width of the element. Only one parameter can * be passed to the <a href="/reference/p5.Element/size">size</a> function as AUTO, at a time. * * @typedef {'auto'} AUTO * @property {AUTO} AUTO * @final */ const AUTO = 'auto'; // INPUT /** * @typedef {'Alt'} ALT * @property {ALT} ALT * @final */ const ALT = 'Alt'; /** * @typedef {'Backspace'} BACKSPACE * @property {BACKSPACE} BACKSPACE * @final */ const BACKSPACE = 'Backspace'; /** * @typedef {'Control' | 'Control'} CONTROL * @property {CONTROL} CONTROL * @final */ const CONTROL = 'Control'; /** * @typedef {'Delete'} DELETE * @property {DELETE} DELETE * @final */ const DELETE = 'Delete'; /** * @typedef {'ArrowDown'} DOWN_ARROW * @property {DOWN_ARROW} DOWN_ARROW * @final */ const DOWN_ARROW = 'ArrowDown'; /** * @typedef {'Enter'} ENTER * @property {ENTER} ENTER * @final */ const ENTER = 'Enter'; /** * @typedef {'Escape'} ESCAPE * @property {ESCAPE} ESCAPE * @final */ const ESCAPE = 'Escape'; /** * @typedef {'ArrowLeft'} LEFT_ARROW * @property {LEFT_ARROW} LEFT_ARROW * @final */ const LEFT_ARROW = 'ArrowLeft'; /** * @typedef {'Alt'} OPTION * @property {OPTION} OPTION * @final */ const OPTION = 'Alt'; /** * @typedef {'Enter'} RETURN * @property {RETURN} RETURN * @final */ const RETURN = 'Enter'; /** * @typedef {'ArrowRight'} RIGHT_ARROW * @property {RIGHT_ARROW} RIGHT_ARROW * @final */ const RIGHT_ARROW = 'ArrowRight'; /** * @typedef {'Shift'} SHIFT * @property {SHIFT} SHIFT * @final */ const SHIFT = 'Shift'; /** * @typedef {'Tab'} TAB * @property {TAB} TAB * @final */ const TAB = 'Tab'; /** * @typedef {'ArrowUp'} UP_ARROW * @property {UP_ARROW} UP_ARROW * @final */ const UP_ARROW = 'ArrowUp'; // RENDERING /** * @typedef {'source-over'} BLEND * @property {BLEND} BLEND * @final */ const BLEND = 'source-over'; /** * @typedef {'destination-out'} REMOVE * @property {REMOVE} REMOVE * @final */ const REMOVE = 'destination-out'; /** * @typedef {'lighter'} ADD * @property {ADD} ADD * @final */ const ADD = 'lighter'; /** * @typedef {'darken'} DARKEST * @property {DARKEST} DARKEST * @final */ const DARKEST = 'darken'; /** * @typedef {'lighten'} LIGHTEST * @property {LIGHTEST} LIGHTEST * @final */ const LIGHTEST = 'lighten'; /** * @typedef {'difference'} DIFFERENCE * @property {DIFFERENCE} DIFFERENCE * @final */ const DIFFERENCE = 'difference'; /** * @typedef {'subtract'} SUBTRACT * @property {SUBTRACT} SUBTRACT * @final */ const SUBTRACT = 'subtract'; /** * @typedef {'exclusion'} EXCLUSION * @property {EXCLUSION} EXCLUSION * @final */ const EXCLUSION = 'exclusion'; /** * @typedef {'multiply'} MULTIPLY * @property {MULTIPLY} MULTIPLY * @final */ const MULTIPLY = 'multiply'; /** * @typedef {'screen'} SCREEN * @property {SCREEN} SCREEN * @final */ const SCREEN = 'screen'; /** * @typedef {'copy'} REPLACE * @property {REPLACE} REPLACE * @final */ const REPLACE = 'copy'; /** * @typedef {'overlay'} OVERLAY * @property {OVERLAY} OVERLAY * @final */ const OVERLAY = 'overlay'; /** * @typedef {'hard-light'} HARD_LIGHT * @property {HARD_LIGHT} HARD_LIGHT * @final */ const HARD_LIGHT = 'hard-light'; /** * @typedef {'soft-light'} SOFT_LIGHT * @property {SOFT_LIGHT} SOFT_LIGHT * @final */ const SOFT_LIGHT = 'soft-light'; /** * @typedef {'color-dodge'} DODGE * @property {DODGE} DODGE * @final */ const DODGE = 'color-dodge'; /** * @typedef {'color-burn'} BURN * @property {BURN} BURN * @final */ const BURN = 'color-burn'; // FILTERS /** * @typedef {'threshold'} THRESHOLD * @property {THRESHOLD} THRESHOLD * @final */ const THRESHOLD = 'threshold'; /** * @typedef {'gray'} GRAY * @property {GRAY} GRAY * @final */ const GRAY = 'gray'; /** * @typedef {'opaque'} OPAQUE * @property {OPAQUE} OPAQUE * @final */ const OPAQUE = 'opaque'; /** * @typedef {'invert'} INVERT * @property {INVERT} INVERT * @final */ const INVERT = 'invert'; /** * @typedef {'posterize'} POSTERIZE * @property {POSTERIZE} POSTERIZE * @final */ const POSTERIZE = 'posterize'; /** * @typedef {'dilate'} DILATE * @property {DILATE} DILATE * @final */ const DILATE = 'dilate'; /** * @typedef {'erode'} ERODE * @property {ERODE} ERODE * @final */ const ERODE = 'erode'; /** * @typedef {'blur'} BLUR * @property {BLUR} BLUR * @final */ const BLUR = 'blur'; // TYPOGRAPHY /** * @typedef {'normal'} NORMAL * @property {NORMAL} NORMAL * @final */ const NORMAL = 'normal'; /** * @typedef {'italic'} ITALIC * @property {ITALIC} ITALIC * @final */ const ITALIC = 'italic'; /** * @typedef {'bold'} BOLD * @property {BOLD} BOLD * @final */ const BOLD = 'bold'; /** * @typedef {'bold italic'} BOLDITALIC * @property {BOLDITALIC} BOLDITALIC * @final */ const BOLDITALIC = 'bold italic'; /** * @typedef {'CHAR'} CHAR * @property {CHAR} CHAR * @final */ const CHAR = 'CHAR'; /** * @typedef {'WORD'} WORD * @property {WORD} WORD * @final */ const WORD = 'WORD'; // TYPOGRAPHY-INTERNAL const _DEFAULT_TEXT_FILL = '#000000'; const _DEFAULT_LEADMULT = 1.25; const _CTX_MIDDLE = 'middle'; // VERTICES /** * @typedef {'linear'} LINEAR * @property {LINEAR} LINEAR * @final */ const LINEAR = 'linear'; /** * @typedef {'quadratic'} QUADRATIC * @property {QUADRATIC} QUADRATIC * @final */ const QUADRATIC = 'quadratic'; /** * @typedef {'bezier'} BEZIER * @property {BEZIER} BEZIER * @final */ const BEZIER = 'bezier'; /** * @typedef {'curve'} CURVE * @property {CURVE} CURVE * @final */ const CURVE = 'curve'; // WEBGL DRAWMODES /** * @typedef {'stroke'} STROKE * @property {STROKE} STROKE * @final */ const STROKE = 'stroke'; /** * @typedef {'fill'} FILL * @property {FILL} FILL * @final */ const FILL = 'fill'; /** * @typedef {'texture'} TEXTURE * @property {TEXTURE} TEXTURE * @final */ const TEXTURE = 'texture'; /** * @typedef {'immediate'} IMMEDIATE * @property {IMMEDIATE} IMMEDIATE * @final */ const IMMEDIATE = 'immediate'; // WEBGL TEXTURE MODE // NORMAL already exists for typography /** * @typedef {'image'} IMAGE * @property {IMAGE} IMAGE * @final */ const IMAGE = 'image'; // WEBGL TEXTURE WRAP AND FILTERING // LINEAR already exists above /** * @typedef {'nearest'} NEAREST * @property {NEAREST} NEAREST * @final */ const NEAREST = 'nearest'; /** * @typedef {'repeat'} REPEAT * @property {REPEAT} REPEAT * @final */ const REPEAT = 'repeat'; /** * @typedef {'clamp'} CLAMP * @property {CLAMP} CLAMP * @final */ const CLAMP = 'clamp'; /** * @typedef {'mirror'} MIRROR * @property {MIRROR} MIRROR * @final */ const MIRROR = 'mirror'; // WEBGL GEOMETRY SHADING /** * @typedef {'flat'} FLAT * @property {FLAT} FLAT * @final */ const FLAT = 'flat'; /** * @typedef {'smooth'} SMOOTH * @property {SMOOTH} SMOOTH * @final */ const SMOOTH = 'smooth'; // DEVICE-ORIENTATION /** * @typedef {'landscape'} LANDSCAPE * @property {LANDSCAPE} LANDSCAPE * @final */ const LANDSCAPE = 'landscape'; /** * @typedef {'portrait'} PORTRAIT * @property {PORTRAIT} PORTRAIT * @final */ const PORTRAIT = 'portrait'; // DEFAULTS const _DEFAULT_STROKE = '#000000'; const _DEFAULT_FILL = '#FFFFFF'; /** * @typedef {'grid'} GRID * @property {GRID} GRID * @final */ const GRID = 'grid'; /** * @typedef {'axes'} AXES * @property {AXES} AXES * @final */ const AXES = 'axes'; /** * @typedef {'label'} LABEL * @property {LABEL} LABEL * @final */ const LABEL = 'label'; /** * @typedef {'fallback'} FALLBACK * @property {FALLBACK} FALLBACK * @final */ const FALLBACK = 'fallback'; /** * @typedef {'contain'} CONTAIN * @property {CONTAIN} CONTAIN * @final */ const CONTAIN = 'contain'; /** * @typedef {'cover'} COVER * @property {COVER} COVER * @final */ const COVER = 'cover'; /** * @typedef {'unsigned-byte'} UNSIGNED_BYTE * @property {UNSIGNED_BYTE} UNSIGNED_BYTE * @final */ const UNSIGNED_BYTE = 'unsigned-byte'; /** * @typedef {'unsigned-int'} UNSIGNED_INT * @property {UNSIGNED_INT} UNSIGNED_INT * @final */ const UNSIGNED_INT = 'unsigned-int'; /** * @typedef {'float'} FLOAT * @property {FLOAT} FLOAT * @final */ const FLOAT = 'float'; /** * @typedef {'half-float'} HALF_FLOAT * @property {HALF_FLOAT} HALF_FLOAT * @final */ const HALF_FLOAT = 'half-float'; /** * The `splineProperty('ends')` mode where splines curve through * their first and last points. * @typedef {unique symbol} INCLUDE * @property {INCLUDE} INCLUDE * @final */ const INCLUDE = Symbol('include'); /** * The `splineProperty('ends')` mode where the first and last points in a spline * affect the direction of the curve, but are not rendered. * @typedef {unique symbol} EXCLUDE * @property {EXCLUDE} EXCLUDE * @final */ const EXCLUDE = Symbol('exclude'); /** * The `splineProperty('ends')` mode where the spline loops back to its first point. * Only used internally. * @typedef {unique symbol} JOIN * @property {JOIN} JOIN * @final * @private */ const JOIN = Symbol('join'); var constants = /*#__PURE__*/Object.freeze({ __proto__: null, ADD: ADD, ALT: ALT, ARROW: ARROW, AUTO: AUTO, AXES: AXES, BACKSPACE: BACKSPACE, BASELINE: BASELINE, BEVEL: BEVEL, BEZIER: BEZIER, BLEND: BLEND, BLUR: BLUR, BOLD: BOLD, BOLDITALIC: BOLDITALIC, BOTTOM: BOTTOM, BURN: BURN, CENTER: CENTER, CHAR: CHAR, CHORD: CHORD, CLAMP: CLAMP, CLOSE: CLOSE, CONTAIN: CONTAIN, CONTROL: CONTROL, CORNER: CORNER, CORNERS: CORNERS, COVER: COVER, CROSS: CROSS, CURVE: CURVE, DARKEST: DARKEST, DEG_TO_RAD: DEG_TO_RAD, DELETE: DELETE, DIFFERENCE: DIFFERENCE, DILATE: DILATE, DODGE: DODGE, DOWN_ARROW: DOWN_ARROW, EMPTY_PATH: EMPTY_PATH, ENTER: ENTER, ERODE: ERODE, ESCAPE: ESCAPE, EXCLUDE: EXCLUDE, EXCLUSION: EXCLUSION, FALLBACK: FALLBACK, FILL: FILL, FLAT: FLAT, FLOAT: FLOAT, FULL: FULL, GRAY: GRAY, GRID: GRID, HALF_FLOAT: HALF_FLOAT, HALF_PI: HALF_PI, HAND: HAND, HARD_LIGHT: HARD_LIGHT, IMAGE: IMAGE, IMMEDIATE: IMMEDIATE, INCLUDE: INCLUDE, INVERT: INVERT, ITALIC: ITALIC, JOIN: JOIN, LABEL: LABEL, LANDSCAPE: LANDSCAPE, LEFT: LEFT, LEFT_ARROW: LEFT_ARROW, LIGHTEST: LIGHTEST, LINEAR: LINEAR, LINES: LINES, LINE_LOOP: LINE_LOOP, LINE_STRIP: LINE_STRIP, MIRROR: MIRROR, MITER: MITER, MOVE: MOVE, MULTIPLY: MULTIPLY, NEAREST: NEAREST, NORMAL: NORMAL, OPAQUE: OPAQUE, OPEN: OPEN, OPTION: OPTION, OVERLAY: OVERLAY, P2D: P2D, P2DHDR: P2DHDR, PATH: PATH, PI: PI, PIE: PIE, POINTS: POINTS, PORTRAIT: PORTRAIT, POSTERIZE: POSTERIZE, PROJECT: PROJECT, QUADRATIC: QUADRATIC, QUADS: QUADS, QUAD_STRIP: QUAD_STRIP, QUARTER_PI: QUARTER_PI, RADIUS: RADIUS, RAD_TO_DEG: RAD_TO_DEG, REMOVE: REMOVE, REPEAT: REPEAT, REPLACE: REPLACE, RETURN: RETURN, RIGHT: RIGHT, RIGHT_ARROW: RIGHT_ARROW, ROUND: ROUND, SCREEN: SCREEN, SHIFT: SHIFT, SIMPLE: SIMPLE, SMOOTH: SMOOTH, SOFT_LIGHT: SOFT_LIGHT, SQUARE: SQUARE, STROKE: STROKE, SUBTRACT: SUBTRACT, TAB: TAB, TAU: TAU, TESS: TESS, TEXT: TEXT, TEXTURE: TEXTURE, THRESHOLD: THRESHOLD, TOP: TOP, TRIANGLES: TRIANGLES, TRIANGLE_FAN: TRIANGLE_FAN, TRIANGLE_STRIP: TRIANGLE_STRIP, TWO_PI: TWO_PI, UNSIGNED_BYTE: UNSIGNED_BYTE, UNSIGNED_INT: UNSIGNED_INT, UP_ARROW: UP_ARROW, VERSION: VERSION, WAIT: WAIT, WEBGL: WEBGL, WEBGL2: WEBGL2, WORD: WORD, _CTX_MIDDLE: _CTX_MIDDLE, _DEFAULT_FILL: _DEFAULT_FILL, _DEFAULT_LEADMULT: _DEFAULT_LEADMULT, _DEFAULT_STROKE: _DEFAULT_STROKE, _DEFAULT_TEXT_FILL: _DEFAULT_TEXT_FILL }); /** * @module Transform * @submodule Transform * @for p5 * @requires core * @requires constants */ function transform(p5, fn){ /** * Applies a transformation matrix to the coordinate system. * * Transformations such as * <a href="#/p5/translate">translate()</a>, * <a href="#/p5/rotate">rotate()</a>, and * <a href="#/p5/scale">scale()</a> * use matrix-vector multiplication behind the scenes. A table of numbers, * called a matrix, encodes each transformation. The values in the matrix * then multiply each point on the canvas, which is represented by a vector. * * `applyMatrix()` allows for many transformations to be applied at once. See * <a href="https://en.wikipedia.org/wiki/Transformation_matrix" target="_blank">Wikipedia</a> * and <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Matrix_math_for_the_web" target="_blank">MDN</a> * for more details about transformations. * * There are two ways to call `applyMatrix()` in two and three dimensions. * * In 2D mode, the parameters `a`, `b`, `c`, `d`, `e`, and `f`, correspond to * elements in the following transformation matrix: * * > <img style="max-width: 150px" src="assets/transformation-matrix.png" * alt="The transformation matrix used when applyMatrix is called in 2D mode."/> * * The numbers can be passed individually, as in * `applyMatrix(2, 0, 0, 0, 2, 0)`. They can also be passed in an array, as in * `applyMatrix([2, 0, 0, 0, 2, 0])`. * * In 3D mode, the parameters `a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`, * `j`, `k`, `l`, `m`, `n`, `o`, and `p` correspond to elements in the * following transformation matrix: * * <img style="max-width: 300px" src="assets/transformation-matrix-4-4.png" * alt="The transformation matrix used when applyMatrix is called in 3D mode."/> * * The numbers can be passed individually, as in * `applyMatrix(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1)`. They can * also be passed in an array, as in * `applyMatrix([2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1])`. * * By default, transformations accumulate. The * <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a> functions * can be used to isolate transformations within distinct drawing groups. * * Note: Transformations are reset at the beginning of the draw loop. Calling * `applyMatrix()` inside the <a href="#/p5/draw">draw()</a> function won't * cause shapes to transform continuously. * * @method applyMatrix * @param {Array} arr an array containing the elements of the transformation matrix. Its length should be either 6 (2D) or 16 (3D). * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe('A white circle on a gray background.'); * } * * function draw() { * background(200); * * // Translate the origin to the center. * applyMatrix(1, 0, 0, 1, 50, 50); * * // Draw the circle at coordinates (0, 0). * circle(0, 0, 40); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe('A white circle on a gray background.'); * } * * function draw() { * background(200); * * // Translate the origin to the center. * let m = [1, 0, 0, 1, 50, 50]; * applyMatrix(m); * * // Draw the circle at coordinates (0, 0). * circle(0, 0, 40); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe("A white rectangle on a gray background. The rectangle's long axis runs from top-left to bottom-right."); * } * * function draw() { * background(200); * * // Rotate the coordinate system 1/8 turn. * let angle = QUARTER_PI; * let ca = cos(angle); * let sa = sin(angle); * applyMatrix(ca, sa, -sa, ca, 0, 0); * * // Draw a rectangle at coordinates (50, 0). * rect(50, 0, 40, 20); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'Two white squares on a gray background. The larger square appears at the top-center. The smaller square appears at the top-left.' * ); * } * * function draw() { * background(200); * * // Draw a square at (30, 20). * square(30, 20, 40); * * // Scale the coordinate system by a factor of 0.5. * applyMatrix(0.5, 0, 0, 0.5, 0, 0); * * // Draw a square at (30, 20). * // It appears at (15, 10) after scaling. * square(30, 20, 40); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe('A white quadrilateral on a gray background.'); * } * * function draw() { * background(200); * * // Calculate the shear factor. * let angle = QUARTER_PI; * let shearFactor = 1 / tan(HALF_PI - angle); * * // Shear the coordinate system along the x-axis. * applyMatrix(1, 0, shearFactor, 1, 0, 0); * * // Draw the square. * square(0, 0, 50); * } * </code> * </div> * * <div> * <code> * // Click and drag the mouse to view the scene from different angles. * * function setup() { * createCanvas(100, 100, WEBGL); * * describe('A white cube rotates slowly against a gray background.'); * } * * function draw() { * background(200); * * // Enable orbiting with the mouse. * orbitControl(); * * // Rotate the coordinate system a little more each frame. * let angle = frameCount * 0.01; * let ca = cos(angle); * let sa = sin(angle); * applyMatrix(ca, 0, sa, 0, 0, 1, 0, 0, -sa, 0, ca, 0, 0, 0, 0, 1); * * // Draw a box. * box(); * } * </code> * </div> */ /** * @method applyMatrix * @param {Number} a an element of the transformation matrix. * @param {Number} b an element of the transformation matrix. * @param {Number} c an element of the transformation matrix. * @param {Number} d an element of the transformation matrix. * @param {Number} e an element of the transformation matrix. * @param {Number} f an element of the transformation matrix. * @chainable */ /** * @method applyMatrix * @param {Number} a * @param {Number} b * @param {Number} c * @param {Number} d * @param {Number} e * @param {Number} f * @param {Number} g an element of the transformation matrix. * @param {Number} h an element of the transformation matrix. * @param {Number} i an element of the transformation matrix. * @param {Number} j an element of the transformation matrix. * @param {Number} k an element of the transformation matrix. * @param {Number} l an element of the transformation matrix. * @param {Number} m an element of the transformation matrix. * @param {Number} n an element of the transformation matrix. * @param {Number} o an element of the transformation matrix. * @param {Number} p an element of the transformation matrix. * @chainable */ fn.applyMatrix = function(...args) { let isTypedArray = args[0] instanceof Object.getPrototypeOf(Uint8Array); if (Array.isArray(args[0]) || isTypedArray) { this._renderer.applyMatrix(...args[0]); } else { this._renderer.applyMatrix(...args); } return this; }; /** * Clears all transformations applied to the coordinate system. * * @method resetMatrix * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'Two circles drawn on a gray background. A blue circle is at the top-left and a red circle is at the bottom-right.' * ); * } * * function draw() { * background(200); * * // Translate the origin to the center. * translate(50, 50); * * // Draw a blue circle at the coordinates (25, 25). * fill('blue'); * circle(25, 25, 20); * * // Clear all transformations. * // The origin is now at the top-left corner. * resetMatrix(); * * // Draw a red circle at the coordinates (25, 25). * fill('red'); * circle(25, 25, 20); * } * </code> * </div> */ fn.resetMatrix = function() { this._renderer.resetMatrix(); return this; }; /** * Rotates the coordinate system. * * By default, the positive x-axis points to the right and the positive y-axis * points downward. The `rotate()` function changes this orientation by * rotating the coordinate system about the origin. Everything drawn after * `rotate()` is called will appear to be rotated. * * The first parameter, `angle`, is the amount to rotate. For example, calling * `rotate(1)` rotates the coordinate system clockwise 1 radian which is * nearly 57˚. `rotate()` interprets angle values using the current * <a href="#/p5/angleMode">angleMode()</a>. * * The second parameter, `axis`, is optional. It's used to orient 3D rotations * in WebGL mode. If a <a href="#/p5.Vector">p5.Vector</a> is passed, as in * `rotate(QUARTER_PI, myVector)`, then the coordinate system will rotate * `QUARTER_PI` radians about `myVector`. If an array of vector components is * passed, as in `rotate(QUARTER_PI, [1, 0, 0])`, then the coordinate system * will rotate `QUARTER_PI` radians about a vector with the components * `[1, 0, 0]`. * * By default, transformations accumulate. For example, calling `rotate(1)` * twice has the same effect as calling `rotate(2)` once. The * <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a> functions * can be used to isolate transformations within distinct drawing groups. * * Note: Transformations are reset at the beginning of the draw loop. Calling * `rotate(1)` inside the <a href="#/p5/draw">draw()</a> function won't cause * shapes to spin. * * @method rotate * @param {Number} angle angle of rotation in the current <a href="#/p5/angleMode">angleMode()</a>. * @param {p5.Vector|Number[]} [axis] axis to rotate about in 3D. * @chainable * * @example * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * "A white rectangle on a gray background. The rectangle's long axis runs from top-left to bottom-right." * ); * } * * function draw() { * background(200); * * // Rotate the coordinate system 1/8 turn. * rotate(QUARTER_PI); * * // Draw a rectangle at coordinates (50, 0). * rect(50, 0, 40, 20); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * "A white rectangle on a gray background. The rectangle's long axis runs from top-left to bottom-right." * ); * } * * function draw() { * background(200); * * // Rotate the coordinate system 1/16 turn. * rotate(QUARTER_PI / 2); * * // Rotate the coordinate system another 1/16 turn. * rotate(QUARTER_PI / 2); * * // Draw a rectangle at coordinates (50, 0). * rect(50, 0, 40, 20); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * // Use degrees. * angleMode(DEGREES); * * describe( * "A white rectangle on a gray background. The rectangle's long axis runs from top-left to bottom-right." * ); * } * * function draw() { * background(200); * * // Rotate the coordinate system 1/8 turn. * rotate(45); * * // Draw a rectangle at coordinates (50, 0). * rect(50, 0, 40, 20); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100); * * describe( * 'A white rectangle on a gray background. The rectangle rotates slowly about the top-left corner. It disappears and reappears periodically.' * ); * } * * function draw() { * background(200); * * // Rotate the coordinate system a little more each frame. * let angle = frameCount * 0.01; * rotate(angle); * * // Draw a rectangle at coordinates (50, 0). * rect(50, 0, 40, 20); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe("A cube on a gray background. The cube's front face points to the top-right."); * } * * function draw() { * background(200); * * // Rotate the coordinate system 1/8 turn about * // the axis [1, 1, 0]. * let axis = createVector(1, 1, 0); * rotate(QUARTER_PI, axis); * * // Draw a box. * box(); * } * </code> * </div> * * <div> * <code> * function setup() { * createCanvas(100, 100, WEBGL); * * describe("A cube on a gray background. The cube's front face points to the top-right."); * } * * function draw() { * background(200); * * // Rotate the coordinate system 1/8 turn about * // the axis [1, 1, 0]. * let axis = [1,