diff --git a/package-lock.json b/package-lock.json index 41c96ea8f6..916363530b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "p5", - "version": "2.0.0-beta.7", + "version": "2.0.0-beta.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "p5", - "version": "2.0.0-beta.7", + "version": "2.0.0-beta.8", "license": "LGPL-2.1", "dependencies": { "@davepagurek/bezier-path": "^0.0.2", diff --git a/src/core/p5.Graphics.js b/src/core/p5.Graphics.js index 751ec51fde..7ee9d9306d 100644 --- a/src/core/p5.Graphics.js +++ b/src/core/p5.Graphics.js @@ -9,7 +9,7 @@ import { RGB, HSB, HSL } from '../color/creating_reading'; import primitives2D from '../shape/2d_primitives'; import attributes from '../shape/attributes'; import curves from '../shape/curves'; -import vertex from '../shape/vertex'; +import customShapes from '../shape/custom_shapes'; import setting from '../color/setting'; import image from '../image/image'; import loadingDisplaying from '../image/loading_displaying'; @@ -676,7 +676,7 @@ function graphics(p5, fn){ primitives2D(p5, p5.Graphics.prototype); attributes(p5, p5.Graphics.prototype); curves(p5, p5.Graphics.prototype); - vertex(p5, p5.Graphics.prototype); + customShapes(p5, p5.Graphics.prototype); setting(p5, p5.Graphics.prototype); loadingDisplaying(p5, p5.Graphics.prototype); diff --git a/src/core/package.json b/src/core/package.json new file mode 100644 index 0000000000..96ae6e57eb --- /dev/null +++ b/src/core/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/src/shape/custom_shapes.js b/src/shape/custom_shapes.js index 9eea6efb68..6db68fcc94 100644 --- a/src/shape/custom_shapes.js +++ b/src/shape/custom_shapes.js @@ -6,7 +6,6 @@ * @requires constants */ -// REMINDER: remove .js extension (currently using it to run file locally) import { Color } from '../color/p5.Color'; import { Vector } from '../math/p5.Vector'; import * as constants from '../core/constants'; @@ -1583,25 +1582,1594 @@ function customShapes(p5, fn) { // ---- FUNCTIONS ---- + /** + * Begins creating a hole within a flat shape. + * + * The `beginContour()` and endContour() + * functions allow for creating negative space within custom shapes that are + * flat. `beginContour()` begins adding vertices to a negative space and + * endContour() stops adding them. + * `beginContour()` and endContour() must be + * called between beginShape() and + * endShape(). + * + * Transformations such as translate(), + * rotate(), and scale() + * don't work between `beginContour()` and + * endContour(). It's also not possible to use + * other shapes, such as ellipse() or + * rect(), between `beginContour()` and + * endContour(). + * + * Note: The vertices that define a negative space must "wind" in the opposite + * direction from the outer shape. First, draw vertices for the outer shape + * clockwise order. Then, draw vertices for the negative space in + * counter-clockwise order. + * + * @method beginContour + * + * @example + *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Exterior vertices, clockwise winding.
+ * vertex(10, 10);
+ * vertex(90, 10);
+ * vertex(90, 90);
+ * vertex(10, 90);
+ *
+ * // Interior vertices, counter-clockwise winding.
+ * beginContour();
+ * vertex(30, 30);
+ * vertex(30, 70);
+ * vertex(70, 70);
+ * vertex(70, 30);
+ * endContour();
+ *
+ * // Stop drawing the shape.
+ * endShape(CLOSE);
+ *
+ * describe('A white square with a square hole in its center drawn on a gray background.');
+ * }
+ *
+ *
+ * // Click and drag the mouse to view the scene from different angles.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A white square with a square hole in its center drawn on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Exterior vertices, clockwise winding.
+ * vertex(-40, -40);
+ * vertex(40, -40);
+ * vertex(40, 40);
+ * vertex(-40, 40);
+ *
+ * // Interior vertices, counter-clockwise winding.
+ * beginContour();
+ * vertex(-20, -20);
+ * vertex(-20, 20);
+ * vertex(20, 20);
+ * vertex(20, -20);
+ * endContour();
+ *
+ * // Stop drawing the shape.
+ * endShape(CLOSE);
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add vertices.
+ * vertex(30, 20);
+ * vertex(85, 20);
+ * vertex(85, 75);
+ * vertex(30, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape(CLOSE);
+ *
+ * describe('A white square on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Only draw the vertices (points).
+ * beginShape(POINTS);
+ *
+ * // Add vertices.
+ * vertex(30, 20);
+ * vertex(85, 20);
+ * vertex(85, 75);
+ * vertex(30, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Four black dots that form a square are drawn on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Only draw lines between alternating pairs of vertices.
+ * beginShape(LINES);
+ *
+ * // Add vertices.
+ * vertex(30, 20);
+ * vertex(85, 20);
+ * vertex(85, 75);
+ * vertex(30, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Two horizontal black lines on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Style the shape.
+ * noFill();
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add vertices.
+ * vertex(30, 20);
+ * vertex(85, 20);
+ * vertex(85, 75);
+ * vertex(30, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Three black lines form a sideways U shape on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Style the shape.
+ * noFill();
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add vertices.
+ * vertex(30, 20);
+ * vertex(85, 20);
+ * vertex(85, 75);
+ * vertex(30, 75);
+ *
+ * // Stop drawing the shape.
+ * // Connect the first and last vertices.
+ * endShape(CLOSE);
+ *
+ * describe('A black outline of a square drawn on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Draw a series of triangles.
+ * beginShape(TRIANGLES);
+ *
+ * // Left triangle.
+ * vertex(30, 75);
+ * vertex(40, 20);
+ * vertex(50, 75);
+ *
+ * // Right triangle.
+ * vertex(60, 20);
+ * vertex(70, 75);
+ * vertex(80, 20);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Two white triangles drawn on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Draw a series of triangles.
+ * beginShape(TRIANGLE_STRIP);
+ *
+ * // Add vertices.
+ * vertex(30, 75);
+ * vertex(40, 20);
+ * vertex(50, 75);
+ * vertex(60, 20);
+ * vertex(70, 75);
+ * vertex(80, 20);
+ * vertex(90, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Five white triangles that are interleaved drawn on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Draw a series of triangles that share their first vertex.
+ * beginShape(TRIANGLE_FAN);
+ *
+ * // Add vertices.
+ * vertex(57.5, 50);
+ * vertex(57.5, 15);
+ * vertex(92, 50);
+ * vertex(57.5, 85);
+ * vertex(22, 50);
+ * vertex(57.5, 15);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Four white triangles form a square are drawn on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Draw a series of quadrilaterals.
+ * beginShape(QUADS);
+ *
+ * // Left rectangle.
+ * vertex(30, 20);
+ * vertex(30, 75);
+ * vertex(50, 75);
+ * vertex(50, 20);
+ *
+ * // Right rectangle.
+ * vertex(65, 20);
+ * vertex(65, 75);
+ * vertex(85, 75);
+ * vertex(85, 20);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Two white rectangles drawn on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Draw a series of quadrilaterals.
+ * beginShape(QUAD_STRIP);
+ *
+ * // Add vertices.
+ * vertex(30, 20);
+ * vertex(30, 75);
+ * vertex(50, 20);
+ * vertex(50, 75);
+ * vertex(65, 20);
+ * vertex(65, 75);
+ * vertex(85, 20);
+ * vertex(85, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('Three white rectangles that share edges are drawn on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * // Draw a series of quadrilaterals.
+ * beginShape(PATH);
+ *
+ * // Add the vertices.
+ * vertex(-30, -30, 0);
+ * vertex(30, -30, 0);
+ * vertex(30, -10, 0);
+ * vertex(-10, -10, 0);
+ * vertex(-10, 10, 0);
+ * vertex(30, 10, 0);
+ * vertex(30, 30, 0);
+ * vertex(-30, 30, 0);
+ *
+ * // Stop drawing the shape.
+ * // Connect the first and last vertices.
+ * endShape(CLOSE);
+ *
+ * describe('A blocky C shape drawn in white on a gray background.');
+ * }
+ *
+ *
+ * // Click and drag with the mouse to view the scene from different angles.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A blocky C shape drawn in red, blue, and green on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Start drawing the shape.
+ * // Draw a series of quadrilaterals.
+ * beginShape(PATH);
+ *
+ * // Add the vertices.
+ * fill('red');
+ * stroke('red');
+ * vertex(-30, -30, 0);
+ * vertex(30, -30, 0);
+ * vertex(30, -10, 0);
+ * fill('green');
+ * stroke('green');
+ * vertex(-10, -10, 0);
+ * vertex(-10, 10, 0);
+ * vertex(30, 10, 0);
+ * fill('blue');
+ * stroke('blue');
+ * vertex(30, 30, 0);
+ * vertex(-30, 30, 0);
+ *
+ * // Stop drawing the shape.
+ * // Connect the first and last vertices.
+ * endShape(CLOSE);
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Style the shape.
+ * noFill();
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first anchor point.
+ * vertex(30, 20);
+ *
+ * // Add the Bézier vertex.
+ * bezierVertex(80, 0, 80, 75, 30, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('A black C curve on a gray background.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * strokeWeight(5);
+ * point(30, 20);
+ * point(30, 75);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(80, 0);
+ * point(80, 75);
+ *
+ * // Style the shape.
+ * noFill();
+ * stroke(0);
+ * strokeWeight(1);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first anchor point.
+ * vertex(30, 20);
+ *
+ * // Add the Bézier vertex.
+ * bezierVertex(80, 0, 80, 75, 30, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * // Draw red lines from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * line(30, 20, 80, 0);
+ * line(30, 75, 80, 75);
+ *
+ * describe(
+ * 'A gray square with three curves. A black curve has two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
+ * );
+ * }
+ *
+ *
+ * // Click the mouse near the red dot in the top-right corner
+ * // and drag to change the curve's shape.
+ *
+ * let x2 = 80;
+ * let y2 = 0;
+ * let isChanging = false;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * describe(
+ * 'A gray square with three curves. A black curve has two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * strokeWeight(5);
+ * point(30, 20);
+ * point(30, 75);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(x2, y2);
+ * point(80, 75);
+ *
+ * // Style the shape.
+ * noFill();
+ * stroke(0);
+ * strokeWeight(1);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first anchor point.
+ * vertex(30, 20);
+ *
+ * // Add the Bézier vertex.
+ * bezierVertex(x2, y2, 80, 75, 30, 75);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * // Draw red lines from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * line(30, 20, x2, y2);
+ * line(30, 75, 80, 75);
+ * }
+ *
+ * // Start changing the first control point if the user clicks near it.
+ * function mousePressed() {
+ * if (dist(mouseX, mouseY, x2, y2) < 20) {
+ * isChanging = true;
+ * }
+ * }
+ *
+ * // Stop changing the first control point when the user releases the mouse.
+ * function mouseReleased() {
+ * isChanging = false;
+ * }
+ *
+ * // Update the first control point while the user drags the mouse.
+ * function mouseDragged() {
+ * if (isChanging === true) {
+ * x2 = mouseX;
+ * y2 = mouseY;
+ * }
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first anchor point.
+ * vertex(30, 20);
+ *
+ * // Add the Bézier vertices.
+ * bezierVertex(80, 0, 80, 75, 30, 75);
+ * bezierVertex(50, 80, 60, 25, 30, 20);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('A crescent moon shape drawn in white on a gray background.');
+ * }
+ *
+ *
+ * // Click and drag the mouse to view the scene from different angles.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A crescent moon shape drawn in white on a blue background. When the user drags the mouse, the scene rotates and a second moon is revealed.');
+ * }
+ *
+ * function draw() {
+ * background('midnightblue');
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Style the moons.
+ * noStroke();
+ * fill('lemonchiffon');
+ *
+ * // Draw the first moon.
+ * beginShape();
+ * vertex(-20, -30, 0);
+ * bezierVertex(30, -50, 0, 30, 25, 0, -20, 25, 0);
+ * bezierVertex(0, 30, 0, 10, -25, 0, -20, -30, 0);
+ * endShape();
+ *
+ * // Draw the second moon.
+ * beginShape();
+ * vertex(-20, -30, -20);
+ * bezierVertex(30, -50, -20, 30, 25, -20, -20, 25, -20);
+ * bezierVertex(0, 30, -20, 10, -25, -20, -20, -30, -20);
+ * endShape();
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Exterior vertices, clockwise winding.
+ * vertex(10, 10);
+ * vertex(90, 10);
+ * vertex(90, 90);
+ * vertex(10, 90);
+ *
+ * // Interior vertices, counter-clockwise winding.
+ * beginContour();
+ * vertex(30, 30);
+ * vertex(30, 70);
+ * vertex(70, 70);
+ * vertex(70, 30);
+ * endContour();
+ *
+ * // Stop drawing the shape.
+ * endShape(CLOSE);
+ *
+ * describe('A white square with a square hole in its center drawn on a gray background.');
+ * }
+ *
+ *
+ * // Click and drag the mouse to view the scene from different angles.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A white square with a square hole in its center drawn on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Exterior vertices, clockwise winding.
+ * vertex(-40, -40);
+ * vertex(40, -40);
+ * vertex(40, 40);
+ * vertex(-40, 40);
+ *
+ * // Interior vertices, counter-clockwise winding.
+ * beginContour();
+ * vertex(-20, -20);
+ * vertex(-20, 20);
+ * vertex(20, 20);
+ * vertex(20, -20);
+ * endContour();
+ *
+ * // Stop drawing the shape.
+ * endShape(CLOSE);
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Style the shapes.
+ * noFill();
+ *
+ * // Left triangle.
+ * beginShape();
+ * vertex(20, 20);
+ * vertex(45, 20);
+ * vertex(45, 80);
+ * endShape(CLOSE);
+ *
+ * // Right triangle.
+ * beginShape();
+ * vertex(50, 20);
+ * vertex(75, 20);
+ * vertex(75, 80);
+ * endShape();
+ *
+ * describe(
+ * 'Two sets of black lines drawn on a gray background. The three lines on the left form a right triangle. The two lines on the right form a right angle.'
+ * );
+ * }
+ *
+ *
+ * // Note: A "uniform" is a global variable within a shader program.
+ *
+ * // Create a string with the vertex shader program.
+ * // The vertex shader is called for each vertex.
+ * let vertSrc = `#version 300 es
+ *
+ * precision mediump float;
+ *
+ * in vec3 aPosition;
+ * flat out int instanceID;
+ *
+ * uniform mat4 uModelViewMatrix;
+ * uniform mat4 uProjectionMatrix;
+ *
+ * void main() {
+ *
+ * // Copy the instance ID to the fragment shader.
+ * instanceID = gl_InstanceID;
+ * vec4 positionVec4 = vec4(aPosition, 1.0);
+ *
+ * // gl_InstanceID represents a numeric value for each instance.
+ * // Using gl_InstanceID allows us to move each instance separately.
+ * // Here we move each instance horizontally by ID * 23.
+ * float xOffset = float(gl_InstanceID) * 23.0;
+ *
+ * // Apply the offset to the final position.
+ * gl_Position = uProjectionMatrix * uModelViewMatrix * (positionVec4 -
+ * vec4(xOffset, 0.0, 0.0, 0.0));
+ * }
+ * `;
+ *
+ * // Create a string with the fragment shader program.
+ * // The fragment shader is called for each pixel.
+ * let fragSrc = `#version 300 es
+ *
+ * precision mediump float;
+ *
+ * out vec4 outColor;
+ * flat in int instanceID;
+ * uniform float numInstances;
+ *
+ * void main() {
+ * vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
+ * vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);
+ *
+ * // Normalize the instance ID.
+ * float normId = float(instanceID) / numInstances;
+ *
+ * // Mix between two colors using the normalized instance ID.
+ * outColor = mix(red, blue, normId);
+ * }
+ * `;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Shader object.
+ * let myShader = createShader(vertSrc, fragSrc);
+ *
+ * background(220);
+ *
+ * // Compile and apply the p5.Shader.
+ * shader(myShader);
+ *
+ * // Set the numInstances uniform.
+ * myShader.setUniform('numInstances', 4);
+ *
+ * // Translate the origin to help align the drawing.
+ * translate(25, -10);
+ *
+ * // Style the shapes.
+ * noStroke();
+ *
+ * // Draw the shapes.
+ * beginShape();
+ * vertex(0, 0);
+ * vertex(0, 20);
+ * vertex(20, 20);
+ * vertex(20, 0);
+ * vertex(0, 0);
+ * endShape(CLOSE, 4);
+ *
+ * describe('A row of four squares. Their colors transition from purple on the left to red on the right');
+ * }
+ *
+ *
+ * // Click the and drag the mouse to view the scene from a different angle.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe(
+ * 'A colorful square on a black background. The square changes color and rotates when the user drags the mouse. Parts of its surface reflect light in different directions.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(0);
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Style the shape.
+ * normalMaterial();
+ * noStroke();
+ *
+ * // Draw the shape.
+ * beginShape();
+ * vertex(-30, -30, 0);
+ * vertex(30, -30, 0);
+ * vertex(30, 30, 0);
+ * vertex(-30, 30, 0);
+ * endShape();
+ * }
+ *
+ *
+ * // Click the and drag the mouse to view the scene from a different angle.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe(
+ * 'A colorful square on a black background. The square changes color and rotates when the user drags the mouse. Parts of its surface reflect light in different directions.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(0);
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Style the shape.
+ * normalMaterial();
+ * noStroke();
+ *
+ * // Draw the shape.
+ * // Use normal() to set vertex normals.
+ * beginShape();
+ * normal(-0.4, -0.4, 0.8);
+ * vertex(-30, -30, 0);
+ *
+ * normal(0, 0, 1);
+ * vertex(30, -30, 0);
+ * vertex(30, 30, 0);
+ *
+ * normal(0.4, -0.4, 0.8);
+ * vertex(-30, 30, 0);
+ * endShape();
+ * }
+ *
+ *
+ * // Click the and drag the mouse to view the scene from a different angle.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe(
+ * 'A colorful square on a black background. The square changes color and rotates when the user drags the mouse. Parts of its surface reflect light in different directions.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(0);
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Style the shape.
+ * normalMaterial();
+ * noStroke();
+ *
+ * // Create p5.Vector objects.
+ * let n1 = createVector(-0.4, -0.4, 0.8);
+ * let n2 = createVector(0, 0, 1);
+ * let n3 = createVector(0.4, -0.4, 0.8);
+ *
+ * // Draw the shape.
+ * // Use normal() to set vertex normals.
+ * beginShape();
+ * normal(n1);
+ * vertex(-30, -30, 0);
+ *
+ * normal(n2);
+ * vertex(30, -30, 0);
+ * vertex(30, 30, 0);
+ *
+ * normal(n3);
+ * vertex(-30, 30, 0);
+ * endShape();
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Style the shape.
+ * noFill();
+ * strokeWeight(1);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first control point.
+ * splineVertex(32, 91);
+ *
+ * // Add the anchor points.
+ * splineVertex(21, 17);
+ * splineVertex(68, 19);
+ *
+ * // Add the second control point.
+ * splineVertex(84, 91);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * // Style the anchor and control points.
+ * strokeWeight(5);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * point(21, 17);
+ * point(68, 19);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(32, 91);
+ * point(84, 91);
+ *
+ * describe(
+ * 'A black curve drawn on a gray background. The curve has black dots at its ends. Two red dots appear near the bottom of the canvas.'
+ * );
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Style the shape.
+ * noFill();
+ * strokeWeight(1);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first control point and draw a segment to it.
+ * splineVertex(32, 91);
+ * splineVertex(32, 91);
+ *
+ * // Add the anchor points.
+ * splineVertex(21, 17);
+ * splineVertex(68, 19);
+ *
+ * // Add the second control point.
+ * splineVertex(84, 91);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * // Style the anchor and control points.
+ * strokeWeight(5);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * point(21, 17);
+ * point(68, 19);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(32, 91);
+ * point(84, 91);
+ *
+ * describe(
+ * 'A black curve drawn on a gray background. The curve passes through one red dot and two black dots. Another red dot appears near the bottom of the canvas.'
+ * );
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Style the shape.
+ * noFill();
+ * strokeWeight(1);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first control point and draw a segment to it.
+ * splineVertex(32, 91);
+ * splineVertex(32, 91);
+ *
+ * // Add the anchor points.
+ * splineVertex(21, 17);
+ * splineVertex(68, 19);
+ *
+ * // Add the second control point and draw a segment to it.
+ * splineVertex(84, 91);
+ * splineVertex(84, 91);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * // Style the anchor and control points.
+ * strokeWeight(5);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * point(21, 17);
+ * point(68, 19);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(32, 91);
+ * point(84, 91);
+ *
+ * describe(
+ * 'A black U curve drawn upside down on a gray background. The curve passes from one red dot through two black dots and ends at another red dot.'
+ * );
+ * }
+ *
+ *
+ * // Click the mouse near the red dot in the bottom-left corner
+ * // and drag to change the curve's shape.
+ *
+ * let x1 = 32;
+ * let y1 = 91;
+ * let isChanging = false;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * describe(
+ * 'A black U curve drawn upside down on a gray background. The curve passes from one red dot through two black dots and ends at another red dot.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the shape.
+ * noFill();
+ * stroke(0);
+ * strokeWeight(1);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first control point and draw a segment to it.
+ * splineVertex(x1, y1);
+ * splineVertex(x1, y1);
+ *
+ * // Add the anchor points.
+ * splineVertex(21, 17);
+ * splineVertex(68, 19);
+ *
+ * // Add the second control point and draw a segment to it.
+ * splineVertex(84, 91);
+ * splineVertex(84, 91);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * // Style the anchor and control points.
+ * strokeWeight(5);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * point(21, 17);
+ * point(68, 19);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(x1, y1);
+ * point(84, 91);
+ * }
+ *
+ * // Start changing the first control point if the user clicks near it.
+ * function mousePressed() {
+ * if (dist(mouseX, mouseY, x1, y1) < 20) {
+ * isChanging = true;
+ * }
+ * }
+ *
+ * // Stop changing the first control point when the user releases the mouse.
+ * function mouseReleased() {
+ * isChanging = false;
+ * }
+ *
+ * // Update the first control point while the user drags the mouse.
+ * function mouseDragged() {
+ * if (isChanging === true) {
+ * x1 = mouseX;
+ * y1 = mouseY;
+ * }
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Start drawing the shape.
+ * beginShape();
+ *
+ * // Add the first control point and draw a segment to it.
+ * splineVertex(32, 91);
+ * splineVertex(32, 91);
+ *
+ * // Add the anchor points.
+ * splineVertex(21, 17);
+ * splineVertex(68, 19);
+ *
+ * // Add the second control point.
+ * splineVertex(84, 91);
+ * splineVertex(84, 91);
+ *
+ * // Stop drawing the shape.
+ * endShape();
+ *
+ * describe('A ghost shape drawn in white on a gray background.');
+ * }
+ *
+ *
+ * // Click and drag the mouse to view the scene from different angles.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A ghost shape drawn in white on a blue background. When the user drags the mouse, the scene rotates to reveal the outline of a second ghost.');
+ * }
+ *
+ * function draw() {
+ * background('midnightblue');
+ *
+ * // Enable orbiting with the mouse.
+ * orbitControl();
+ *
+ * // Draw the first ghost.
+ * noStroke();
+ * fill('ghostwhite');
+ *
+ * beginShape();
+ * splineVertex(-28, 41, 0);
+ * splineVertex(-28, 41, 0);
+ * splineVertex(-29, -33, 0);
+ * splineVertex(18, -31, 0);
+ * splineVertex(34, 41, 0);
+ * splineVertex(34, 41, 0);
+ * endShape();
+ *
+ * // Draw the second ghost.
+ * noFill();
+ * stroke('ghostwhite');
+ *
+ * beginShape();
+ * splineVertex(-28, 41, -20);
+ * splineVertex(-28, 41, -20);
+ * splineVertex(-29, -33, -20);
+ * splineVertex(18, -31, -20);
+ * splineVertex(34, 41, -20);
+ * splineVertex(34, 41, -20);
+ * endShape();
+ * }
+ *
+ *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Exterior vertices, clockwise winding.
- * vertex(10, 10);
- * vertex(90, 10);
- * vertex(90, 90);
- * vertex(10, 90);
+ * The first parameter, `propertyName`, is a string with the property's name.
+ * This is the same variable name which should be declared in the shader, such as
+ * `in vec3 aProperty`, similar to .`setUniform()`.
*
- * // Interior vertices, counter-clockwise winding.
- * beginContour();
- * vertex(30, 30);
- * vertex(30, 70);
- * vertex(70, 70);
- * vertex(70, 30);
- * endContour();
+ * The second parameter, `data`, is the value assigned to the shader variable. This
+ * value will be applied to subsequent vertices created with
+ * vertex(). It can be a Number or an array of numbers,
+ * and in the shader program the type can be declared according to the WebGL
+ * specification. Common types include `float`, `vec2`, `vec3`, `vec4` or matrices.
*
- * // Stop drawing the shape.
- * endShape(CLOSE);
+ * See also the vertexProperty() method on
+ * Geometry objects.
*
- * describe('A white square with a square hole in its center drawn on a gray background.');
- * }
- *
- *
- * // Click and drag the mouse to view the scene from different angles.
- *
- * function setup() {
+ * const vertSrc = `#version 300 es
+ * precision mediump float;
+ * uniform mat4 uModelViewMatrix;
+ * uniform mat4 uProjectionMatrix;
+ *
+ * in vec3 aPosition;
+ * in vec2 aOffset;
+ *
+ * void main(){
+ * vec4 positionVec4 = vec4(aPosition.xyz, 1.0);
+ * positionVec4.xy += aOffset;
+ * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
+ * }
+ * `;
+ *
+ * const fragSrc = `#version 300 es
+ * precision mediump float;
+ * out vec4 outColor;
+ * void main(){
+ * outColor = vec4(0.0, 1.0, 1.0, 1.0);
+ * }
+ * `;
+ *
+ * function setup(){
* createCanvas(100, 100, WEBGL);
*
- * describe('A white square with a square hole in its center drawn on a gray background.');
- * }
- *
- * function draw() {
- * background(200);
- *
- * // Enable orbiting with the mouse.
- * orbitControl();
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Exterior vertices, clockwise winding.
- * vertex(-40, -40);
- * vertex(40, -40);
- * vertex(40, 40);
- * vertex(-40, 40);
- *
- * // Interior vertices, counter-clockwise winding.
- * beginContour();
- * vertex(-20, -20);
- * vertex(-20, 20);
- * vertex(20, 20);
- * vertex(20, -20);
- * endContour();
+ * // Create and use the custom shader.
+ * const myShader = createShader(vertSrc, fragSrc);
+ * shader(myShader);
*
- * // Stop drawing the shape.
- * endShape(CLOSE);
+ * describe('A wobbly, cyan circle on a gray background.');
* }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
*
- * background(200);
+ * function draw(){
+ * // Set the styles
+ * background(125);
+ * noStroke();
*
- * // Start drawing the shape.
+ * // Draw the circle.
* beginShape();
- *
- * // Exterior vertices, clockwise winding.
- * vertex(10, 10);
- * vertex(90, 10);
- * vertex(90, 90);
- * vertex(10, 90);
- *
- * // Interior vertices, counter-clockwise winding.
- * beginContour();
- * vertex(30, 30);
- * vertex(30, 70);
- * vertex(70, 70);
- * vertex(70, 30);
- * endContour();
- *
- * // Stop drawing the shape.
+ * for (let i = 0; i < 30; i++){
+ * const x = 40 * cos(i/30 * TWO_PI);
+ * const y = 40 * sin(i/30 * TWO_PI);
+ *
+ * // Apply some noise to the coordinates.
+ * const xOff = 10 * noise(x + millis()/1000) - 5;
+ * const yOff = 10 * noise(y + millis()/1000) - 5;
+ *
+ * // Apply these noise values to the following vertex.
+ * vertexProperty('aOffset', [xOff, yOff]);
+ * vertex(x, y);
+ * }
* endShape(CLOSE);
- *
- * describe('A white square with a square hole in its center drawn on a gray background.');
* }
*
*
- * // Click and drag the mouse to view the scene from different angles.
- *
- * function setup() {
+ * let myShader;
+ * const cols = 10;
+ * const rows = 10;
+ * const cellSize = 6;
+ *
+ * const vertSrc = `#version 300 es
+ * precision mediump float;
+ * uniform mat4 uProjectionMatrix;
+ * uniform mat4 uModelViewMatrix;
+ *
+ * in vec3 aPosition;
+ * in vec3 aNormal;
+ * in vec3 aVertexColor;
+ * in float aDistance;
+ *
+ * out vec3 vVertexColor;
+ *
+ * void main(){
+ * vec4 positionVec4 = vec4(aPosition, 1.0);
+ * positionVec4.xyz += aDistance * aNormal * 2.0;;
+ * vVertexColor = aVertexColor;
+ * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
+ * }
+ * `;
+ *
+ * const fragSrc = `#version 300 es
+ * precision mediump float;
+ *
+ * in vec3 vVertexColor;
+ * out vec4 outColor;
+ *
+ * void main(){
+ * outColor = vec4(vVertexColor, 1.0);
+ * }
+ * `;
+ *
+ * function setup(){
* createCanvas(100, 100, WEBGL);
*
- * describe('A white square with a square hole in its center drawn on a gray background.');
+ * // Create and apply the custom shader.
+ * myShader = createShader(vertSrc, fragSrc);
+ * shader(myShader);
+ * noStroke();
+ * describe('A blue grid, which moves away from the mouse position, on a gray background.');
* }
*
- * function draw() {
+ * function draw(){
* background(200);
*
- * // Enable orbiting with the mouse.
- * orbitControl();
+ * // Draw the grid in the middle of the screen.
+ * translate(-cols*cellSize/2, -rows*cellSize/2);
+ * beginShape(QUADS);
+ * for (let i = 0; i < cols; i++) {
+ * for (let j = 0; j < rows; j++) {
*
- * // Start drawing the shape.
- * beginShape();
+ * // Calculate the cell position.
+ * let x = i * cellSize;
+ * let y = j * cellSize;
*
- * // Exterior vertices, clockwise winding.
- * vertex(-40, -40);
- * vertex(40, -40);
- * vertex(40, 40);
- * vertex(-40, 40);
+ * fill(j/rows*255, j/cols*255, 255);
*
- * // Interior vertices, counter-clockwise winding.
- * beginContour();
- * vertex(-20, -20);
- * vertex(-20, 20);
- * vertex(20, 20);
- * vertex(20, -20);
- * endContour();
+ * // Calculate the distance from the corner of each cell to the mouse.
+ * let distance = dist(x, y, mouseX, mouseY);
*
- * // Stop drawing the shape.
- * endShape(CLOSE);
+ * // Send the distance to the shader.
+ * vertexProperty('aDistance', min(distance, 100));
+ *
+ * vertex(x, y);
+ * vertex(x + cellSize, y);
+ * vertex(x + cellSize, y + cellSize);
+ * vertex(x, y + cellSize);
+ * }
+ * }
+ * endShape();
* }
*
*
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add vertices.
- * vertex(30, 20);
- * vertex(85, 20);
- * vertex(85, 75);
- * vertex(30, 75);
- *
- * // Stop drawing the shape.
- * endShape(CLOSE);
- *
- * describe('A white square on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Only draw the vertices (points).
- * beginShape(POINTS);
- *
- * // Add vertices.
- * vertex(30, 20);
- * vertex(85, 20);
- * vertex(85, 75);
- * vertex(30, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Four black dots that form a square are drawn on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Only draw lines between alternating pairs of vertices.
- * beginShape(LINES);
- *
- * // Add vertices.
- * vertex(30, 20);
- * vertex(85, 20);
- * vertex(85, 75);
- * vertex(30, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Two horizontal black lines on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Style the shape.
- * noFill();
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add vertices.
- * vertex(30, 20);
- * vertex(85, 20);
- * vertex(85, 75);
- * vertex(30, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Three black lines form a sideways U shape on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Style the shape.
- * noFill();
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add vertices.
- * vertex(30, 20);
- * vertex(85, 20);
- * vertex(85, 75);
- * vertex(30, 75);
- *
- * // Stop drawing the shape.
- * // Connect the first and last vertices.
- * endShape(CLOSE);
- *
- * describe('A black outline of a square drawn on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Draw a series of triangles.
- * beginShape(TRIANGLES);
- *
- * // Left triangle.
- * vertex(30, 75);
- * vertex(40, 20);
- * vertex(50, 75);
- *
- * // Right triangle.
- * vertex(60, 20);
- * vertex(70, 75);
- * vertex(80, 20);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Two white triangles drawn on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Draw a series of triangles.
- * beginShape(TRIANGLE_STRIP);
- *
- * // Add vertices.
- * vertex(30, 75);
- * vertex(40, 20);
- * vertex(50, 75);
- * vertex(60, 20);
- * vertex(70, 75);
- * vertex(80, 20);
- * vertex(90, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Five white triangles that are interleaved drawn on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Draw a series of triangles that share their first vertex.
- * beginShape(TRIANGLE_FAN);
- *
- * // Add vertices.
- * vertex(57.5, 50);
- * vertex(57.5, 15);
- * vertex(92, 50);
- * vertex(57.5, 85);
- * vertex(22, 50);
- * vertex(57.5, 15);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Four white triangles form a square are drawn on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Draw a series of quadrilaterals.
- * beginShape(QUADS);
- *
- * // Left rectangle.
- * vertex(30, 20);
- * vertex(30, 75);
- * vertex(50, 75);
- * vertex(50, 20);
- *
- * // Right rectangle.
- * vertex(65, 20);
- * vertex(65, 75);
- * vertex(85, 75);
- * vertex(85, 20);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Two white rectangles drawn on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Draw a series of quadrilaterals.
- * beginShape(QUAD_STRIP);
- *
- * // Add vertices.
- * vertex(30, 20);
- * vertex(30, 75);
- * vertex(50, 20);
- * vertex(50, 75);
- * vertex(65, 20);
- * vertex(65, 75);
- * vertex(85, 20);
- * vertex(85, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('Three white rectangles that share edges are drawn on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * // Draw a series of quadrilaterals.
- * beginShape(PATH);
- *
- * // Add the vertices.
- * vertex(-30, -30, 0);
- * vertex(30, -30, 0);
- * vertex(30, -10, 0);
- * vertex(-10, -10, 0);
- * vertex(-10, 10, 0);
- * vertex(30, 10, 0);
- * vertex(30, 30, 0);
- * vertex(-30, 30, 0);
- *
- * // Stop drawing the shape.
- * // Connect the first and last vertices.
- * endShape(CLOSE);
- *
- * describe('A blocky C shape drawn in white on a gray background.');
- * }
- *
- *
- * // Click and drag with the mouse to view the scene from different angles.
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * describe('A blocky C shape drawn in red, blue, and green on a gray background.');
- * }
- *
- * function draw() {
- * background(200);
- *
- * // Enable orbiting with the mouse.
- * orbitControl();
- *
- * // Start drawing the shape.
- * // Draw a series of quadrilaterals.
- * beginShape(PATH);
- *
- * // Add the vertices.
- * fill('red');
- * stroke('red');
- * vertex(-30, -30, 0);
- * vertex(30, -30, 0);
- * vertex(30, -10, 0);
- * fill('green');
- * stroke('green');
- * vertex(-10, -10, 0);
- * vertex(-10, 10, 0);
- * vertex(30, 10, 0);
- * fill('blue');
- * stroke('blue');
- * vertex(30, 30, 0);
- * vertex(-30, 30, 0);
- *
- * // Stop drawing the shape.
- * // Connect the first and last vertices.
- * endShape(CLOSE);
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Style the shape.
- * noFill();
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first anchor point.
- * vertex(30, 20);
- *
- * // Add the Bézier vertex.
- * bezierVertex(80, 0, 80, 75, 30, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('A black C curve on a gray background.');
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Draw the anchor points in black.
- * stroke(0);
- * strokeWeight(5);
- * point(30, 20);
- * point(30, 75);
- *
- * // Draw the control points in red.
- * stroke(255, 0, 0);
- * point(80, 0);
- * point(80, 75);
- *
- * // Style the shape.
- * noFill();
- * stroke(0);
- * strokeWeight(1);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first anchor point.
- * vertex(30, 20);
- *
- * // Add the Bézier vertex.
- * bezierVertex(80, 0, 80, 75, 30, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * // Draw red lines from the anchor points to the control points.
- * stroke(255, 0, 0);
- * line(30, 20, 80, 0);
- * line(30, 75, 80, 75);
- *
- * describe(
- * 'A gray square with three curves. A black curve has two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
- * );
- * }
- *
- *
- * // Click the mouse near the red dot in the top-right corner
- * // and drag to change the curve's shape.
- *
- * let x2 = 80;
- * let y2 = 0;
- * let isChanging = false;
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * describe(
- * 'A gray square with three curves. A black curve has two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
- * );
- * }
- *
- * function draw() {
- * background(200);
- *
- * // Draw the anchor points in black.
- * stroke(0);
- * strokeWeight(5);
- * point(30, 20);
- * point(30, 75);
- *
- * // Draw the control points in red.
- * stroke(255, 0, 0);
- * point(x2, y2);
- * point(80, 75);
- *
- * // Style the shape.
- * noFill();
- * stroke(0);
- * strokeWeight(1);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first anchor point.
- * vertex(30, 20);
- *
- * // Add the Bézier vertex.
- * bezierVertex(x2, y2, 80, 75, 30, 75);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * // Draw red lines from the anchor points to the control points.
- * stroke(255, 0, 0);
- * line(30, 20, x2, y2);
- * line(30, 75, 80, 75);
- * }
- *
- * // Start changing the first control point if the user clicks near it.
- * function mousePressed() {
- * if (dist(mouseX, mouseY, x2, y2) < 20) {
- * isChanging = true;
- * }
- * }
- *
- * // Stop changing the first control point when the user releases the mouse.
- * function mouseReleased() {
- * isChanging = false;
- * }
- *
- * // Update the first control point while the user drags the mouse.
- * function mouseDragged() {
- * if (isChanging === true) {
- * x2 = mouseX;
- * y2 = mouseY;
- * }
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first anchor point.
- * vertex(30, 20);
- *
- * // Add the Bézier vertices.
- * bezierVertex(80, 0, 80, 75, 30, 75);
- * bezierVertex(50, 80, 60, 25, 30, 20);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('A crescent moon shape drawn in white on a gray background.');
- * }
- *
- *
- * // Click and drag the mouse to view the scene from different angles.
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * describe('A crescent moon shape drawn in white on a blue background. When the user drags the mouse, the scene rotates and a second moon is revealed.');
- * }
- *
- * function draw() {
- * background('midnightblue');
- *
- * // Enable orbiting with the mouse.
- * orbitControl();
- *
- * // Style the moons.
- * noStroke();
- * fill('lemonchiffon');
- *
- * // Draw the first moon.
- * beginShape();
- * vertex(-20, -30, 0);
- * bezierVertex(30, -50, 0, 30, 25, 0, -20, 25, 0);
- * bezierVertex(0, 30, 0, 10, -25, 0, -20, -30, 0);
- * endShape();
- *
- * // Draw the second moon.
- * beginShape();
- * vertex(-20, -30, -20);
- * bezierVertex(30, -50, -20, 30, 25, -20, -20, 25, -20);
- * bezierVertex(0, 30, -20, 10, -25, -20, -20, -30, -20);
- * endShape();
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Style the shape.
- * noFill();
- * strokeWeight(1);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first control point.
- * splineVertex(32, 91);
- *
- * // Add the anchor points.
- * splineVertex(21, 17);
- * splineVertex(68, 19);
- *
- * // Add the second control point.
- * splineVertex(84, 91);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * // Style the anchor and control points.
- * strokeWeight(5);
- *
- * // Draw the anchor points in black.
- * stroke(0);
- * point(21, 17);
- * point(68, 19);
- *
- * // Draw the control points in red.
- * stroke(255, 0, 0);
- * point(32, 91);
- * point(84, 91);
- *
- * describe(
- * 'A black curve drawn on a gray background. The curve has black dots at its ends. Two red dots appear near the bottom of the canvas.'
- * );
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Style the shape.
- * noFill();
- * strokeWeight(1);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first control point and draw a segment to it.
- * splineVertex(32, 91);
- * splineVertex(32, 91);
- *
- * // Add the anchor points.
- * splineVertex(21, 17);
- * splineVertex(68, 19);
- *
- * // Add the second control point.
- * splineVertex(84, 91);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * // Style the anchor and control points.
- * strokeWeight(5);
- *
- * // Draw the anchor points in black.
- * stroke(0);
- * point(21, 17);
- * point(68, 19);
- *
- * // Draw the control points in red.
- * stroke(255, 0, 0);
- * point(32, 91);
- * point(84, 91);
- *
- * describe(
- * 'A black curve drawn on a gray background. The curve passes through one red dot and two black dots. Another red dot appears near the bottom of the canvas.'
- * );
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Style the shape.
- * noFill();
- * strokeWeight(1);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first control point and draw a segment to it.
- * splineVertex(32, 91);
- * splineVertex(32, 91);
- *
- * // Add the anchor points.
- * splineVertex(21, 17);
- * splineVertex(68, 19);
- *
- * // Add the second control point and draw a segment to it.
- * splineVertex(84, 91);
- * splineVertex(84, 91);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * // Style the anchor and control points.
- * strokeWeight(5);
- *
- * // Draw the anchor points in black.
- * stroke(0);
- * point(21, 17);
- * point(68, 19);
- *
- * // Draw the control points in red.
- * stroke(255, 0, 0);
- * point(32, 91);
- * point(84, 91);
- *
- * describe(
- * 'A black U curve drawn upside down on a gray background. The curve passes from one red dot through two black dots and ends at another red dot.'
- * );
- * }
- *
- *
- * // Click the mouse near the red dot in the bottom-left corner
- * // and drag to change the curve's shape.
- *
- * let x1 = 32;
- * let y1 = 91;
- * let isChanging = false;
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * describe(
- * 'A black U curve drawn upside down on a gray background. The curve passes from one red dot through two black dots and ends at another red dot.'
- * );
- * }
- *
- * function draw() {
- * background(200);
- *
- * // Style the shape.
- * noFill();
- * stroke(0);
- * strokeWeight(1);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first control point and draw a segment to it.
- * splineVertex(x1, y1);
- * splineVertex(x1, y1);
- *
- * // Add the anchor points.
- * splineVertex(21, 17);
- * splineVertex(68, 19);
- *
- * // Add the second control point and draw a segment to it.
- * splineVertex(84, 91);
- * splineVertex(84, 91);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * // Style the anchor and control points.
- * strokeWeight(5);
- *
- * // Draw the anchor points in black.
- * stroke(0);
- * point(21, 17);
- * point(68, 19);
- *
- * // Draw the control points in red.
- * stroke(255, 0, 0);
- * point(x1, y1);
- * point(84, 91);
- * }
- *
- * // Start changing the first control point if the user clicks near it.
- * function mousePressed() {
- * if (dist(mouseX, mouseY, x1, y1) < 20) {
- * isChanging = true;
- * }
- * }
- *
- * // Stop changing the first control point when the user releases the mouse.
- * function mouseReleased() {
- * isChanging = false;
- * }
- *
- * // Update the first control point while the user drags the mouse.
- * function mouseDragged() {
- * if (isChanging === true) {
- * x1 = mouseX;
- * y1 = mouseY;
- * }
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Start drawing the shape.
- * beginShape();
- *
- * // Add the first control point and draw a segment to it.
- * splineVertex(32, 91);
- * splineVertex(32, 91);
- *
- * // Add the anchor points.
- * splineVertex(21, 17);
- * splineVertex(68, 19);
- *
- * // Add the second control point.
- * splineVertex(84, 91);
- * splineVertex(84, 91);
- *
- * // Stop drawing the shape.
- * endShape();
- *
- * describe('A ghost shape drawn in white on a gray background.');
- * }
- *
- *
- * // Click and drag the mouse to view the scene from different angles.
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * describe('A ghost shape drawn in white on a blue background. When the user drags the mouse, the scene rotates to reveal the outline of a second ghost.');
- * }
- *
- * function draw() {
- * background('midnightblue');
- *
- * // Enable orbiting with the mouse.
- * orbitControl();
- *
- * // Draw the first ghost.
- * noStroke();
- * fill('ghostwhite');
- *
- * beginShape();
- * splineVertex(-28, 41, 0);
- * splineVertex(-28, 41, 0);
- * splineVertex(-29, -33, 0);
- * splineVertex(18, -31, 0);
- * splineVertex(34, 41, 0);
- * splineVertex(34, 41, 0);
- * endShape();
- *
- * // Draw the second ghost.
- * noFill();
- * stroke('ghostwhite');
- *
- * beginShape();
- * splineVertex(-28, 41, -20);
- * splineVertex(-28, 41, -20);
- * splineVertex(-29, -33, -20);
- * splineVertex(18, -31, -20);
- * splineVertex(34, 41, -20);
- * splineVertex(34, 41, -20);
- * endShape();
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Style the shapes.
- * noFill();
- *
- * // Left triangle.
- * beginShape();
- * vertex(20, 20);
- * vertex(45, 20);
- * vertex(45, 80);
- * endShape(CLOSE);
- *
- * // Right triangle.
- * beginShape();
- * vertex(50, 20);
- * vertex(75, 20);
- * vertex(75, 80);
- * endShape();
- *
- * describe(
- * 'Two sets of black lines drawn on a gray background. The three lines on the left form a right triangle. The two lines on the right form a right angle.'
- * );
- * }
- *
- *
- * // Note: A "uniform" is a global variable within a shader program.
- *
- * // Create a string with the vertex shader program.
- * // The vertex shader is called for each vertex.
- * let vertSrc = `#version 300 es
- *
- * precision mediump float;
- *
- * in vec3 aPosition;
- * flat out int instanceID;
- *
- * uniform mat4 uModelViewMatrix;
- * uniform mat4 uProjectionMatrix;
- *
- * void main() {
- *
- * // Copy the instance ID to the fragment shader.
- * instanceID = gl_InstanceID;
- * vec4 positionVec4 = vec4(aPosition, 1.0);
- *
- * // gl_InstanceID represents a numeric value for each instance.
- * // Using gl_InstanceID allows us to move each instance separately.
- * // Here we move each instance horizontally by ID * 23.
- * float xOffset = float(gl_InstanceID) * 23.0;
- *
- * // Apply the offset to the final position.
- * gl_Position = uProjectionMatrix * uModelViewMatrix * (positionVec4 -
- * vec4(xOffset, 0.0, 0.0, 0.0));
- * }
- * `;
- *
- * // Create a string with the fragment shader program.
- * // The fragment shader is called for each pixel.
- * let fragSrc = `#version 300 es
- *
- * precision mediump float;
- *
- * out vec4 outColor;
- * flat in int instanceID;
- * uniform float numInstances;
- *
- * void main() {
- * vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
- * vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);
- *
- * // Normalize the instance ID.
- * float normId = float(instanceID) / numInstances;
- *
- * // Mix between two colors using the normalized instance ID.
- * outColor = mix(red, blue, normId);
- * }
- * `;
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * // Create a p5.Shader object.
- * let myShader = createShader(vertSrc, fragSrc);
- *
- * background(220);
- *
- * // Compile and apply the p5.Shader.
- * shader(myShader);
- *
- * // Set the numInstances uniform.
- * myShader.setUniform('numInstances', 4);
- *
- * // Translate the origin to help align the drawing.
- * translate(25, -10);
- *
- * // Style the shapes.
- * noStroke();
- *
- * // Draw the shapes.
- * beginShape();
- * vertex(0, 0);
- * vertex(0, 20);
- * vertex(20, 20);
- * vertex(20, 0);
- * vertex(0, 0);
- * endShape(CLOSE, 4);
- *
- * describe('A row of four squares. Their colors transition from purple on the left to red on the right');
- * }
- *
- *
- * // Click the and drag the mouse to view the scene from a different angle.
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * describe(
- * 'A colorful square on a black background. The square changes color and rotates when the user drags the mouse. Parts of its surface reflect light in different directions.'
- * );
- * }
- *
- * function draw() {
- * background(0);
- *
- * // Enable orbiting with the mouse.
- * orbitControl();
- *
- * // Style the shape.
- * normalMaterial();
- * noStroke();
- *
- * // Draw the shape.
- * beginShape();
- * vertex(-30, -30, 0);
- * vertex(30, -30, 0);
- * vertex(30, 30, 0);
- * vertex(-30, 30, 0);
- * endShape();
- * }
- *
- *
- * // Click the and drag the mouse to view the scene from a different angle.
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * describe(
- * 'A colorful square on a black background. The square changes color and rotates when the user drags the mouse. Parts of its surface reflect light in different directions.'
- * );
- * }
- *
- * function draw() {
- * background(0);
- *
- * // Enable orbiting with the mouse.
- * orbitControl();
- *
- * // Style the shape.
- * normalMaterial();
- * noStroke();
- *
- * // Draw the shape.
- * // Use normal() to set vertex normals.
- * beginShape();
- * normal(-0.4, -0.4, 0.8);
- * vertex(-30, -30, 0);
- *
- * normal(0, 0, 1);
- * vertex(30, -30, 0);
- * vertex(30, 30, 0);
- *
- * normal(0.4, -0.4, 0.8);
- * vertex(-30, 30, 0);
- * endShape();
- * }
- *
- *
- * // Click the and drag the mouse to view the scene from a different angle.
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * describe(
- * 'A colorful square on a black background. The square changes color and rotates when the user drags the mouse. Parts of its surface reflect light in different directions.'
- * );
- * }
- *
- * function draw() {
- * background(0);
- *
- * // Enable orbiting with the mouse.
- * orbitControl();
- *
- * // Style the shape.
- * normalMaterial();
- * noStroke();
- *
- * // Create p5.Vector objects.
- * let n1 = createVector(-0.4, -0.4, 0.8);
- * let n2 = createVector(0, 0, 1);
- * let n3 = createVector(0.4, -0.4, 0.8);
- *
- * // Draw the shape.
- * // Use normal() to set vertex normals.
- * beginShape();
- * normal(n1);
- * vertex(-30, -30, 0);
- *
- * normal(n2);
- * vertex(30, -30, 0);
- * vertex(30, 30, 0);
- *
- * normal(n3);
- * vertex(-30, 30, 0);
- * endShape();
- * }
- *
- *
- * const vertSrc = `#version 300 es
- * precision mediump float;
- * uniform mat4 uModelViewMatrix;
- * uniform mat4 uProjectionMatrix;
- *
- * in vec3 aPosition;
- * in vec2 aOffset;
- *
- * void main(){
- * vec4 positionVec4 = vec4(aPosition.xyz, 1.0);
- * positionVec4.xy += aOffset;
- * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
- * }
- * `;
- *
- * const fragSrc = `#version 300 es
- * precision mediump float;
- * out vec4 outColor;
- * void main(){
- * outColor = vec4(0.0, 1.0, 1.0, 1.0);
- * }
- * `;
- *
- * function setup(){
- * createCanvas(100, 100, WEBGL);
- *
- * // Create and use the custom shader.
- * const myShader = createShader(vertSrc, fragSrc);
- * shader(myShader);
- *
- * describe('A wobbly, cyan circle on a gray background.');
- * }
- *
- * function draw(){
- * // Set the styles
- * background(125);
- * noStroke();
- *
- * // Draw the circle.
- * beginShape();
- * for (let i = 0; i < 30; i++){
- * const x = 40 * cos(i/30 * TWO_PI);
- * const y = 40 * sin(i/30 * TWO_PI);
- *
- * // Apply some noise to the coordinates.
- * const xOff = 10 * noise(x + millis()/1000) - 5;
- * const yOff = 10 * noise(y + millis()/1000) - 5;
- *
- * // Apply these noise values to the following vertex.
- * vertexProperty('aOffset', [xOff, yOff]);
- * vertex(x, y);
- * }
- * endShape(CLOSE);
- * }
- *
- *
- * let myShader;
- * const cols = 10;
- * const rows = 10;
- * const cellSize = 6;
- *
- * const vertSrc = `#version 300 es
- * precision mediump float;
- * uniform mat4 uProjectionMatrix;
- * uniform mat4 uModelViewMatrix;
- *
- * in vec3 aPosition;
- * in vec3 aNormal;
- * in vec3 aVertexColor;
- * in float aDistance;
- *
- * out vec3 vVertexColor;
- *
- * void main(){
- * vec4 positionVec4 = vec4(aPosition, 1.0);
- * positionVec4.xyz += aDistance * aNormal * 2.0;;
- * vVertexColor = aVertexColor;
- * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
- * }
- * `;
- *
- * const fragSrc = `#version 300 es
- * precision mediump float;
- *
- * in vec3 vVertexColor;
- * out vec4 outColor;
- *
- * void main(){
- * outColor = vec4(vVertexColor, 1.0);
- * }
- * `;
- *
- * function setup(){
- * createCanvas(100, 100, WEBGL);
- *
- * // Create and apply the custom shader.
- * myShader = createShader(vertSrc, fragSrc);
- * shader(myShader);
- * noStroke();
- * describe('A blue grid, which moves away from the mouse position, on a gray background.');
- * }
- *
- * function draw(){
- * background(200);
- *
- * // Draw the grid in the middle of the screen.
- * translate(-cols*cellSize/2, -rows*cellSize/2);
- * beginShape(QUADS);
- * for (let i = 0; i < cols; i++) {
- * for (let j = 0; j < rows; j++) {
- *
- * // Calculate the cell position.
- * let x = i * cellSize;
- * let y = j * cellSize;
- *
- * fill(j/rows*255, j/cols*255, 255);
- *
- * // Calculate the distance from the corner of each cell to the mouse.
- * let distance = dist(x, y, mouseX, mouseY);
- *
- * // Send the distance to the shader.
- * vertexProperty('aDistance', min(distance, 100));
- *
- * vertex(x, y);
- * vertex(x + cellSize, y);
- * vertex(x + cellSize, y + cellSize);
- * vertex(x, y + cellSize);
- * }
- * }
- * endShape();
- * }
- *
- *