diff --git a/src/webgl/p5.Camera.js b/src/webgl/p5.Camera.js index b096af803c..ce91926fa3 100644 --- a/src/webgl/p5.Camera.js +++ b/src/webgl/p5.Camera.js @@ -11,105 +11,132 @@ import p5 from '../core/main'; //////////////////////////////////////////////////////////////////////////////// /** - * Sets the position of the current camera in a 3D sketch. - * Parameters for this function define the camera's position, - * the center of the sketch (where the camera is pointing), - * and an up direction (the orientation of the camera). - * - * This function simulates the movements of the camera, allowing objects to be - * viewed from various angles. Remember, it does not move the objects themselves - * but the camera instead. For example when the centerX value is positive, - * and the camera is rotating to the right side of the sketch, - * the object will seem like it's moving to the left. - * - * See this example - * to view the position of your camera. - * - * If no parameters are given, the following default is used: - * camera(0, 0, 800, 0, 0, 0, 0, 1, 0) + * Sets the position and orientation of the current camera in a 3D sketch. + * + * `camera()` allows objects to be viewed from different angles. It has nine + * parameters that are all optional. + * + * The first three parameters, `x`, `y`, and `z`, are the coordinates of the + * camera’s position. For example, calling `camera(0, 0, 0)` places the camera + * at the origin `(0, 0, 0)`. By default, the camera is placed at + * `(0, 0, 800)`. + * + * The next three parameters, `centerX`, `centerY`, and `centerZ` are the + * coordinates of the point where the camera faces. For example, calling + * `camera(0, 0, 0, 10, 20, 30)` places the camera at the origin `(0, 0, 0)` + * and points it at `(10, 20, 30)`. By default, the camera points at the + * origin `(0, 0, 0)`. + * + * The last three parameters, `upX`, `upY`, and `upZ` are the components of + * the "up" vector. The "up" vector orients the camera’s y-axis. For example, + * calling `camera(0, 0, 0, 10, 20, 30, 0, -1, 0)` places the camera at the + * origin `(0, 0, 0)`, points it at `(10, 20, 30)`, and sets the "up" vector + * to `(0, -1, 0)` which is like holding it upside-down. By default, the "up" + * vector is `(0, 1, 0)`. + * + * Note: `camera()` can only be used in WebGL mode. + * * @method camera * @constructor * @for p5 - * @param {Number} [x] camera position value on x axis - * @param {Number} [y] camera position value on y axis - * @param {Number} [z] camera position value on z axis - * @param {Number} [centerX] x coordinate representing center of the sketch - * @param {Number} [centerY] y coordinate representing center of the sketch - * @param {Number} [centerZ] z coordinate representing center of the sketch - * @param {Number} [upX] x component of direction 'up' from camera - * @param {Number} [upY] y component of direction 'up' from camera - * @param {Number} [upZ] z component of direction 'up' from camera + * @param {Number} [x] x-coordinate of the camera. Defaults to 0. + * @param {Number} [y] y-coordinate of the camera. Defaults to 0. + * @param {Number} [z] z-coordinate of the camera. Defaults to 800. + * @param {Number} [centerX] x-coordinate of the point the camera faces. Defaults to 0. + * @param {Number} [centerY] y-coordinate of the point the camera faces. Defaults to 0. + * @param {Number} [centerZ] z-coordinate of the point the camera faces. Defaults to 0. + * @param {Number} [upX] x-component of the camera’s "up" vector. Defaults to 0. + * @param {Number} [upY] y-component of the camera’s "up" vector. Defaults to 1. + * @param {Number} [upZ] z-component of the camera’s "up" vector. Defaults to 0. * @chainable + * * @example *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * describe('a square moving closer and then away from the camera.');
+ *
+ * describe('A white cube on a gray background.');
* }
+ *
* function draw() {
- * background(204);
- * //move the camera away from the plane by a sin wave
- * camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);
- * plane(10, 10);
+ * background(200);
+ *
+ * // Move the camera to the top-right.
+ * camera(200, -400, 800);
+ *
+ * // Draw the box.
+ * box();
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A white cube apperas to sway left and right on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Calculate the camera's x-coordinate.
+ * let x = 400 * cos(frameCount * 0.01);
+ *
+ * // Orbit the camera around the box.
+ * camera(x, -400, 800);
+ *
+ * // Draw the box.
+ * box();
* }
*
*
- * //move slider to see changes!
- * //sliders control the first 6 parameters of camera()
- * let sliderGroup = [];
- * let X;
- * let Y;
- * let Z;
- * let centerX;
- * let centerY;
- * let centerZ;
- * let h = 20;
+ * // Adjust the range sliders to change the camera's position.
+ *
+ * let xSlider;
+ * let ySlider;
+ * let zSlider;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * //create sliders
- * for (var i = 0; i < 6; i++) {
- * if (i === 2) {
- * sliderGroup[i] = createSlider(10, 400, 200);
- * } else {
- * sliderGroup[i] = createSlider(-400, 400, 0);
- * }
- * h = map(i, 0, 6, 5, 85);
- * sliderGroup[i].position(10, height + h);
- * sliderGroup[i].style('width', '80px');
- * }
+ *
+ * // Create slider objects to set the camera's coordinates.
+ * xSlider = createSlider(-400, 400, 400);
+ * xSlider.position(0, 100);
+ * xSlider.size(100);
+ * ySlider = createSlider(-400, 400, -200);
+ * ySlider.position(0, 120);
+ * ySlider.size(100);
+ * zSlider = createSlider(0, 1600, 800);
+ * zSlider.position(0, 140);
+ * zSlider.size(100);
+ *
* describe(
- * 'White square repeatedly grows to fill canvas and then shrinks. An interactive example of a red cube with 3 sliders for moving it across x, y, z axis and 3 sliders for shifting its center.'
+ * 'A white cube drawn against a gray background. Three range sliders appear beneath the image. The camera position changes when the user moves the sliders.'
* );
* }
*
* function draw() {
- * background(60);
- * // assigning sliders' value to each parameters
- * X = sliderGroup[0].value();
- * Y = sliderGroup[1].value();
- * Z = sliderGroup[2].value();
- * centerX = sliderGroup[3].value();
- * centerY = sliderGroup[4].value();
- * centerZ = sliderGroup[5].value();
- * camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);
- * stroke(255);
- * fill(255, 102, 94);
- * box(85);
+ * background(200);
+ *
+ * // Get the camera's coordinates from the sliders.
+ * let x = xSlider.value();
+ * let y = ySlider.value();
+ * let z = zSlider.value();
+ *
+ * // Move the camera.
+ * camera(x, y, z);
+ *
+ * // Draw the box.
+ * box();
* }
*
*
- * //drag the mouse to look around!
+ * // Double-click to squeeze the box.
+ *
+ * let isSqueezed = false;
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * perspective(PI / 3.0, width / height, 0.1, 500);
- * describe(
- * 'two colored 3D boxes move back and forth, rotating as mouse is dragged.'
- * );
+ *
+ * describe('A white rectangular prism on a gray background. The box appears to become thinner when the user double-clicks.');
* }
+ *
* function draw() {
* background(200);
- * orbitControl();
- * normalMaterial();
*
- * rotateX(-0.3);
- * rotateY(-0.2);
- * translate(0, 0, -50);
+ * // Place the camera at the top-right.
+ * camera(400, -400, 800);
*
- * push();
- * translate(-15, 0, sin(frameCount / 30) * 65);
- * box(30);
- * pop();
- * push();
- * translate(15, 0, sin(frameCount / 30 + PI) * 65);
- * box(30);
- * pop();
+ * if (isSqueezed === true) {
+ * // Set fovy to 0.2.
+ * // Set aspect to 1.5.
+ * perspective(0.2, 1.5);
+ * }
+ *
+ * // Draw the box.
+ * box();
+ * }
+ *
+ * // Change the camera's perspective when the user double-clicks.
+ * function doubleClicked() {
+ * isSqueezed = true;
* }
*
*
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A white rectangular prism on a gray background. The prism moves away from the camera until it disappears.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Place the camera at the top-right.
+ * camera(400, -400, 800);
+ *
+ * // Set fovy to 0.2.
+ * // Set aspect to 1.5.
+ * // Set near to 600.
+ * // Set far to 1200.
+ * perspective(0.2, 1.5, 600, 1200);
+ *
+ * // Move the origin away from the camera.
+ * let x = -frameCount;
+ * let y = frameCount;
+ * let z = -2 * frameCount;
+ * translate(x, y, z);
+ *
+ * // Draw the box.
+ * box();
+ * }
+ *
+ *
+ * // Double-click the canvas to toggle the line perspective.
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * setAttributes({ antialias: true });
- * strokeWeight(3);
+ *
* describe(
- * 'rotated 3D boxes have their stroke weights affected if toggled back and forth with mouse clicks.'
+ * 'A white cube with black edges on a gray background. Its edges toggle between thick and thin when the user double-clicks.'
* );
* }
*
* function draw() {
- * background(220);
- * rotateY(PI/24);
- * rotateZ(PI/8);
- * translate(0, 0, 350);
- * for (let i = 0; i < 12; i++) {
- * translate(0, 0, -70);
- * box(30);
+ * background(200);
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 600);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
* }
* }
*
- * function mousePressed() {
- * linePerspective(!linePerspective());
+ * // Toggle the line perspective when the user double-clicks.
+ * function doubleClicked() {
+ * let isEnabled = linePerspective();
+ * linePerspective(!isEnabled);
* }
*
*
+ * // Double-click the canvas to toggle the line perspective.
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * strokeWeight(4);
+ *
+ * describe(
+ * 'A row of cubes with black edges on a gray background. Their edges toggle between thick and thin when the user double-clicks.'
+ * );
* }
*
* function draw() {
- * background(220);
+ * background(200);
*
- * // Using orthographic projection
+ * // Use an orthographic projection.
* ortho();
*
- * // Enable line perspective explicitly
- * linePerspective(true);
- *
- * // Draw a rotating cube
- * rotateX(frameCount * 0.01);
- * rotateY(frameCount * 0.01);
- * box(25);
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 600);
*
- * // Move to a new position
- * translate(0, -60, 0);
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
*
- * // Using perspective projection
- * perspective();
- *
- * // Disable line perspective explicitly
- * linePerspective(false);
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
+ * }
+ * }
*
- * // Draw another rotating cube with perspective
- * rotateX(frameCount * 0.01);
- * rotateY(frameCount * 0.01);
- * box(25);
+ * // Toggle the line perspective when the user double-clicks.
+ * function doubleClicked() {
+ * let isEnabled = linePerspective();
+ * linePerspective(!isEnabled);
* }
*
*
- * //drag the mouse to look around!
- * //there's no vanishing point
* function setup() {
* createCanvas(100, 100, WEBGL);
- * ortho();
- * describe(
- * 'two 3D boxes move back and forth along same plane, rotating as mouse is dragged.'
- * );
+ *
+ * describe('A row of tiny, white cubes on a gray background. All the cubes appear the same size.');
* }
+ *
* function draw() {
* background(200);
- * orbitControl();
- * normalMaterial();
*
- * rotateX(0.2);
- * rotateY(-0.2);
- * push();
- * translate(-15, 0, sin(frameCount / 30) * 65);
- * box(30);
- * pop();
- * push();
- * translate(15, 0, sin(frameCount / 30 + PI) * 65);
- * box(30);
- * pop();
+ * // Apply an orthographic projection.
+ * ortho();
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 600);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
+ * }
* }
*
*
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A white cube on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Apply an orthographic projection.
+ * // Center the frustum.
+ * // Set its width and height to 20.
+ * // Place its near plane 300 pixels from the camera.
+ * // Place its far plane 350 pixels from the camera.
+ * ortho(-10, 10, -10, 10, 300, 350);
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 600);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
+ * }
+ * }
+ *
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * setAttributes('antialias', true);
- * camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);
- * describe(
- * 'two 3D boxes move back and forth along same plane, rotating as mouse is dragged.'
- * );
+ *
+ * describe('A row of white cubes on a gray background.');
* }
+ *
* function draw() {
* background(200);
- * orbitControl();
- * normalMaterial();
*
- * rotateY(-0.2);
- * rotateX(-0.3);
- * push();
- * translate(-15, 0, sin(frameCount / 30) * 25);
- * box(30);
- * pop();
- * push();
- * translate(15, 0, sin(frameCount / 30 + PI) * 25);
- * box(30);
- * pop();
+ * // Apply the default frustum projection.
+ * frustum();
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 600);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
+ * }
* }
*
*
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * describe('A white cube on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Adjust the frustum.
+ * // Center it.
+ * // Set its width and height to 20 pixels.
+ * // Place its near plane 300 pixels from the camera.
+ * // Place its far plane 350 pixels from the camera.
+ * frustum(-10, 10, -10, 10, 300, 350);
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 600);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
+ * }
+ * }
+ *
+ *
- * // Creates a camera object and animates it around a box.
- * let camera;
+ *
+ *
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let usingCam1 = true;
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * background(0);
- * camera = createCamera();
- * camera.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * camera.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * describe('An example that creates a camera and moves it around the box.');
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * // Place it at the top-left.
+ * // Point it at the origin.
+ * cam2 = createCamera();
+ * cam2.setPosition(400, -400, 800);
+ * cam2.lookAt(0, 0, 0);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe('A white cube on a gray background. The camera toggles between frontal and aerial views when the user double-clicks.');
* }
*
* function draw() {
- * background(0);
- * // The camera will automatically
- * // rotate to look at [0, 0, 0].
- * camera.lookAt(0, 0, 0);
- *
- * // The camera will move on the
- * // x axis.
- * camera.setPosition(sin(frameCount / 60) * 200, 0, 100);
- * box(20);
+ * background(200);
*
- * // A 'ground' box to give the viewer
- * // a better idea of where the camera
- * // is looking.
- * translate(0, 50, 0);
- * rotateX(HALF_PI);
- * box(150, 150, 20);
+ * // Draw the box.
+ * box();
* }
- *
*
- * @alt
- * An example that creates a camera and moves it around the box.
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (usingCam1 === true) {
+ * setCamera(cam2);
+ * usingCam1 = false;
+ * } else {
+ * setCamera(cam1);
+ * usingCam1 = true;
+ * }
+ * }
+ *
+ * eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ
- * which describes camera position, orientation, and projection
- * are also accessible via the camera object generated using
- * createCamera()
+ * A class to describe a camera for viewing a 3D sketch.
+ *
+ * Each `p5.Camera` object represents a camera that views a section of 3D
+ * space. It stores information about the camera’s position, orientation, and
+ * projection.
+ *
+ * In WebGL mode, the default camera is a `p5.Camera` object that can be
+ * controlled with the camera(),
+ * perspective(),
+ * ortho(), and
+ * frustum() functions. Additional cameras can be
+ * created with createCamera() and activated
+ * with setCamera().
+ *
+ * Note: `p5.Camera`’s methods operate in two coordinate systems:
+ * - The “world” coordinate system describes positions in terms of their
+ * relationship to the origin along the x-, y-, and z-axes. For example,
+ * calling `myCamera.setPosition()` places the camera in 3D space using
+ * "world" coordinates.
+ * - The "local" coordinate system describes positions from the camera's point
+ * of view: left-right, up-down, and forward-backward. For example, calling
+ * `myCamera.move()` moves the camera along its own axes.
*
* @class p5.Camera
* @param {rendererGL} rendererGL instance of WebGL renderer
+ *
* @example
*
* let cam;
- * let delta = 0.01;
+ * let delta = 0.001;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * normalMaterial();
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // set initial pan angle
- * cam.pan(-0.8);
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
* describe(
- * 'camera view pans left and right across a series of rotating 3D boxes.'
+ * 'A white cube on a gray background. The cube goes in and out of view as the camera pans left and right.'
* );
* }
*
* function draw() {
* background(200);
*
- * // pan camera according to angle 'delta'
+ * // Turn the camera left and right, called "panning".
* cam.pan(delta);
*
- * // every 160 frames, switch direction
- * if (frameCount % 160 === 0) {
+ * // Switch directions every 120 frames.
+ * if (frameCount % 120 === 0) {
* delta *= -1;
* }
*
- * rotateX(frameCount * 0.01);
- * translate(-100, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
+ * // Draw the box.
+ * box();
* }
*
*
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * // Place it at the top-left.
+ * // Point it at the origin.
+ * cam2 = createCamera();
+ * cam2.setPosition(400, -400, 800);
+ * cam2.lookAt(0, 0, 0);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe(
+ * 'A white cube on a gray background. The camera toggles between frontal and aerial views when the user double-clicks.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Draw the box.
+ * box();
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
*
- *
- * let cam, div;
* function setup() {
* createCanvas(100, 100, WEBGL);
- * background(0);
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * div = createDiv();
- * div.position(0, 0);
- * describe('An example showing the use of camera object properties');
- * }
*
- * function draw() {
- * orbitControl();
- * box(10);
- * div.html('eyeX = ' + cam.eyeX);
- * }
- *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
*
- * @alt
- * An example showing the use of camera object properties
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
*
- */
-
- /**
- * camera position value on y axis. default value is 0
- * @property {Number} eyeY
- * @readonly
- * @example
- *
- * let cam, div;
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- * background(0);
- * cam = createCamera();
- * div = createDiv();
- * div.position(0, 0);
- * describe('An example showing the use of camera object properties');
+ * describe(
+ * 'A white cube on a gray background. The text "eyeX: 0" is written in black beneath it.'
+ * );
* }
*
* function draw() {
- * orbitControl();
- * box(10);
- * div.html('eyeY = ' + cam.eyeY);
- * }
- *
+ * background(200);
*
- * @alt
- * An example showing the use of camera object properties
+ * // Style the box.
+ * fill(255);
*
- */
-
- /**
- * camera position value on z axis. default value is 800
- * @property {Number} eyeZ
- * @readonly
- * @example
- *
- * let cam, div;
- * function setup() {
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of eyeX, rounded to the nearest integer.
+ * text(`eyeX: ${round(cam.eyeX)}`, 0, 55);
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to move left and right as the camera moves. The text "eyeX: X" is written in black beneath the cube. X oscillates between -25 and 25.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the new x-coordinate.
+ * let x = 25 * sin(frameCount * 0.01);
+ *
+ * // Set the camera's position.
+ * cam.setPosition(x, -400, 800);
+ *
+ * // Display the value of eyeX, rounded to the nearest integer.
+ * text(`eyeX: ${round(cam.eyeX)}`, 0, 55);
+ * }
+ *
+ *
+ */
+
+ /**
+ * The camera’s y-coordinate.
+ *
+ * By default, the camera’s y-coordinate is set to 0 in "world" space.
+ *
+ * @property {Number} eyeY
+ * @readonly
+ *
+ * @example
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "eyeY: -400" is written in black beneath it.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of eyeY, rounded to the nearest integer.
+ * text(`eyeX: ${round(cam.eyeY)}`, 0, 55);
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
* createCanvas(100, 100, WEBGL);
- * background(0);
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * div = createDiv();
- * div.position(0, 0);
- * describe('An example showing the use of camera object properties');
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to move up and down as the camera moves. The text "eyeY: Y" is written in black beneath the cube. Y oscillates between -374 and -425.'
+ * );
* }
*
* function draw() {
- * orbitControl();
- * box(10);
- * div.html('eyeZ = ' + cam.eyeZ);
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the new y-coordinate.
+ * let y = 25 * sin(frameCount * 0.01) - 400;
+ *
+ * // Set the camera's position.
+ * cam.setPosition(0, y, 800);
+ *
+ * // Display the value of eyeY, rounded to the nearest integer.
+ * text(`eyeY: ${round(cam.eyeY)}`, 0, 55);
* }
- *
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "eyeZ: 800" is written in black beneath it.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of eyeZ, rounded to the nearest integer.
+ * text(`eyeZ: ${round(cam.eyeZ)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to move forward and back as the camera moves. The text "eyeZ: Z" is written in black beneath the cube. Z oscillates between 700 and 900.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the new z-coordinate.
+ * let z = 100 * sin(frameCount * 0.01) + 800;
+ *
+ * // Set the camera's position.
+ * cam.setPosition(0, -400, z);
+ *
+ * // Display the value of eyeZ, rounded to the nearest integer.
+ * text(`eyeZ: ${round(cam.eyeZ)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at (10, 20, -30).
+ * cam.lookAt(10, 20, -30);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "centerX: 10" is written in black beneath it.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of centerX, rounded to the nearest integer.
+ * text(`centerX: ${round(cam.centerX)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-right.
+ * cam.setPosition(100, -400, 800);
+ *
+ * // Point the camera at (10, 20, -30).
+ * cam.lookAt(10, 20, -30);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to move left and right as the camera shifts its focus. The text "centerX: X" is written in black beneath the cube. X oscillates between -15 and 35.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the new x-coordinate.
+ * let x = 25 * sin(frameCount * 0.01) + 10;
+ *
+ * // Point the camera.
+ * cam.lookAt(x, 20, -30);
+ *
+ * // Display the value of centerX, rounded to the nearest integer.
+ * text(`centerX: ${round(cam.centerX)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at (10, 20, -30).
+ * cam.lookAt(10, 20, -30);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "centerY: 20" is written in black beneath it.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of centerY, rounded to the nearest integer.
+ * text(`centerY: ${round(cam.centerY)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-right.
+ * cam.setPosition(100, -400, 800);
+ *
+ * // Point the camera at (10, 20, -30).
+ * cam.lookAt(10, 20, -30);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to move up and down as the camera shifts its focus. The text "centerY: Y" is written in black beneath the cube. Y oscillates between -5 and 45.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the new y-coordinate.
+ * let y = 25 * sin(frameCount * 0.01) + 20;
+ *
+ * // Point the camera.
+ * cam.lookAt(10, y, -30);
+ *
+ * // Display the value of centerY, rounded to the nearest integer.
+ * text(`centerY: ${round(cam.centerY)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at (10, 20, -30).
+ * cam.lookAt(10, 20, -30);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "centerZ: -30" is written in black beneath it.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of centerZ, rounded to the nearest integer.
+ * text(`centerZ: ${round(cam.centerZ)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-right.
+ * cam.setPosition(100, -400, 800);
+ *
+ * // Point the camera at (10, 20, -30).
+ * cam.lookAt(10, 20, -30);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to move forward and back as the camera shifts its focus. The text "centerZ: Z" is written in black beneath the cube. Z oscillates between -55 and -25.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the new z-coordinate.
+ * let z = 25 * sin(frameCount * 0.01) - 30;
+ *
+ * // Point the camera.
+ * cam.lookAt(10, 20, z);
+ *
+ * // Display the value of centerZ, rounded to the nearest integer.
+ * text(`centerZ: ${round(cam.centerZ)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-right: (100, -400, 800)
+ * // Point it at the origin: (0, 0, 0)
+ * // Set its "up" vector: (0, 1, 0).
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, 1, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "upX: 0" is written in black beneath it.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of upX, rounded to the nearest tenth.
+ * text(`upX: ${round(cam.upX, 1)}`, 0, 55);
+ * }
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create a p5.Camera object.
+ * cam = createCamera();
+ *
+ * // Place the camera at the top-right: (100, -400, 800)
+ * // Point it at the origin: (0, 0, 0)
+ * // Set its "up" vector: (0, 1, 0).
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, 1, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to rock back and forth. The text "upX: X" is written in black beneath it. X oscillates between -1 and 1.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the x-component.
+ * let x = sin(frameCount * 0.01);
*
- * @alt
- * An example showing the use of camera object properties
+ * // Update the camera's "up" vector.
+ * cam.camera(100, -400, 800, 0, 0, 0, x, 1, 0);
*
+ * // Display the value of upX, rounded to the nearest tenth.
+ * text(`upX: ${round(cam.upX, 1)}`, 0, 55);
+ * }
+ *
+ *
- * let cam, div;
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * background(255);
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * cam.lookAt(1, 0, 0);
- * div = createDiv('centerX = ' + cam.centerX);
- * div.position(0, 0);
- * div.style('color', 'white');
- * describe('An example showing the use of camera object properties');
+ *
+ * // Place the camera at the top-right: (100, -400, 800)
+ * // Point it at the origin: (0, 0, 0)
+ * // Set its "up" vector: (0, 1, 0).
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, 1, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "upY: 1" is written in black beneath it.'
+ * );
* }
*
* function draw() {
- * orbitControl();
- * box(10);
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Display the value of upY, rounded to the nearest tenth.
+ * text(`upY: ${round(cam.upY, 1)}`, 0, 55);
* }
- *
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
*
- */
-
- /**
- * y coordinate representing center of the sketch
- * @property {Number} centerY
- * @readonly
- * @example
- *
- * let cam, div;
* function setup() {
* createCanvas(100, 100, WEBGL);
- * background(255);
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * cam.lookAt(0, 1, 0);
- * div = createDiv('centerY = ' + cam.centerY);
- * div.position(0, 0);
- * div.style('color', 'white');
- * describe('An example showing the use of camera object properties');
+ *
+ * // Place the camera at the top-right: (100, -400, 800)
+ * // Point it at the origin: (0, 0, 0)
+ * // Set its "up" vector: (0, 1, 0).
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, 1, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube flips upside-down periodically. The text "upY: Y" is written in black beneath it. Y oscillates between -1 and 1.'
+ * );
* }
*
* function draw() {
- * orbitControl();
- * box(10);
- * }
- *
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the y-component.
+ * let y = sin(frameCount * 0.01);
*
- * @alt
- * An example showing the use of camera object properties
+ * // Update the camera's "up" vector.
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, y, 0);
*
+ * // Display the value of upY, rounded to the nearest tenth.
+ * text(`upY: ${round(cam.upY, 1)}`, 0, 55);
+ * }
+ *
+ *
- * let cam, div;
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * background(255);
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * cam.lookAt(0, 0, 1);
- * div = createDiv('centerZ = ' + cam.centerZ);
- * div.position(0, 0);
- * div.style('color', 'white');
- * describe('An example showing the use of camera object properties');
+ *
+ * // Place the camera at the top-right: (100, -400, 800)
+ * // Point it at the origin: (0, 0, 0)
+ * // Set its "up" vector: (0, 1, 0).
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, 1, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The text "upZ: 0" is written in black beneath it.'
+ * );
* }
*
* function draw() {
- * orbitControl();
- * box(10);
- * }
- *
+ * background(200);
*
- * @alt
- * An example showing the use of camera object properties
+ * // Style the box.
+ * fill(255);
*
- */
-
- /**
- * x component of direction 'up' from camera
- * @property {Number} upX
- * @readonly
- * @example
- *
- * let cam, div;
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- * background(255);
- * cam = createCamera();
- * div = createDiv('upX = ' + cam.upX);
- * div.position(0, 0);
- * div.style('color', 'blue');
- * div.style('font-size', '18px');
- * describe('An example showing the use of camera object properties');
- * }
- *
+ * // Draw the box.
+ * box();
*
- * @alt
- * An example showing the use of camera object properties
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
*
- */
-
- /**
- * y component of direction 'up' from camera
- * @property {Number} upY
- * @readonly
- * @example
- *
- * let cam, div;
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- * background(255);
- * cam = createCamera();
- * div = createDiv('upY = ' + cam.upY);
- * div.position(0, 0);
- * div.style('color', 'blue');
- * div.style('font-size', '18px');
- * describe('An example showing the use of camera object properties');
+ * // Display the value of upZ, rounded to the nearest tenth.
+ * text(`upZ: ${round(cam.upZ, 1)}`, 0, 55);
* }
- *
+ *
+ *
+ * let cam;
+ * let font;
+ *
+ * // Load a font and create a p5.Font object.
+ * function preload() {
+ * font = loadFont('assets/inconsolata.otf');
+ * }
*
- */
-
- /**
- * z component of direction 'up' from camera
- * @property {Number} upZ
- * @readonly
- * @example
- *
- * let cam, div;
* function setup() {
* createCanvas(100, 100, WEBGL);
- * background(255);
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * div = createDiv('upZ = ' + cam.upZ);
- * div.position(0, 0);
- * div.style('color', 'blue');
- * div.style('font-size', '18px');
- * describe('An example showing the use of camera object properties');
+ *
+ * // Place the camera at the top-right: (100, -400, 800)
+ * // Point it at the origin: (0, 0, 0)
+ * // Set its "up" vector: (0, 1, 0).
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, 1, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube appears to rock back and forth. The text "upZ: Z" is written in black beneath it. Z oscillates between -1 and 1.'
+ * );
* }
- *
*
- * @alt
- * An example showing the use of camera object properties
+ * function draw() {
+ * background(200);
+ *
+ * // Style the box.
+ * fill(255);
+ *
+ * // Draw the box.
+ * box();
+ *
+ * // Style the text.
+ * textAlign(CENTER);
+ * textSize(16);
+ * textFont(font);
+ * fill(0);
+ *
+ * // Calculate the z-component.
+ * let z = sin(frameCount * 0.01);
*
+ * // Update the camera's "up" vector.
+ * cam.camera(100, -400, 800, 0, 0, 0, 0, 1, z);
+ *
+ * // Display the value of upZ, rounded to the nearest tenth.
+ * text(`upZ: ${round(cam.upZ, 1)}`, 0, 55);
+ * }
+ *
+ *
- * // drag the mouse to look around!
+ * // Double-click to toggle between cameras.
*
- * let cam;
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * // create a camera
- * cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * // give it a perspective projection
- * cam.perspective(PI / 3.0, width / height, 0.1, 500);
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Place it at the top-right.
+ * cam2.camera(400, -400, 800);
+ *
+ * // Set its fovy to 0.2.
+ * // Set its aspect to 1.5.
+ * // Set its near to 600.
+ * // Set its far to 1200.
+ * cam2.perspective(0.2, 1.5, 600, 1200);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe('A white cube on a gray background. The camera toggles between a frontal view and a skewed aerial view when the user double-clicks.');
* }
*
* function draw() {
* background(200);
- * orbitControl();
- * normalMaterial();
*
- * rotateX(-0.3);
- * rotateY(-0.2);
- * translate(0, 0, -50);
+ * // Draw the box.
+ * box();
+ * }
*
- * push();
- * translate(-15, 0, sin(frameCount / 30) * 65);
- * box(30);
- * pop();
- * push();
- * translate(15, 0, sin(frameCount / 30 + PI) * 65);
- * box(30);
- * pop();
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
+ * }
+ *
+ *
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Place it at the top-right.
+ * cam2.camera(400, -400, 800);
+ *
+ * // Set its fovy to 0.2.
+ * // Set its aspect to 1.5.
+ * // Set its near to 600.
+ * // Set its far to 1200.
+ * cam2.perspective(0.2, 1.5, 600, 1200);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe('A white cube moves left and right on a gray background. The camera toggles between a frontal and a skewed aerial view when the user double-clicks.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Translate the origin left and right.
+ * let x = 100 * sin(frameCount * 0.01);
+ * translate(x, 0, 0);
+ *
+ * // Draw the box.
+ * box();
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
* }
*
*
- * // drag the mouse to look around!
- * // there's no vanishing point
+ * // Double-click to toggle between cameras.
*
- * let cam;
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * // create a camera
- * cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * // give it an orthographic projection
- * cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Apply an orthographic projection.
+ * cam2.ortho();
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe('A row of white cubes against a gray background. The camera toggles between a perspective and an orthographic projection when the user double-clicks.');
* }
+ *
* function draw() {
* background(200);
- * orbitControl();
- * normalMaterial();
*
- * rotateX(0.2);
- * rotateY(-0.2);
- * push();
- * translate(-15, 0, sin(frameCount / 30) * 65);
- * box(30);
- * pop();
- * push();
- * translate(15, 0, sin(frameCount / 30 + PI) * 65);
- * box(30);
- * pop();
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 500);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
+ * }
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
+ * }
+ *
+ *
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Apply an orthographic projection.
+ * cam2.ortho();
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe('A row of white cubes slither like a snake against a gray background. The camera toggles between a perspective and an orthographic projection when the user double-clicks.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 500);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * push();
+ * // Calculate the box's coordinates.
+ * let x = 10 * sin(frameCount * 0.02 + i * 0.6);
+ * let z = -40 * i;
+ * // Translate the origin.
+ * translate(x, 0, z);
+ * // Draw the box.
+ * box(10);
+ * pop();
+ * }
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
* }
*
*
- * let cam;
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
*
* function setup() {
- * x = createCanvas(100, 100, WEBGL);
- * setAttributes('antialias', true);
- * // create a camera
- * cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * // set its frustum
- * cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Adjust the frustum.
+ * // Center it.
+ * // Set its width and height to 20 pixels.
+ * // Place its near plane 300 pixels from the camera.
+ * // Place its far plane 350 pixels from the camera.
+ * cam2.frustum(-10, 10, -10, 10, 300, 350);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe(
+ * 'A row of white cubes against a gray background. The camera zooms in on one cube when the user double-clicks.'
+ * );
* }
*
* function draw() {
* background(200);
- * orbitControl();
- * normalMaterial();
*
- * rotateY(-0.2);
- * rotateX(-0.3);
- * push();
- * translate(-15, 0, sin(frameCount / 30) * 25);
- * box(30);
- * pop();
- * push();
- * translate(15, 0, sin(frameCount / 30 + PI) * 25);
- * box(30);
- * pop();
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 600);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -40);
+ * box(10);
+ * }
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
* }
*
*
* let cam;
- * let delta = 0.01;
+ * let delta = 0.001;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * normalMaterial();
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // set initial pan angle
- * cam.pan(-0.8);
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube goes in and out of view as the camera pans left and right.'
+ * );
* }
*
* function draw() {
* background(200);
*
- * // pan camera according to angle 'delta'
+ * // Pan with the camera.
* cam.pan(delta);
*
- * // every 160 frames, switch direction
- * if (frameCount % 160 === 0) {
+ * // Switch directions every 120 frames.
+ * if (frameCount % 120 === 0) {
* delta *= -1;
* }
*
- * rotateX(frameCount * 0.01);
- * translate(-100, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
+ * // Draw the box.
+ * box();
* }
*
*
* let cam;
- * let delta = 0.01;
+ * let delta = 0.001;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * normalMaterial();
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // set initial tilt
- * cam.tilt(-0.8);
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube on a gray background. The cube goes in and out of view as the camera tilts up and down.'
+ * );
* }
*
* function draw() {
* background(200);
*
- * // pan camera according to angle 'delta'
+ * // Pan with the camera.
* cam.tilt(delta);
*
- * // every 160 frames, switch direction
- * if (frameCount % 160 === 0) {
+ * // Switch directions every 120 frames.
+ * if (frameCount % 120 === 0) {
* delta *= -1;
* }
*
- * rotateY(frameCount * 0.01);
- * translate(0, -100, 0);
- * box(20);
- * translate(0, 35, 0);
- * box(20);
- * translate(0, 35, 0);
- * box(20);
- * translate(0, 35, 0);
- * box(20);
- * translate(0, 35, 0);
- * box(20);
- * translate(0, 35, 0);
- * box(20);
- * translate(0, 35, 0);
- * box(20);
+ * // Draw the box.
+ * box();
* }
*
*
+ * // Double-click to look at a different cube.
+ *
* let cam;
+ * let isLookingLeft = true;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * normalMaterial();
+ *
+ * // Create a p5.Camera object.
* cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
+ *
+ * // Place the camera at the top-center.
+ * cam.setPosition(0, -400, 800);
+ *
+ * // Point the camera at the origin.
+ * cam.lookAt(-30, 0, 0);
+ *
+ * describe(
+ * 'A red cube and a blue cube on a gray background. The camera switches focus between the cubes when the user double-clicks.'
+ * );
* }
*
* function draw() {
* background(200);
*
- * // look at a new random point every 60 frames
- * if (frameCount % 60 === 0) {
- * cam.lookAt(random(-100, 100), random(-50, 50), 0);
- * }
- *
- * rotateX(frameCount * 0.01);
- * translate(-100, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
+ * // Draw the box on the left.
+ * push();
+ * // Translate the origin to the left.
+ * translate(-30, 0, 0);
+ * // Style the box.
+ * fill(255, 0, 0);
+ * // Draw the box.
* box(20);
- * translate(35, 0, 0);
+ * pop();
+ *
+ * // Draw the box on the right.
+ * push();
+ * // Translate the origin to the right.
+ * translate(30, 0, 0);
+ * // Style the box.
+ * fill(0, 0, 255);
+ * // Draw the box.
* box(20);
+ * pop();
+ * }
+ *
+ * // Change the camera's focus when the user double-clicks.
+ * function doubleClicked() {
+ * if (isLookingLeft === true) {
+ * cam.lookAt(30, 0, 0);
+ * isLookingLeft = false;
+ * } else {
+ * cam.lookAt(-30, 0, 0);
+ * isLookingLeft = true;
+ * }
* }
*
*
- * let cam;
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * // Create a camera.
- * // createCamera() sets the newly created camera as
- * // the current (active) camera.
- * cam = createCamera();
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Place it at the top-right: (1200, -600, 100)
+ * // Point it at the row of boxes: (-10, -10, 400)
+ * // Set its "up" vector to the default: (0, 1, 0)
+ * cam2.camera(1200, -600, 100, -10, -10, 400, 0, 1, 0);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe(
+ * 'A row of white cubes against a gray background. The camera toggles between a frontal and an aerial view when the user double-clicks.'
+ * );
* }
*
* function draw() {
- * background(204);
- * // Move the camera away from the plane by a sin wave
- * cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);
- * plane(10, 10);
+ * background(200);
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 500);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -30);
+ * box(10);
+ * }
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
* }
*
*
- * // move slider to see changes!
- * // sliders control the first 6 parameters of camera()
- *
- * let sliderGroup = [];
- * let X;
- * let Y;
- * let Z;
- * let centerX;
- * let centerY;
- * let centerZ;
- * let h = 20;
- * let cam;
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * // create a camera
- * cam = createCamera();
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // create sliders
- * for (var i = 0; i < 6; i++) {
- * if (i === 2) {
- * sliderGroup[i] = createSlider(10, 400, 200);
- * } else {
- * sliderGroup[i] = createSlider(-400, 400, 0);
- * }
- * h = map(i, 0, 6, 5, 85);
- * sliderGroup[i].position(10, height + h);
- * sliderGroup[i].style('width', '80px');
- * }
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Place it at the right: (1200, 0, 100)
+ * // Point it at the row of boxes: (-10, -10, 400)
+ * // Set its "up" vector to the default: (0, 1, 0)
+ * cam2.camera(1200, 0, 100, -10, -10, 400, 0, 1, 0);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe(
+ * 'A row of white cubes against a gray background. The camera toggles between a static frontal view and an orbiting view when the user double-clicks.'
+ * );
* }
*
* function draw() {
- * background(60);
- * // assigning sliders' value to each parameters
- * X = sliderGroup[0].value();
- * Y = sliderGroup[1].value();
- * Z = sliderGroup[2].value();
- * centerX = sliderGroup[3].value();
- * centerY = sliderGroup[4].value();
- * centerZ = sliderGroup[5].value();
- * cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);
- * stroke(255);
- * fill(255, 102, 94);
- * box(85);
+ * background(200);
+ *
+ * // Update cam2's position.
+ * let x = 1200 * cos(frameCount * 0.01);
+ * let y = -600 * sin(frameCount * 0.01);
+ * cam2.camera(x, y, 100, -10, -10, 400, 0, 1, 0);
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 500);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -30);
+ * box(10);
+ * }
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
* }
*
*
- * // see the camera move along its own axes while maintaining its orientation
+ * // Click the canvas to begin detecting key presses.
+ *
* let cam;
- * let delta = 0.5;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * normalMaterial();
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
* cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
+ *
+ * // Place the camera at the top-right.
+ * cam.setPosition(400, -400, 800);
+ *
+ * // Point it at the origin.
+ * cam.lookAt(0, 0, 0);
+ *
+ * describe(
+ * 'A white cube drawn against a gray background. The cube appears to move when the user presses certain keys.'
+ * );
* }
*
* function draw() {
* background(200);
*
- * // move the camera along its local axes
- * cam.move(delta, delta, 0);
+ * // Move the camera along its "local" axes
+ * // when the user presses certain keys.
+ * if (keyIsPressed === true) {
*
- * // every 100 frames, switch direction
- * if (frameCount % 150 === 0) {
- * delta *= -1;
+ * // Move horizontally.
+ * if (keyCode === LEFT_ARROW) {
+ * cam.move(-1, 0, 0);
+ * }
+ * if (keyCode === RIGHT_ARROW) {
+ * cam.move(1, 0, 0);
+ * }
+ *
+ * // Move vertically.
+ * if (keyCode === UP_ARROW) {
+ * cam.move(0, -1, 0);
+ * }
+ * if (keyCode === DOWN_ARROW) {
+ * cam.move(0, 1, 0);
+ * }
+ *
+ * // Move in/out of the screen.
+ * if (key === 'i') {
+ * cam.move(0, 0, -1);
+ * }
+ * if (key === 'o') {
+ * cam.move(0, 0, 1);
+ * }
* }
*
- * translate(-10, -10, 0);
- * box(50, 8, 50);
- * translate(15, 15, 0);
- * box(50, 8, 50);
- * translate(15, 15, 0);
- * box(50, 8, 50);
- * translate(15, 15, 0);
- * box(50, 8, 50);
- * translate(15, 15, 0);
- * box(50, 8, 50);
- * translate(15, 15, 0);
- * box(50, 8, 50);
+ * // Draw the box.
+ * box();
* }
*
*
- * // press '1' '2' or '3' keys to set camera position
+ * // Double-click to toggle between cameras.
*
- * let cam;
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * normalMaterial();
- * cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Place it closer to the origin.
+ * cam2.setPosition(0, 0, 600);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe(
+ * 'A row of white cubes against a gray background. The camera toggles the amount of zoom when the user double-clicks.'
+ * );
* }
*
* function draw() {
* background(200);
*
- * // '1' key
- * if (keyIsDown(49)) {
- * cam.setPosition(30, 0, 80);
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 500);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -30);
+ * box(10);
* }
- * // '2' key
- * if (keyIsDown(50)) {
- * cam.setPosition(0, 0, 80);
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
* }
- * // '3' key
- * if (keyIsDown(51)) {
- * cam.setPosition(-30, 0, 80);
+ * }
+ *
+ *
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let isDefaultCamera = true;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Place it closer to the origin.
+ * cam2.setPosition(0, 0, 600);
+ *
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
+ *
+ * describe(
+ * 'A row of white cubes against a gray background. The camera toggles between a static view and a view that zooms in and out when the user double-clicks.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Update cam2's z-coordinate.
+ * let z = 100 * sin(frameCount * 0.01) + 700;
+ * cam2.setPosition(0, 0, z);
+ *
+ * // Translate the origin toward the camera.
+ * translate(-10, 10, 500);
+ *
+ * // Rotate the coordinate system.
+ * rotateY(-0.1);
+ * rotateX(-0.1);
+ *
+ * // Draw the row of boxes.
+ * for (let i = 0; i < 6; i += 1) {
+ * translate(0, 0, -30);
+ * box(10);
* }
+ * }
*
- * box(20);
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (isDefaultCamera === true) {
+ * setCamera(cam2);
+ * isDefaultCamera = false;
+ * } else {
+ * setCamera(cam1);
+ * isDefaultCamera = true;
+ * }
* }
*
*
- * let cam, initialCam;
+ * // Double-click to "reset" the camera zoom.
+ *
+ * let cam1;
+ * let cam2;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * strokeWeight(3);
*
- * // Set the initial state to initialCamera and set it to the camera
- * // used for drawing. Then set cam to be the active camera.
- * cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * initialCam = createCamera();
- * initialCam.camera(100, 100, 100, 0, 0, 0, 0, 0, -1);
- * initialCam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * cam.set(initialCam);
+ * // Create the first camera.
+ * cam1 = createCamera();
*
- * setCamera(cam);
+ * // Place the camera at the top-right.
+ * cam1.setPosition(400, -400, 800);
+ *
+ * // Point it at the origin.
+ * cam1.lookAt(0, 0, 0);
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ *
+ * // Copy cam1's configuration.
+ * cam2.set(cam1);
+ *
+ * describe(
+ * 'A white cube drawn against a gray background. The camera slowly moves forward. The camera resets when the user double-clicks.'
+ * );
* }
*
* function draw() {
- * orbitControl();
- * background(255);
- * box(50);
- * translate(0, 0, -25);
- * plane(100);
+ * background(200);
+ *
+ * // Update cam2's position.
+ * cam2.move(0, 0, -1);
+ *
+ * // Draw the box.
+ * box();
* }
*
- * function doubleClicked(){
- * // Double-click to return the camera to its initial position.
- * cam.set(initialCam);
+ * // "Reset" the camera when the user double-clicks.
+ * function doubleClicked() {
+ * cam2.set(cam1);
* }
- *
- *
- * let cam0, cam1, cam;
+ * let cam;
+ * let cam0;
+ * let cam1;
+ *
* function setup() {
* createCanvas(100, 100, WEBGL);
- * strokeWeight(3);
*
- * // camera for slerp.
+ * // Create the main camera.
+ * // Keep its default settings.
* cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // cam0 is looking at the cube from the front.
- * cam0 = createCamera();
- * cam0.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam0.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // cam1 is pointing straight to the right in the cube
- * // at the same position as cam0 by doing a pan(-PI/2).
- * cam1 = createCamera();
- * cam1.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam1.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * cam1.pan(-PI/2);
*
- * // we only use cam.
- * setCamera(cam);
- * }
+ * // Create the first camera.
+ * // Keep its default settings.
+ * cam0 = createCamera();
*
- * function draw() {
- * // calculate amount.
- * const amt = 0.5 - 0.5 * cos(frameCount * TAU / 120);
- * // slerp cam0 and cam1 with amt, set to cam.
- * // When amt moves from 0 to 1, cam moves from cam0 to cam1,
- * // shaking the camera to the right.
- * cam.slerp(cam0, cam1, amt);
+ * // Create the second camera.
+ * cam1 = createCamera();
*
- * background(255);
- * // Every time the camera turns right, the cube drifts left.
- * box(40);
- * }
- *
- *
- * let cam, lastCam, initialCam;
- * let countForReset = 30;
- * // This sample uses orbitControl() to move the camera.
- * // Double-clicking the canvas restores the camera to its initial state.
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- * strokeWeight(3);
+ * // Point it at the origin.
+ * cam1.lookAt(0, 0, 0);
*
- * // main camera
- * cam = createCamera();
- * cam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // Camera for recording loc info before reset
- * lastCam = createCamera();
- * lastCam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * lastCam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
- * // Camera for recording the initial state
- * initialCam = createCamera();
- * initialCam.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * initialCam.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
+ * // Set the current camera to cam.
+ * setCamera(cam);
*
- * setCamera(cam); // set main camera
+ * describe('A white cube drawn against a gray background. The camera slowly oscillates between a frontal view and an aerial view.');
* }
*
* function draw() {
- * if (countForReset < 30) {
- * // if the reset count is less than 30,
- * // it will move closer to the original camera as it increases.
- * countForReset++;
- * cam.slerp(lastCam, initialCam, countForReset / 30);
- * } else {
- * // if the count is 30,
- * // you can freely move the main camera with orbitControl().
- * orbitControl();
- * }
+ * background(200);
*
- * background(255);
- * box(40);
- * }
- * // A double-click sets countForReset to 0 and initiates a reset.
- * function doubleClicked() {
- * if (countForReset === 30) {
- * countForReset = 0;
- * lastCam.set(cam);
- * }
+ * // Calculate the amount to interpolate between cam0 and cam1.
+ * let amt = 0.5 * sin(frameCount * 0.01) + 0.5;
+ *
+ * // Update the main camera's position and orientation.
+ * cam.slerp(cam0, cam1, amt);
+ *
+ * box();
* }
*
*
- * let cam1, cam2;
- * let currentCamera;
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ * let usingCam1 = true;
*
* function setup() {
* createCanvas(100, 100, WEBGL);
- * normalMaterial();
*
+ * // Create the first camera.
+ * // Keep its default settings.
* cam1 = createCamera();
- * cam1.camera(0, 0, 50*sqrt(3), 0, 0, 0, 0, 1, 0);
- * cam1.perspective(PI/3, 1, 5*sqrt(3), 500*sqrt(3));
+ *
+ * // Create the second camera.
+ * // Place it at the top-left.
+ * // Point it at the origin.
* cam2 = createCamera();
- * cam2.setPosition(30, 0, 50);
+ * cam2.setPosition(400, -400, 800);
* cam2.lookAt(0, 0, 0);
- * cam2.ortho(-50, 50, -50, 50, 0, 200);
*
- * // set variable for previously active camera:
- * currentCamera = 1;
+ * // Set the current camera to cam1.
+ * setCamera(cam1);
*
- * describe(
- * 'Canvas switches between two camera views, each showing a series of spinning 3D boxes.'
- * );
+ * describe('A white cube on a gray background. The camera toggles between frontal and aerial views when the user double-clicks.');
* }
*
* function draw() {
* background(200);
*
- * // every 100 frames, switch between the two cameras
- * if (frameCount % 100 === 0) {
- * if (currentCamera === 1) {
- * setCamera(cam1);
- * currentCamera = 0;
- * } else {
- * setCamera(cam2);
- * currentCamera = 1;
- * }
- * }
- *
- * // camera 1:
- * cam1.lookAt(0, 0, 0);
- * cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);
- *
- * drawBoxes();
+ * // Draw the box.
+ * box();
* }
*
- * function drawBoxes() {
- * rotateX(frameCount * 0.01);
- * translate(-100, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
- * translate(35, 0, 0);
- * box(20);
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * if (usingCam1 === true) {
+ * setCamera(cam2);
+ * usingCam1 = false;
+ * } else {
+ * setCamera(cam1);
+ * usingCam1 = true;
+ * }
* }
*
*