diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index 36a5a162f8..ab0d2ab073 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -19,65 +19,65 @@ import Filters from './filters'; */ /** - * Creates a new p5.Image. A p5.Image is a canvas backed representation of an - * image. + * A class to describe an image. Images are rectangular grids of pixels that + * can be displayed and modified. * - * p5 can display .gif, .jpg and .png images. Images may be displayed - * in 2D and 3D space. Before an image is used, it must be loaded with the - * loadImage() function. The p5.Image class contains fields for the width and - * height of the image, as well as an array called pixels[] that contains the - * values for every pixel in the image. + * Existing images can be loaded by calling + * loadImage(). Blank images can be created by + * calling createImage(). `p5.Image` objects + * have methods for common tasks such as applying filters and modifying + * pixel values. * - * The methods described below allow easy access to the image's pixels and - * alpha channel and simplify the process of compositing. - * - * Before using the pixels[] array, be sure to use the loadPixels() method on - * the image to make sure that the pixel data is properly loaded. * @example - *
- * function setup() {
- * let img = createImage(100, 100); // same as new p5.Image(100, 100);
- * img.loadPixels();
- * createCanvas(100, 100);
- * background(0);
+ *
+ *
+ * let img;
*
- * // helper for writing color to array
- * function writeColor(image, x, y, red, green, blue, alpha) {
- * let index = (x + y * width) * 4;
- * image.pixels[index] = red;
- * image.pixels[index + 1] = green;
- * image.pixels[index + 2] = blue;
- * image.pixels[index + 3] = alpha;
- * }
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
*
- * let x, y;
- * // fill with random colors
- * for (y = 0; y < img.height; y++) {
- * for (x = 0; x < img.width; x++) {
- * let red = random(255);
- * let green = random(255);
- * let blue = random(255);
- * let alpha = 255;
- * writeColor(img, x, y, red, green, blue, alpha);
- * }
- * }
+ * function setup() {
+ * image(img, 0, 0);
*
- * // draw a red line
- * y = 0;
- * for (x = 0; x < img.width; x++) {
- * writeColor(img, x, y, 255, 0, 0, 255);
- * }
+ * describe('An image of a brick wall.');
+ * }
+ *
+ *
*
- * // draw a green line
- * y = img.height - 1;
- * for (x = 0; x < img.width; x++) {
- * writeColor(img, x, y, 0, 255, 0, 255);
- * }
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
*
- * img.updatePixels();
+ * function setup() {
+ * img.filter(GRAY);
* image(img, 0, 0);
+ *
+ * describe('A grayscale image of a brick wall.');
* }
- *
+ *
+ *
+ * background(200);
+ * let img = createImage(66, 66);
+ * img.loadPixels();
+ * for (let x = 0; x < img.width; x += 1) {
+ * for (let y = 0; y < img.height; y += 1) {
+ * img.set(x, y, 0);
+ * }
+ * }
+ * img.updatePixels();
+ * image(img, 17, 17);
+ *
+ * describe('A black square drawn in the middle of a gray square.');
+ *
+ *
+ *
+ *
* let img;
+ *
* function preload() {
* img = loadImage('assets/rockies.jpg');
* }
*
* function setup() {
- * createCanvas(100, 100);
* image(img, 0, 0);
- * for (let i = 0; i < img.width; i++) {
- * let c = img.get(i, img.height / 2);
- * stroke(c);
- * line(i, height / 2, i, height);
- * }
- * }
- *
- *
- * @alt
- * rocky mountains in top and horizontal lines in corresponding colors in bottom.
+ * let x = img.width / 2;
+ * let y = img.height / 2;
+ * let d = 20;
+ * circle(x, y, d);
*
+ * describe('An image of a mountain landscape with a white circle drawn in the middle.');
+ * }
+ *
+ *
+ *
+ *
* let img;
+ *
* function preload() {
* img = loadImage('assets/rockies.jpg');
* }
*
* function setup() {
- * createCanvas(100, 100);
* image(img, 0, 0);
- * for (let i = 0; i < img.height; i++) {
- * let c = img.get(img.width / 2, i);
- * stroke(c);
- * line(0, i, width / 2, i);
- * }
- * }
- *
- *
- * @alt
- * rocky mountains on right and vertical lines in corresponding colors on left.
+ * let x = img.width / 2;
+ * let y = img.height / 2;
+ * let d = 20;
+ * circle(x, y, d);
*
+ * describe('An image of a mountain landscape with a white circle drawn in the middle.');
+ * }
+ *
+ *
* let img = createImage(66, 66);
* img.loadPixels();
- * for (let i = 0; i < img.width; i++) {
- * for (let j = 0; j < img.height; j++) {
- * img.set(i, j, color(0, 90, 102));
- * }
+ * let numPixels = 4 * img.width * img.height;
+ * for (let i = 0; i < numPixels; i += 4) {
+ * // Red.
+ * img.pixels[i] = 0;
+ * // Green.
+ * img.pixels[i + 1] = 0;
+ * // Blue.
+ * img.pixels[i + 2] = 0;
+ * // Alpha.
+ * img.pixels[i + 3] = 255;
* }
* img.updatePixels();
* image(img, 17, 17);
+ *
+ * describe('A black square drawn in the middle of a gray square.');
*
*
- * let pink = color(255, 102, 204);
* let img = createImage(66, 66);
* img.loadPixels();
- * for (let i = 0; i < 4 * (width * height / 2); i += 4) {
- * img.pixels[i] = red(pink);
- * img.pixels[i + 1] = green(pink);
- * img.pixels[i + 2] = blue(pink);
- * img.pixels[i + 3] = alpha(pink);
+ * let numPixels = 4 * img.width * img.height;
+ * for (let i = 0; i < numPixels; i += 4) {
+ * // Red.
+ * img.pixels[i] = 255;
+ * // Green.
+ * img.pixels[i + 1] = 0;
+ * // Blue.
+ * img.pixels[i + 2] = 0;
+ * // Alpha.
+ * img.pixels[i + 3] = 255;
* }
* img.updatePixels();
* image(img, 17, 17);
+ *
+ * describe('A red square drawn in the middle of a gray square.');
*
*
- * let myImage;
- * let halfImage;
- *
- * function preload() {
- * myImage = loadImage('assets/rockies.jpg');
- * }
- *
- * function setup() {
- * myImage.loadPixels();
- * halfImage = 4 * myImage.width * myImage.height / 2;
- * for (let i = 0; i < halfImage; i++) {
- * myImage.pixels[i + halfImage] = myImage.pixels[i];
+ *
+ *
+ * let img = createImage(66, 66);
+ * img.loadPixels();
+ * for (let x = 0; x < img.width; x += 1) {
+ * for (let y = 0; y < img.height; y += 1) {
+ * img.set(x, y, 0);
* }
- * myImage.updatePixels();
* }
+ * img.updatePixels();
+ * image(img, 17, 17);
*
- * function draw() {
- * image(myImage, 0, 0, width, height);
- * }
- *
+ * describe('A black square drawn in the middle of a gray square.');
+ *
+ *
+ * let img = createImage(66, 66);
+ * img.loadPixels();
+ * let numPixels = 4 * img.width * img.height;
+ * for (let i = 0; i < numPixels; i += 4) {
+ * // Red.
+ * img.pixels[i] = 0;
+ * // Green.
+ * img.pixels[i + 1] = 0;
+ * // Blue.
+ * img.pixels[i + 2] = 0;
+ * // Alpha.
+ * img.pixels[i + 3] = 255;
+ * }
+ * img.updatePixels();
+ * image(img, 17, 17);
+ *
+ * describe('A black square drawn in the middle of a gray square.');
+ *
+ *
- * let myImage;
- * let halfImage;
+ * The optional parameters `x`, `y`, `width`, and `height` define a
+ * subsection of the p5.Image object to update.
+ * Doing so can improve performance in some cases.
*
- * function preload() {
- * myImage = loadImage('assets/rockies.jpg');
- * }
+ * If the p5.Image object was loaded from a GIF,
+ * then calling `img.updatePixels()` will update the pixels in current
+ * frame.
*
- * function setup() {
- * myImage.loadPixels();
- * halfImage = 4 * myImage.width * myImage.height / 2;
- * for (let i = 0; i < halfImage; i++) {
- * myImage.pixels[i + halfImage] = myImage.pixels[i];
+ * @method updatePixels
+ * @param {Integer} x x-coordinate of the upper-left corner
+ * of the subsection to update.
+ * @param {Integer} y y-coordinate of the upper-left corner
+ * of the subsection to update.
+ * @param {Integer} w width of the subsection to update.
+ * @param {Integer} h height of the subsection to update.
+ * @example
+ *
+ *
+ * let img = createImage(66, 66);
+ * img.loadPixels();
+ * for (let x = 0; x < img.width; x += 1) {
+ * for (let y = 0; y < img.height; y += 1) {
+ * img.set(x, y, 0);
* }
- * myImage.updatePixels();
* }
+ * img.updatePixels();
+ * image(img, 17, 17);
*
- * function draw() {
- * image(myImage, 0, 0, width, height);
+ * describe('A black square drawn in the middle of a gray square.');
+ *
+ *
+ *
+ *
+ *
+ * let img = createImage(66, 66);
+ * img.loadPixels();
+ * let numPixels = 4 * img.width * img.height;
+ * for (let i = 0; i < numPixels; i += 4) {
+ * // Red.
+ * img.pixels[i] = 0;
+ * // Green.
+ * img.pixels[i + 1] = 0;
+ * // Blue.
+ * img.pixels[i + 2] = 0;
+ * // Alpha.
+ * img.pixels[i + 3] = 255;
* }
- *
+ * img.updatePixels();
+ * image(img, 17, 17);
*
- * @alt
- * 2 images of rocky mountains vertically stacked
+ * describe('A black square drawn in the middle of a gray square.');
+ *
+ *
- * let myImage;
- * let c;
+ *
+ *
+ * let img;
*
* function preload() {
- * myImage = loadImage('assets/rockies.jpg');
+ * img = loadImage('assets/rockies.jpg');
* }
*
* function setup() {
- * background(myImage);
- * noStroke();
- * c = myImage.get(60, 90);
+ * image(img, 0, 0);
+ * let img2 = get();
+ * image(img2, width / 2, 0);
+ *
+ * describe('Two identical mountain landscapes shown side-by-side.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/rockies.jpg');
+ * }
+ *
+ * function setup() {
+ * image(img, 0, 0);
+ * let c = img.get(50, 90);
* fill(c);
- * rect(25, 25, 50, 50);
+ * noStroke();
+ * square(25, 25, 50);
+ *
+ * describe('A mountain landscape with an olive green square in its center.');
* }
+ *
+ *
*
- * //get() returns color here
- *
+ * let img;
*
- * @alt
- * image of rocky mountains with 50×50 green rect in front
+ * function preload() {
+ * img = loadImage('assets/rockies.jpg');
+ * }
+ *
+ * function setup() {
+ * image(img, 0, 0);
+ * let img2 = img.get(0, 0, img.width / 2, img.height / 2);
+ * image(img2, width / 2, height / 2);
+ *
+ * describe('A mountain landscape drawn on top of another mountain landscape.');
+ * }
+ *
+ *
+ * let img = createImage(100, 100);
+ * img.set(30, 20, 0);
+ * img.set(85, 20, 0);
+ * img.set(85, 75, 0);
+ * img.set(30, 75, 0);
+ * img.updatePixels();
+ * image(img, 0, 0);
+ *
+ * describe('Four black dots arranged in a square drawn on a gray background.');
+ *
+ *
+ * let img = createImage(100, 100);
+ * let black = color(0);
+ * img.set(30, 20, black);
+ * img.set(85, 20, black);
+ * img.set(85, 75, black);
+ * img.set(30, 75, black);
+ * img.updatePixels();
+ * image(img, 0, 0);
+ *
+ * describe('Four black dots arranged in a square drawn on a gray background.');
+ *
+ *
* let img = createImage(66, 66);
- * img.loadPixels();
- * for (let i = 0; i < img.width; i++) {
- * for (let j = 0; j < img.height; j++) {
- * img.set(i, j, color(0, 90, 102, (i % img.width) * 2));
+ * for (let x = 0; x < img.width; x += 1) {
+ * for (let y = 0; y < img.height; y += 1) {
+ * let c = map(x, 0, img.width, 0, 255);
+ * img.set(x, y, c);
* }
* }
* img.updatePixels();
* image(img, 17, 17);
- * image(img, 34, 34);
+ *
+ * describe('A square with a horiztonal color gradient from black to white drawn on a gray background.');
*
*
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/rockies.jpg');
+ * }
+ *
+ * function setup() {
+ * let img2 = createImage(100, 100);
+ * img2.set(0, 0, img);
+ * image(img2, 0, 0);
+ *
+ * describe('An image of a mountain landscape.');
+ * }
+ *
+ *
+ *
+ *
* let img;
*
* function preload() {
* img = loadImage('assets/rockies.jpg');
* }
- * function draw() {
+ * function setup() {
+ * image(img, 0, 0);
+ * img.resize(50, 100);
* image(img, 0, 0);
+ *
+ * describe('Two images of a mountain landscape. One copy of the image is squeezed horizontally.');
* }
+ *
+ *
*
- * function mousePressed() {
- * img.resize(50, 100);
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/rockies.jpg');
* }
- *
+
+ * function setup() {
+ * image(img, 0, 0);
+ * img.resize(0, 30);
+ * image(img, 0, 0);
*
- * @alt
- * image of rocky mountains. zoomed in
+ * describe('Two images of a mountain landscape. The small copy of the image covers the top-left corner of the larger image.');
+ * }
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/rockies.jpg');
+ * }
+
+ * function setup() {
+ * image(img, 0, 0);
+ * img.resize(60, 0);
+ * image(img, 0, 0);
+ *
+ * describe('Two images of a mountain landscape. The small copy of the image covers the top-left corner of the larger image.');
+ * }
+ *
+ *
- * let photo;
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/rockies.jpg');
+ * }
+ *
+ * function setup() {
+ * img.copy(7, 22, 10, 10, 35, 25, 50, 50);
+ * image(img, 0, 0);
+ * // Outline copied region.
+ * stroke(255);
+ * noFill();
+ * square(7, 22, 10);
+ *
+ * describe('An image of a mountain landscape. A square region is outlined in white. A larger square contains a pixelated view of the outlined region.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let mountains;
* let bricks;
- * let x;
- * let y;
*
* function preload() {
- * photo = loadImage('assets/rockies.jpg');
+ * mountains = loadImage('assets/rockies.jpg');
* bricks = loadImage('assets/bricks.jpg');
* }
*
* function setup() {
- * x = bricks.width / 2;
- * y = bricks.height / 2;
- * photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);
- * image(photo, 0, 0);
- * }
- *
+ * let x = bricks.width / 2;
+ * let y = bricks.height / 2;
+ * mountains.copy(bricks, 0, 0, x, y, 0, 0, x, y);
+ * image(mountains, 0, 0);
*
- * @alt
- * image of rocky mountains and smaller image on top of bricks at top left
+ * describe('An image of a brick wall drawn at the top-left of an image of a mountain landscape.');
+ * }
+ *
+ *
- * let photo, maskImage;
+ *
+ *
+ * let photo;
+ * let maskImage;
+ *
* function preload() {
* photo = loadImage('assets/rockies.jpg');
* maskImage = loadImage('assets/mask2.png');
* }
*
* function setup() {
- * createCanvas(100, 100);
* photo.mask(maskImage);
* image(photo, 0, 0);
- * }
- *
*
- * @alt
- * image of rocky mountains with white at right
- *
- * http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
+ * describe('An image of a mountain landscape. The right side of the image has a faded patch of white.');
+ * }
+ *
+ *
- * let photo1;
- * let photo2;
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
+ *
+ * function setup() {
+ * img.filter(INVERT);
+ * image(img, 0, 0);
+ *
+ * describe('A blue brick wall.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
+ *
+ * function setup() {
+ * img.filter(GRAY);
+ * image(img, 0, 0);
+ *
+ * describe('A brick wall drawn in grayscale.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
+ *
+ * function setup() {
+ * img.filter(THRESHOLD);
+ * image(img, 0, 0);
+ *
+ * describe('A brick wall drawn in black and white.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let img;
*
* function preload() {
- * photo1 = loadImage('assets/rockies.jpg');
- * photo2 = loadImage('assets/rockies.jpg');
+ * img = loadImage('assets/bricks.jpg');
* }
*
* function setup() {
- * photo2.filter(GRAY);
- * image(photo1, 0, 0);
- * image(photo2, width / 2, 0);
+ * img.filter(OPAQUE);
+ * image(img, 0, 0);
+ *
+ * describe('A red brick wall.');
* }
- *
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
+ *
+ * function setup() {
+ * img.filter(POSTERIZE, 3);
+ * image(img, 0, 0);
+ *
+ * describe('An image of a red brick wall drawn with a limited color palette.');
+ * }
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
+ *
+ * function setup() {
+ * img.filter(BLUR, 3);
+ * image(img, 0, 0);
+ *
+ * describe('A blurry image of a red brick wall.');
+ * }
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
+ *
+ * function setup() {
+ * img.filter(DILATE);
+ * image(img, 0, 0);
+ *
+ * describe('A red brick wall with bright lines between each brick.');
+ * }
+ *
+ *
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/bricks.jpg');
+ * }
+ *
+ * function setup() {
+ * img.filter(ERODE);
+ * image(img, 0, 0);
+ *
+ * describe('A red brick wall with faint lines between each brick.');
+ * }
+ *
+ *
+ *
+ *
* let mountains;
* let bricks;
*
@@ -792,9 +1098,14 @@ p5.Image = class {
* mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);
* image(mountains, 0, 0);
* image(bricks, 0, 0);
+ *
+ * describe('A wall of bricks in front of a mountain landscape. The same wall of bricks appears faded on the right of the image.');
* }
- *
- *
+ *
+ *
+ *
+ *
+ *
* let mountains;
* let bricks;
*
@@ -807,9 +1118,14 @@ p5.Image = class {
* mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);
* image(mountains, 0, 0);
* image(bricks, 0, 0);
+ *
+ * describe('A wall of bricks in front of a mountain landscape. The same wall of bricks appears transparent on the right of the image.');
* }
- *
- *
+ *
+ *
+ *
+ *
+ *
* let mountains;
* let bricks;
*
@@ -822,13 +1138,11 @@ p5.Image = class {
* mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);
* image(mountains, 0, 0);
* image(bricks, 0, 0);
- * }
- *
*
- * @alt
- * image of rocky mountains. Brick images on left and right. Right overexposed
- * image of rockies. Brickwall images on left and right. Right mortar transparent
- * image of rockies. Brickwall images on left and right. Right translucent
+ * describe('A wall of bricks in front of a mountain landscape. The same wall of bricks appears washed out on the right of the image.');
+ * }
+ *
+ *
- * let photo;
+ *
+ *
+ * let img;
*
* function preload() {
- * photo = loadImage('assets/rockies.jpg');
+ * img = loadImage('assets/rockies.jpg');
* }
*
* function draw() {
- * image(photo, 0, 0);
+ * image(img, 0, 0);
+ *
+ * describe('An image of a mountain landscape.');
* }
*
- * function keyTyped() {
+ * function keyPressed() {
* if (key === 's') {
- * photo.save('photo', 'png');
+ * img.save();
+ * } else if (key === 'j') {
+ * img.save('rockies.jpg');
+ * } else if (key === 'p') {
+ * img.save('rockies', 'png');
* }
* }
- *
- *
- * @alt
- * image of rocky mountains.
+ *
+ *
+ *
+ *
* let gif;
*
* function preload() {
@@ -929,19 +1260,16 @@ p5.Image = class {
*
* function draw() {
* background(255);
- * // The GIF file that we loaded only loops once
- * // so it freezes on the last frame after playing through
* image(gif, 0, 0);
+ *
+ * describe('A cartoon face winks once and then freezes. Clicking resets the face and makes it wink again.');
* }
*
* function mousePressed() {
- * // Click to reset the GIF and begin playback from start
* gif.reset();
* }
- *
- * @alt
- * Animated image of a cartoon face that winks once and then freezes
- * When you click it animates again, winks once and freezes
+ *
+ *
+ *
+ *
* let gif;
*
* function preload() {
@@ -970,15 +1299,14 @@ p5.Image = class {
* }
*
* function draw() {
- * let frame = gif.getCurrentFrame();
+ * let index = gif.getCurrentFrame();
* image(gif, 0, 0);
- * text(frame, 10, 90);
+ * text(index, 10, 90);
+ *
+ * describe('A cartoon eye repeatedly looks around, then outwards. A number displayed in the bottom-left corner increases from 0 to 124, then repeats.');
* }
- *
- * @alt
- * Animated image of a cartoon eye looking around and then
- * looking outwards, in the lower-left hand corner a number counts
- * up quickly to 124 and then starts back over at 0
+ *
+ *
+ *
+ *
* let gif;
+ * let frameSlider;
*
* function preload() {
* gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
* }
*
- * // Move your mouse up and down over canvas to see the GIF
- * // frames animate
+ * function setup() {
+ * let maxFrame = gif.numFrames() - 1;
+ * frameSlider = createSlider(0, maxFrame);
+ * frameSlider.position(10, 80);
+ * frameSlider.size(80);
+ * }
+ *
* function draw() {
- * gif.pause();
+ * let index = frameSlider.value();
+ * gif.setFrame(index);
* image(gif, 0, 0);
- * // Get the highest frame number which is the number of frames - 1
- * let maxFrame = gif.numFrames() - 1;
- * // Set the current frame that is mapped to be relative to mouse position
- * let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));
- * gif.setFrame(frameNumber);
- * }
- *
- * @alt
- * A still image of a cartoon eye that looks around when you move your mouse
- * up and down over the canvas
+ *
+ * describe('A cartoon eye looks around when a slider is moved.');
+ * }
+ *
+ *
+ * @return {Number} number of frames in the GIF.
+ *
+ * @example
+ *
+ *
* let gif;
*
* function preload() {
* gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
* }
*
- * // Move your mouse up and down over canvas to see the GIF
- * // frames animate
* function draw() {
- * gif.pause();
* image(gif, 0, 0);
- * // Get the highest frame number which is the number of frames - 1
- * let maxFrame = gif.numFrames() - 1;
- * // Set the current frame that is mapped to be relative to mouse position
- * let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));
- * gif.setFrame(frameNumber);
- * }
- *
- * @alt
- * A still image of a cartoon eye that looks around when you move your mouse
- * up and down over the canvas
+ * let total = gif.numFrames();
+ * let index = gif.getCurrentFrame();
+ * text(`${index} / ${total}`, 30, 90);
+ *
+ * describe('A cartoon eye looks around. The text "n / 125" is shown at the bottom of the canvas.');
+ * }
+ *
+ *
+ *
+ *
* let gif;
*
* function preload() {
@@ -1083,6 +1413,8 @@ p5.Image = class {
* function draw() {
* background(255);
* image(gif, 0, 0);
+ *
+ * describe('A drawing of a child with hair blowing in the wind. The animation freezes when clicked and resumes when released.');
* }
*
* function mousePressed() {
@@ -1092,11 +1424,8 @@ p5.Image = class {
* function mouseReleased() {
* gif.play();
* }
- *
- * @alt
- * An animated GIF of a drawing of small child with
- * hair blowing in the wind, when you click the image
- * freezes when you release it animates again
+ *
+ *
+ *
+ *
* let gif;
*
* function preload() {
@@ -1119,6 +1451,8 @@ p5.Image = class {
* function draw() {
* background(255);
* image(gif, 0, 0);
+ *
+ * describe('A drawing of a child with hair blowing in the wind. The animation freezes when clicked and resumes when released.');
* }
*
* function mousePressed() {
@@ -1128,11 +1462,8 @@ p5.Image = class {
* function mouseReleased() {
* gif.play();
* }
- *
- * @alt
- * An animated GIF of a drawing of small child with
- * hair blowing in the wind, when you click the image
- * freezes when you release it animates again
+ *
+ *
- * let gifFast, gifSlow;
+ *
+ *
+ * let gifFast;
+ * let gifSlow;
*
* function preload() {
* gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
@@ -1158,24 +1494,40 @@ p5.Image = class {
* }
*
* function setup() {
- * gifFast.resize(width / 2, height / 2);
- * gifSlow.resize(width / 2, height / 2);
- *
- * //Change the delay here
+ * gifFast.resize(50, 50);
+ * gifSlow.resize(50, 50);
* gifFast.delay(10);
* gifSlow.delay(100);
* }
*
* function draw() {
- * background(255);
* image(gifFast, 0, 0);
- * image(gifSlow, width / 2, 0);
+ * image(gifSlow, 50, 0);
+ *
+ * describe('Two animated eyes looking around. The eye on the left moves faster than the eye on the right.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let gif;
+ *
+ * function preload() {
+ * gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
+ * }
+ *
+ * function setup() {
+ * gif.delay(3000, 67);
* }
- *
- * @alt
- * Two animated gifs of cartoon eyes looking around
- * The gif on the left animates quickly, on the right
- * the animation is much slower
+ *
+ * function draw() {
+ * image(gif, 0, 0);
+ *
+ * describe('An animated eye looking around. It pauses for three seconds while it looks down.');
+ * }
+ *
+ *