diff --git a/preview/index.html b/preview/index.html index deb1e21e11..ac5bedefcc 100644 --- a/preview/index.html +++ b/preview/index.html @@ -20,8 +20,12 @@ import p5 from '../src/app.js'; const sketch = function (p) { + let g, f; + p.setup = function () { p.createCanvas(200, 200); + g = p.createGraphics(200, 200); + f = p.createGraphics(200, 200, p.WEBGL); }; p.draw = function () { @@ -31,6 +35,10 @@ p.fill('white'); p.textSize(30); p.text('hello', 10, 30); + + // f.fill('red'); + f.sphere(); + p.image(f, 0, 0); }; }; diff --git a/src/app.js b/src/app.js index 210f0c444d..85c99e2e11 100644 --- a/src/app.js +++ b/src/app.js @@ -5,9 +5,6 @@ import './core/friendly_errors/validate_params'; import './core/friendly_errors/file_errors'; import './core/friendly_errors/fes_core'; import './core/friendly_errors/sketch_reader'; -import './core/p5.Element'; -// import './core/p5.Graphics'; -// import './core/rendering'; import shape from './shape'; shape(p5); diff --git a/src/core/main.js b/src/core/main.js index 3b58026346..6914a754da 100644 --- a/src/core/main.js +++ b/src/core/main.js @@ -665,7 +665,7 @@ import rendering from './rendering'; import renderer from './p5.Renderer'; import renderer2D from './p5.Renderer2D'; import graphics from './p5.Graphics'; -import element from './p5.Element'; +// import element from './p5.Element'; p5.registerAddon(transform); p5.registerAddon(structure); @@ -674,6 +674,6 @@ p5.registerAddon(rendering); p5.registerAddon(renderer); p5.registerAddon(renderer2D); p5.registerAddon(graphics); -p5.registerAddon(element); +// p5.registerAddon(element); export default p5; diff --git a/src/core/p5.Element.js b/src/core/p5.Element.js deleted file mode 100644 index fdfa402a65..0000000000 --- a/src/core/p5.Element.js +++ /dev/null @@ -1,998 +0,0 @@ -/** - * @module DOM - * @submodule DOM - * @for p5.Element - */ - -class Element { - constructor(elt, pInst) { - this.elt = elt; - this._pInst = this._pixelsState = pInst; - this._events = {}; - this.width = this.elt.offsetWidth; - this.height = this.elt.offsetHeight; - } - - /** - * Attaches the element to a parent element. - * - * For example, a `<div></div>` element may be used as a box to - * hold two pieces of text, a header and a paragraph. The - * `<div></div>` is the parent element of both the header and - * paragraph. - * - * The parameter `parent` can have one of three types. `parent` can be a - * string with the parent element's ID, as in - * `myElement.parent('container')`. It can also be another - * p5.Element object, as in - * `myElement.parent(myDiv)`. Finally, `parent` can be an `HTMLElement` - * object, as in `myElement.parent(anotherElement)`. - * - * Calling `myElement.parent()` without an argument returns the element's - * parent. - * - * @param {String|p5.Element|Object} parent ID, p5.Element, - * or HTMLElement of desired parent element. - * @chainable - * - * @example - *
- * function setup() {
- * background(200);
- *
- * // Create a div element.
- * let div = createDiv();
- *
- * // Place the div in the top-left corner.
- * div.position(10, 20);
- *
- * // Set its width and height.
- * div.size(80, 60);
- *
- * // Set its background color to white
- * div.style('background-color', 'white');
- *
- * // Align any text to the center.
- * div.style('text-align', 'center');
- *
- * // Set its ID to "container".
- * div.id('container');
- *
- * // Create a paragraph element.
- * let p = createP('p5*js');
- *
- * // Make the div its parent
- * // using its ID "container".
- * p.parent('container');
- *
- * describe('The text "p5*js" written in black at the center of a white rectangle. The rectangle is inside a gray square.');
- * }
- *
- *
- * function setup() {
- * background(200);
- *
- * // Create rectangular div element.
- * let div = createDiv();
- *
- * // Place the div in the top-left corner.
- * div.position(10, 20);
- *
- * // Set its width and height.
- * div.size(80, 60);
- *
- * // Set its background color and align
- * // any text to the center.
- * div.style('background-color', 'white');
- * div.style('text-align', 'center');
- *
- * // Create a paragraph element.
- * let p = createP('p5*js');
- *
- * // Make the div its parent.
- * p.parent(div);
- *
- * describe('The text "p5*js" written in black at the center of a white rectangle. The rectangle is inside a gray square.');
- * }
- *
- *
- * function setup() {
- * background(200);
- *
- * // Create rectangular div element.
- * let div = createDiv();
- *
- * // Place the div in the top-left corner.
- * div.position(10, 20);
- *
- * // Set its width and height.
- * div.size(80, 60);
- *
- * // Set its background color and align
- * // any text to the center.
- * div.style('background-color', 'white');
- * div.style('text-align', 'center');
- *
- * // Create a paragraph element.
- * let p = createP('p5*js');
- *
- * // Make the div its parent
- * // using the underlying
- * // HTMLElement.
- * p.parent(div.elt);
- *
- * describe('The text "p5*js" written in black at the center of a white rectangle. The rectangle is inside a gray square.');
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Set the canvas' ID
- * // to "mycanvas".
- * cnv.id('mycanvas');
- *
- * // Get the canvas' ID.
- * let id = cnv.id();
- * text(id, 24, 54);
- *
- * describe('The text "mycanvas" written in black on a gray background.');
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Add the class "small" to the
- * // canvas element.
- * cnv.class('small');
- *
- * // Get the canvas element's class
- * // and display it.
- * let c = cnv.class();
- * text(c, 35, 54);
- *
- * describe('The word "small" written in black on a gray canvas.');
- *
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the canvas
- * // is pressed.
- * cnv.mousePressed(randomColor);
- *
- * describe('A gray square changes color when the mouse is pressed.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // canvas is double-clicked.
- * cnv.doubleClicked(randomColor);
- *
- * describe('A gray square changes color when the user double-clicks the canvas.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // mouse wheel moves.
- * cnv.mouseWheel(randomColor);
- *
- * describe('A gray square changes color when the user scrolls the mouse wheel over the canvas.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call changeBackground() when the
- * // mouse wheel moves.
- * cnv.mouseWheel(changeBackground);
- *
- * describe('A gray square. When the mouse wheel scrolls over the square, it changes color and displays shapes.');
- * }
- *
- * function changeBackground(event) {
- * // Change the background color
- * // based on deltaY.
- * if (event.deltaY > 0) {
- * background('deeppink');
- * } else if (event.deltaY < 0) {
- * background('cornflowerblue');
- * } else {
- * background(200);
- * }
- *
- * // Draw a shape based on deltaX.
- * if (event.deltaX > 0) {
- * circle(50, 50, 20);
- * } else if (event.deltaX < 0) {
- * square(40, 40, 20);
- * }
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when a
- * // mouse press ends.
- * cnv.mouseReleased(randomColor);
- *
- * describe('A gray square changes color when the user releases a mouse press.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when a
- * // mouse press ends.
- * cnv.mouseClicked(randomColor);
- *
- * describe('A gray square changes color when the user releases a mouse press.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // mouse moves.
- * cnv.mouseMoved(randomColor);
- *
- * describe('A gray square changes color when the mouse moves over the canvas.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // mouse moves onto the canvas.
- * cnv.mouseOver(randomColor);
- *
- * describe('A gray square changes color when the mouse moves onto the canvas.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // mouse moves off the canvas.
- * cnv.mouseOut(randomColor);
- *
- * describe('A gray square changes color when the mouse moves off the canvas.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // user touches the canvas.
- * cnv.touchStarted(randomColor);
- *
- * describe('A gray square changes color when the user touches the canvas.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // user touches the canvas
- * // and moves.
- * cnv.touchMoved(randomColor);
- *
- * describe('A gray square changes color when the user touches the canvas and moves.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call randomColor() when the
- * // user touches the canvas,
- * // then lifts their finger.
- * cnv.touchEnded(randomColor);
- *
- * describe('A gray square changes color when the user touches the canvas, then lifts their finger.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * // Drag a file over the canvas to test.
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call helloFile() when a
- * // file is dragged over
- * // the canvas.
- * cnv.dragOver(helloFile);
- *
- * describe('A gray square. The text "hello, file" appears when a file is dragged over the square.');
- * }
- *
- * function helloFile() {
- * text('hello, file', 50, 50);
- * }
- *
- *
- * // Drag a file over, then off
- * // the canvas to test.
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Call byeFile() when a
- * // file is dragged over,
- * // then off the canvas.
- * cnv.dragLeave(byeFile);
- *
- * describe('A gray square. The text "bye, file" appears when a file is dragged over, then off the square.');
- * }
- *
- * function byeFile() {
- * text('bye, file', 50, 50);
- * }
- *
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Create a button element and
- * // place it beneath the canvas.
- * let btn = createButton('change');
- * btn.position(0, 100);
- *
- * // Call randomColor() when
- * // the button is pressed.
- * btn.mousePressed(randomColor);
- *
- * describe('A gray square with a button that says "change" beneath it. The square changes color when the user presses the button.');
- * }
- *
- * // Paint the background either
- * // red, yellow, blue, or green.
- * function randomColor() {
- * let c = random(['red', 'yellow', 'blue', 'green']);
- * background(c);
- * }
- *
- *
- * function setup() {
- * // Create a canvas element and
- * // assign it to cnv.
- * let cnv = createCanvas(100, 100);
- *
- * background(200);
- *
- * // Set the border style for the
- * // canvas.
- * cnv.elt.style.border = '5px dashed deeppink';
- *
- * describe('A gray square with a pink border drawn with dashed lines.');
- * }
- *
- *
- * let slider;
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Create a slider and place it beneath the canvas.
- * slider = createSlider(0, 255, 200);
- * slider.position(0, 100);
- *
- * // Call repaint() when the slider changes.
- * slider.input(repaint);
- *
- * describe('A gray square with a range slider underneath it. The background changes shades of gray when the slider is moved.');
- * }
- *
- * // Paint the background using slider's value.
- * function repaint() {
- * let g = slider.value();
- * background(g);
- * }
- *
- *
- * let input;
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Create an input and place it beneath the canvas.
- * input = createInput('');
- * input.position(0, 100);
- *
- * // Call repaint() when input is detected.
- * input.input(repaint);
- *
- * describe('A gray square with a text input bar beneath it. Any text written in the input appears in the middle of the square.');
- * }
- *
- * // Paint the background gray and display the input's value.
- * function repaint() {
- * background(200);
- * let msg = input.value();
- * text(msg, 5, 50);
- * }
- *
- *
- * let dropdown;
- *
* function setup() {
- * createCanvas(100, 100);
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
* background(200);
*
- * // Create a dropdown menu and add a few color options.
- * dropdown = createSelect();
- * dropdown.position(0, 0);
- * dropdown.option('red');
- * dropdown.option('green');
- * dropdown.option('blue');
- *
- * // Call paintBackground() when the color option changes.
- * dropdown.changed(paintBackground);
- *
- * describe('A gray square with a dropdown menu at the top. The square changes color when an option is selected.');
- * }
+ * // Set the border style for the
+ * // canvas.
+ * cnv.elt.style.border = '5px dashed deeppink';
*
- * // Paint the background with the selected color.
- * function paintBackground() {
- * let c = dropdown.value();
- * background(c);
+ * describe('A gray square with a pink border drawn with dashed lines.');
* }
*
*
- * let checkbox;
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Create a checkbox and place it beneath the canvas.
- * checkbox = createCheckbox(' circle');
- * checkbox.position(0, 100);
- *
- * // Call repaint() when the checkbox changes.
- * checkbox.changed(repaint);
- *
- * describe('A gray square with a checkbox underneath it that says "circle". A white circle appears when the box is checked and disappears otherwise.');
- * }
- *
- * // Paint the background gray and determine whether to draw a circle.
- * function repaint() {
- * background(200);
- * if (checkbox.checked() === true) {
- * circle(50, 50, 30);
- * }
- * }
- *
- *
+ * let p;
+ *
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Create a div element.
- * let div = createDiv('div');
+ * // Create a paragraph element.
+ * p = createP('p5*js');
+ * p.position(10, 10);
*
- * // Add a class to the div.
- * div.addClass('myClass');
+ * describe('The text "p5*js" written at the center of a gray square. ');
+ * }
*
- * describe('A gray square.');
+ * // Remove the paragraph when the user double-clicks.
+ * function doubleClicked() {
+ * p.remove();
* }
*
*
- * // In this example, a class is set when the div is created
- * // and removed when mouse is pressed. This could link up
- * // with a CSS style rule to toggle style properties.
+ * function setup() {
+ * background(200);
*
- * let div;
+ * // Create a div element.
+ * let div = createDiv();
*
- * function setup() {
- * createCanvas(100, 100);
+ * // Place the div in the top-left corner.
+ * div.position(10, 20);
*
- * background(200);
+ * // Set its width and height.
+ * div.size(80, 60);
*
- * // Create a div element.
- * div = createDiv('div');
+ * // Set its background color to white
+ * div.style('background-color', 'white');
*
- * // Add a class to the div.
- * div.addClass('myClass');
+ * // Align any text to the center.
+ * div.style('text-align', 'center');
*
- * describe('A gray square.');
- * }
+ * // Set its ID to "container".
+ * div.id('container');
*
- * // Remove 'myClass' from the div when the user presses the mouse.
- * function mousePressed() {
- * div.removeClass('myClass');
+ * // Create a paragraph element.
+ * let p = createP('p5*js');
+ *
+ * // Make the div its parent
+ * // using its ID "container".
+ * p.parent('container');
+ *
+ * describe('The text "p5*js" written in black at the center of a white rectangle. The rectangle is inside a gray square.');
* }
*
*
- * let div;
+ * function setup() {
+ * background(200);
*
- * function setup() {
- * createCanvas(100, 100);
+ * // Create rectangular div element.
+ * let div = createDiv();
*
- * background(200);
+ * // Place the div in the top-left corner.
+ * div.position(10, 20);
*
- * // Create a div element.
- * div = createDiv('div');
+ * // Set its width and height.
+ * div.size(80, 60);
*
- * // Add the class 'show' to the div.
- * div.addClass('show');
+ * // Set its background color and align
+ * // any text to the center.
+ * div.style('background-color', 'white');
+ * div.style('text-align', 'center');
*
- * describe('A gray square.');
- * }
+ * // Create a paragraph element.
+ * let p = createP('p5*js');
*
- * // Toggle the class 'show' when the mouse is pressed.
- * function mousePressed() {
- * if (div.hasClass('show')) {
- * div.addClass('show');
- * } else {
- * div.removeClass('show');
- * }
+ * // Make the div its parent.
+ * p.parent(div);
+ *
+ * describe('The text "p5*js" written in black at the center of a white rectangle. The rectangle is inside a gray square.');
* }
*
*
- * let div;
+ * function setup() {
+ * background(200);
*
- * function setup() {
- * createCanvas(100, 100);
+ * // Create rectangular div element.
+ * let div = createDiv();
*
- * background(200);
+ * // Place the div in the top-left corner.
+ * div.position(10, 20);
*
- * // Create a div element.
- * div = createDiv('div');
+ * // Set its width and height.
+ * div.size(80, 60);
*
- * // Add the 'show' class to the div.
- * div.addClass('show');
+ * // Set its background color and align
+ * // any text to the center.
+ * div.style('background-color', 'white');
+ * div.style('text-align', 'center');
*
- * describe('A gray square.');
- * }
+ * // Create a paragraph element.
+ * let p = createP('p5*js');
*
- * // Toggle the 'show' class when the mouse is pressed.
- * function mousePressed() {
- * div.toggleClass('show');
+ * // Make the div its parent
+ * // using the underlying
+ * // HTMLElement.
+ * p.parent(div.elt);
+ *
+ * describe('The text "p5*js" written in black at the center of a white rectangle. The rectangle is inside a gray square.');
* }
*
*
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Create the div element and style it.
- * let div = createDiv('');
- * div.size(10, 10);
- * div.style('background-color', 'orange');
- *
- * // Center the div relative to the page's body.
- * div.center();
- *
- * describe('A gray square and an orange rectangle. The rectangle is at the center of the page.');
- * }
- *
- *
* function setup() {
* createCanvas(100, 100);
@@ -492,7 +446,7 @@ function element(p5, fn){
* @param {Boolean} [append] whether to append HTML to existing
* @chainable
*/
- p5.Element.prototype.html = function (...args) {
+ html(...args) {
if (args.length === 0) {
return this.elt.innerHTML;
} else if (args[1]) {
@@ -502,817 +456,1834 @@ function element(p5, fn){
this.elt.innerHTML = args[0];
return this;
}
- };
+ }
/**
- * Sets the element's position.
+ * Sets the element's ID using a given string.
*
- * The first two parameters, `x` and `y`, set the element's position relative
- * to the top-left corner of the web page.
- *
- * The third parameter, `positionType`, is optional. It sets the element's
- * positioning scheme.
- * `positionType` is a string that can be either `'static'`, `'fixed'`,
- * `'relative'`, `'sticky'`, `'initial'`, or `'inherit'`.
+ * Calling `myElement.id()` without an argument returns its ID as a string.
*
- * If no arguments passed, as in `myElement.position()`, the method returns
- * the element's position in an object, as in `{ x: 0, y: 0 }`.
- *
- * @method position
- * @returns {Object} object of form `{ x: 0, y: 0 }` containing the element's position.
+ * @param {String} id ID of the element.
+ * @chainable
*
* @example
*
- *
+ *
* function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
* let cnv = createCanvas(100, 100);
*
* background(200);
*
- * // Positions the canvas 50px to the right and 100px
- * // below the top-left corner of the window.
- * cnv.position(50, 100);
+ * // Set the canvas' ID
+ * // to "mycanvas".
+ * cnv.id('mycanvas');
*
- * describe('A gray square that is 50 pixels to the right and 100 pixels down from the top-left corner of the web page.');
+ * // Get the canvas' ID.
+ * let id = cnv.id();
+ * text(id, 24, 54);
+ *
+ * describe('The text "mycanvas" written in black on a gray background.');
* }
*
*
+ */
+ /**
+ * @return {String} ID of the element.
+ */
+ id(id) {
+ if (typeof id === 'undefined') {
+ return this.elt.id;
+ }
+
+ this.elt.id = id;
+ this.width = this.elt.offsetWidth;
+ this.height = this.elt.offsetHeight;
+ return this;
+ }
+
+ /**
+ * Adds a
+ * class attribute
+ * to the element using a given string.
+ *
+ * Calling `myElement.class()` without an argument returns a string with its current classes.
+ *
+ * @param {String} class class to add.
+ * @chainable
*
+ * @example
*
- *
+ *
* function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
* let cnv = createCanvas(100, 100);
*
* background(200);
*
- * // Positions the canvas at the top-left corner
- * // of the window with a 'fixed' position type.
- * cnv.position(0, 0, 'fixed');
+ * // Add the class "small" to the
+ * // canvas element.
+ * cnv.class('small');
+ *
+ * // Get the canvas element's class
+ * // and display it.
+ * let c = cnv.class();
+ * text(c, 35, 54);
+ *
+ * describe('The word "small" written in black on a gray canvas.');
*
- * describe('A gray square in the top-left corner of the web page.');
* }
*
*
*/
/**
- * @method position
- * @param {Number} [x] x-position relative to top-left of window (optional)
- * @param {Number} [y] y-position relative to top-left of window (optional)
- * @param {String} [positionType] it can be static, fixed, relative, sticky, initial or inherit (optional)
- * @chainable
+ * @return {String} element's classes, if any.
*/
- p5.Element.prototype.position = function (...args) {
- if (args.length === 0) {
- return { x: this.elt.offsetLeft, y: this.elt.offsetTop };
- } else {
- let positionType = 'absolute';
- if (
- args[2] === 'static' ||
- args[2] === 'fixed' ||
- args[2] === 'relative' ||
- args[2] === 'sticky' ||
- args[2] === 'initial' ||
- args[2] === 'inherit'
- ) {
- positionType = args[2];
- }
- this.elt.style.position = positionType;
- this.elt.style.left = args[0] + 'px';
- this.elt.style.top = args[1] + 'px';
- this.x = args[0];
- this.y = args[1];
- return this;
- }
- };
-
- /* Helper method called by p5.Element.style() */
- p5.Element.prototype._translate = function (...args) {
- this.elt.style.position = 'absolute';
- // save out initial non-translate transform styling
- let transform = '';
- if (this.elt.style.transform) {
- transform = this.elt.style.transform.replace(/translate3d\(.*\)/g, '');
- transform = transform.replace(/translate[X-Z]?\(.*\)/g, '');
- }
- if (args.length === 2) {
- this.elt.style.transform =
- 'translate(' + args[0] + 'px, ' + args[1] + 'px)';
- } else if (args.length > 2) {
- this.elt.style.transform =
- 'translate3d(' +
- args[0] +
- 'px,' +
- args[1] +
- 'px,' +
- args[2] +
- 'px)';
- if (args.length === 3) {
- this.elt.parentElement.style.perspective = '1000px';
- } else {
- this.elt.parentElement.style.perspective = args[3] + 'px';
- }
- }
- // add any extra transform styling back on end
- this.elt.style.transform += transform;
- return this;
- };
-
- /* Helper method called by p5.Element.style() */
- p5.Element.prototype._rotate = function (...args) {
- // save out initial non-rotate transform styling
- let transform = '';
- if (this.elt.style.transform) {
- transform = this.elt.style.transform.replace(/rotate3d\(.*\)/g, '');
- transform = transform.replace(/rotate[X-Z]?\(.*\)/g, '');
+ class(c) {
+ if (typeof c === 'undefined') {
+ return this.elt.className;
}
- if (args.length === 1) {
- this.elt.style.transform = 'rotate(' + args[0] + 'deg)';
- } else if (args.length === 2) {
- this.elt.style.transform =
- 'rotate(' + args[0] + 'deg, ' + args[1] + 'deg)';
- } else if (args.length === 3) {
- this.elt.style.transform = 'rotateX(' + args[0] + 'deg)';
- this.elt.style.transform += 'rotateY(' + args[1] + 'deg)';
- this.elt.style.transform += 'rotateZ(' + args[2] + 'deg)';
- }
- // add remaining transform back on
- this.elt.style.transform += transform;
+ this.elt.className = c;
return this;
- };
+ }
/**
- * Applies a style to the element by adding a
- * CSS declaration.
*
- * The first parameter, `property`, is a string. If the name of a style
- * property is passed, as in `myElement.style('color')`, the method returns
- * the current value as a string or `null` if it hasn't been set. If a
- * `property:style` string is passed, as in
- * `myElement.style('color:deeppink')`, the method sets the style `property`
- * to `value`.
- *
- * The second parameter, `value`, is optional. It sets the property's value.
- * `value` can be a string, as in
- * `myElement.style('color', 'deeppink')`, or a
- * p5.Color object, as in
- * `myElement.style('color', myColor)`.
+ * Adds a class to the element.
*
- * @method style
- * @param {String} property style property to set.
- * @returns {String} value of the property.
+ * @for p5.Element
+ * @method addClass
+ * @param {String} class name of class to add.
+ * @chainable
*
* @example
- *
+ *
*
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Create a paragraph element and set its font color to "deeppink".
- * let p = createP('p5*js');
- * p.position(25, 20);
- * p.style('color', 'deeppink');
+ * // Create a div element.
+ * let div = createDiv('div');
*
- * describe('The text p5*js written in pink on a gray background.');
+ * // Add a class to the div.
+ * div.addClass('myClass');
+ *
+ * describe('A gray square.');
* }
*
*
+ */
+ addClass(c) {
+ if (this.elt.className) {
+ if (!this.hasClass(c)) {
+ this.elt.className = this.elt.className + ' ' + c;
+ }
+ } else {
+ this.elt.className = c;
+ }
+ return this;
+ }
+
+ /**
+ * Removes a class from the element.
*
- *
+ * @method removeClass
+ * @param {String} class name of class to remove.
+ * @chainable
+ *
+ * @example
+ *
*
+ * // In this example, a class is set when the div is created
+ * // and removed when mouse is pressed. This could link up
+ * // with a CSS style rule to toggle style properties.
+ *
+ * let div;
+ *
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Create a p5.Color object.
- * let c = color('deeppink');
+ * // Create a div element.
+ * div = createDiv('div');
*
- * // Create a paragraph element and set its font color using a p5.Color object.
- * let p = createP('p5*js');
- * p.position(25, 20);
- * p.style('color', c);
+ * // Add a class to the div.
+ * div.addClass('myClass');
*
- * describe('The text p5*js written in pink on a gray background.');
+ * describe('A gray square.');
* }
- *
+ *
+ * // Remove 'myClass' from the div when the user presses the mouse.
+ * function mousePressed() {
+ * div.removeClass('myClass');
+ * }
+ *
*
+ */
+ removeClass(c) {
+ // Note: Removing a class that does not exist does NOT throw an error in classList.remove method
+ this.elt.classList.remove(c);
+ return this;
+ }
+
+ /**
+ * Checks if a class is already applied to element.
*
- *
+ * @method hasClass
+ * @returns {boolean} a boolean value if element has specified class.
+ * @param c {String} name of class to check.
+ *
+ * @example
+ *
*
+ * let div;
+ *
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Create a paragraph element and set its font color to "deeppink"
- * // using property:value syntax.
- * let p = createP('p5*js');
- * p.position(25, 20);
- * p.style('color:deeppink');
+ * // Create a div element.
+ * div = createDiv('div');
*
- * describe('The text p5*js written in pink on a gray background.');
+ * // Add the class 'show' to the div.
+ * div.addClass('show');
+ *
+ * describe('A gray square.');
+ * }
+ *
+ * // Toggle the class 'show' when the mouse is pressed.
+ * function mousePressed() {
+ * if (div.hasClass('show')) {
+ * div.addClass('show');
+ * } else {
+ * div.removeClass('show');
+ * }
* }
*
*
+ */
+ hasClass(c) {
+ return this.elt.classList.contains(c);
+ }
+
+ /**
+ * Toggles whether a class is applied to the element.
*
- *
+ * @method toggleClass
+ * @param c {String} class name to toggle.
+ * @chainable
+ *
+ * @example
+ *
*
+ * let div;
+ *
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Create an empty paragraph element and set its font color to "deeppink".
- * let p = createP();
- * p.position(5, 5);
- * p.style('color', 'deeppink');
+ * // Create a div element.
+ * div = createDiv('div');
*
- * // Get the element's color as an RGB color string.
- * let c = p.style('color');
+ * // Add the 'show' class to the div.
+ * div.addClass('show');
*
- * // Set the element's inner HTML using the RGB color string.
- * p.html(c);
+ * describe('A gray square.');
+ * }
*
- * describe('The text "rgb(255, 20, 147)" written in pink on a gray background.');
+ * // Toggle the 'show' class when the mouse is pressed.
+ * function mousePressed() {
+ * div.toggleClass('show');
* }
*
*
*/
+ toggleClass(c) {
+ // classList also has a toggle() method, but we cannot use that yet as support is unclear.
+ // See https://github.com/processing/p5.js/issues/3631
+ // this.elt.classList.toggle(c);
+ if (this.elt.classList.contains(c)) {
+ this.elt.classList.remove(c);
+ } else {
+ this.elt.classList.add(c);
+ }
+ return this;
+ }
+
/**
- * @method style
- * @param {String} property
- * @param {String|p5.Color} value value to assign to the property.
- * @return {String} value of the property.
+ * Centers the element either vertically, horizontally, or both.
+ *
+ * `center()` will center the element relative to its parent or according to
+ * the page's body if the element has no parent.
+ *
+ * If no argument is passed, as in `myElement.center()` the element is aligned
+ * both vertically and horizontally.
+ *
+ * @method center
+ * @param {String} [align] passing 'vertical', 'horizontal' aligns element accordingly
* @chainable
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create the div element and style it.
+ * let div = createDiv('');
+ * div.size(10, 10);
+ * div.style('background-color', 'orange');
+ *
+ * // Center the div relative to the page's body.
+ * div.center();
+ *
+ * describe('A gray square and an orange rectangle. The rectangle is at the center of the page.');
+ * }
+ *
+ *
*/
- p5.Element.prototype.style = function (prop, val) {
- const self = this;
+ center(align) {
+ const style = this.elt.style.display;
+ const hidden = this.elt.style.display === 'none';
+ const parentHidden = this.parent().style.display === 'none';
+ const pos = { x: this.elt.offsetLeft, y: this.elt.offsetTop };
- if (val instanceof p5.Color) {
- val =
- 'rgba(' +
- val.levels[0] +
- ',' +
- val.levels[1] +
- ',' +
- val.levels[2] +
- ',' +
- val.levels[3] / 255 +
- ')';
- }
+ if (hidden) this.show();
+ if (parentHidden) this.parent().show();
+ this.elt.style.display = 'block';
- if (typeof val === 'undefined') {
- if (prop.indexOf(':') === -1) {
- // no value set, so assume requesting a value
- let styles = window.getComputedStyle(self.elt);
- let style = styles.getPropertyValue(prop);
- return style;
- } else {
- // value set using `:` in a single line string
- const attrs = prop.split(';');
- for (let i = 0; i < attrs.length; i++) {
- const parts = attrs[i].split(':');
- if (parts[0] && parts[1]) {
- this.elt.style[parts[0].trim()] = parts[1].trim();
- }
- }
- }
- } else {
- // input provided as key,val pair
- this.elt.style[prop] = val;
- if (
- prop === 'width' ||
- prop === 'height' ||
- prop === 'left' ||
- prop === 'top'
- ) {
- let styles = window.getComputedStyle(self.elt);
- let styleVal = styles.getPropertyValue(prop);
- let numVal = styleVal.replace(/[^\d.]/g, '');
- this[prop] = Math.round(parseFloat(numVal, 10));
- }
+ this.position(0, 0);
+ const wOffset = Math.abs(this.parent().offsetWidth - this.elt.offsetWidth);
+ const hOffset = Math.abs(this.parent().offsetHeight - this.elt.offsetHeight);
+
+ if (align === 'both' || align === undefined) {
+ this.position(
+ wOffset / 2 + this.parent().offsetLeft,
+ hOffset / 2 + this.parent().offsetTop
+ );
+ } else if (align === 'horizontal') {
+ this.position(wOffset / 2 + this.parent().offsetLeft, pos.y);
+ } else if (align === 'vertical') {
+ this.position(pos.x, hOffset / 2 + this.parent().offsetTop);
}
+
+ this.style('display', style);
+ if (hidden) this.hide();
+ if (parentHidden) this.parent().hide();
+
return this;
- };
+ }
/**
- * Adds an
- * attribute
- * to the element.
+ * Sets the element's position.
*
- * This method is useful for advanced tasks. Most commonly-used attributes,
- * such as `id`, can be set with their dedicated methods. For example,
- * `nextButton.id('next')` sets an element's `id` attribute. Calling
- * `nextButton.attribute('id', 'next')` has the same effect.
+ * The first two parameters, `x` and `y`, set the element's position relative
+ * to the top-left corner of the web page.
*
- * The first parameter, `attr`, is the attribute's name as a string. Calling
- * `myElement.attribute('align')` returns the attribute's current value as a
- * string or `null` if it hasn't been set.
+ * The third parameter, `positionType`, is optional. It sets the element's
+ * positioning scheme.
+ * `positionType` is a string that can be either `'static'`, `'fixed'`,
+ * `'relative'`, `'sticky'`, `'initial'`, or `'inherit'`.
+ *
+ * If no arguments passed, as in `myElement.position()`, the method returns
+ * the element's position in an object, as in `{ x: 0, y: 0 }`.
+ *
+ * @method position
+ * @returns {Object} object of form `{ x: 0, y: 0 }` containing the element's position.
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Positions the canvas 50px to the right and 100px
+ * // below the top-left corner of the window.
+ * cnv.position(50, 100);
+ *
+ * describe('A gray square that is 50 pixels to the right and 100 pixels down from the top-left corner of the web page.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * function setup() {
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Positions the canvas at the top-left corner
+ * // of the window with a 'fixed' position type.
+ * cnv.position(0, 0, 'fixed');
+ *
+ * describe('A gray square in the top-left corner of the web page.');
+ * }
+ *
+ *
+ */
+ /**
+ * @method position
+ * @param {Number} [x] x-position relative to top-left of window (optional)
+ * @param {Number} [y] y-position relative to top-left of window (optional)
+ * @param {String} [positionType] it can be static, fixed, relative, sticky, initial or inherit (optional)
+ * @chainable
+ */
+ position(...args) {
+ if (args.length === 0) {
+ return { x: this.elt.offsetLeft, y: this.elt.offsetTop };
+ } else {
+ let positionType = 'absolute';
+ if (
+ args[2] === 'static' ||
+ args[2] === 'fixed' ||
+ args[2] === 'relative' ||
+ args[2] === 'sticky' ||
+ args[2] === 'initial' ||
+ args[2] === 'inherit'
+ ) {
+ positionType = args[2];
+ }
+ this.elt.style.position = positionType;
+ this.elt.style.left = args[0] + 'px';
+ this.elt.style.top = args[1] + 'px';
+ this.x = args[0];
+ this.y = args[1];
+ return this;
+ }
+ }
+
+ /**
+ * Shows the current element.
+ *
+ * @method show
+ * @chainable
+ *
+ * @example
+ *
+ *
+ * let p;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a paragraph element and hide it.
+ * p = createP('p5*js');
+ * p.position(10, 10);
+ * p.hide();
+ *
+ * describe('A gray square. The text "p5*js" appears when the user double-clicks the square.');
+ * }
+ *
+ * // Show the paragraph when the user double-clicks.
+ * function doubleClicked() {
+ * p.show();
+ * }
+ *
+ *
+ */
+ show() {
+ this.elt.style.display = 'block';
+ return this;
+ }
+
+ /**
+ * Hides the current element.
+ *
+ * @method hide
+ * @chainable
+ *
+ * @example
+ * let p;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a paragraph element.
+ * p = createP('p5*js');
+ * p.position(10, 10);
+ *
+ * describe('The text "p5*js" at the center of a gray square. The text disappears when the user double-clicks the square.');
+ * }
+ *
+ * // Hide the paragraph when the user double-clicks.
+ * function doubleClicked() {
+ * p.hide();
+ * }
+ *
+ *
+ */
+ hide() {
+ this.elt.style.display = 'none';
+ return this;
+ }
+
+ /**
+ * Sets the element's width and height.
+ *
+ * Calling `myElement.size()` without an argument returns the element's size
+ * as an object with the properties `width` and `height`. For example,
+ * `{ width: 20, height: 10 }`.
+ *
+ * The first parameter, `width`, is optional. It's a number used to set the
+ * element's width. Calling `myElement.size(10)`
+ *
+ * The second parameter, 'height`, is also optional. It's a
+ * number used to set the element's height. For example, calling
+ * `myElement.size(20, 10)` sets the element's width to 20 pixels and height
+ * to 10 pixels.
+ *
+ * The constant `AUTO` can be used to adjust one dimension at a time while
+ * maintaining the aspect ratio, which is `width / height`. For example,
+ * consider an element that's 200 pixels wide and 100 pixels tall. Calling
+ * `myElement.size(20, AUTO)` sets the width to 20 pixels and height to 10
+ * pixels.
+ *
+ * Note: In the case of elements that need to load data, such as images, wait
+ * to call `myElement.size()` until after the data loads.
+ *
+ * @method size
+ * @return {Object} width and height of the element in an object.
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a pink div element and place it at the top-left corner.
+ * let div = createDiv();
+ * div.position(10, 10);
+ * div.style('background-color', 'deeppink');
+ *
+ * // Set the div's width to 80 pixels and height to 20 pixels.
+ * div.size(80, 20);
+ *
+ * describe('A gray square with a pink rectangle near its top.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a pink div element and place it at the top-left corner.
+ * let div = createDiv();
+ * div.position(10, 10);
+ * div.style('background-color', 'deeppink');
+ *
+ * // Set the div's width to 80 pixels and height to 40 pixels.
+ * div.size(80, 40);
+ *
+ * // Get the div's size as an object.
+ * let s = div.size();
+ *
+ * // Display the div's dimensions.
+ * div.html(`${s.width} x ${s.height}`);
+ *
+ * describe('A gray square with a pink rectangle near its top. The text "80 x 40" is written within the rectangle.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let img1;
+ * let img2;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Load an image of an astronaut on the moon
+ * // and place it at the top-left of the canvas.
+ * img1 = createImg(
+ * 'assets/moonwalk.jpg',
+ * 'An astronaut walking on the moon',
+ * ''
+ * );
+ * img1.position(0, 0);
+ *
+ * // Load an image of an astronaut on the moon
+ * // and place it at the top-left of the canvas.
+ * // Resize the image once it's loaded.
+ * img2 = createImg(
+ * 'assets/moonwalk.jpg',
+ * 'An astronaut walking on the moon',
+ * '',
+ * resizeImage
+ * );
+ * img2.position(0, 0);
+ *
+ * describe('A gray square two copies of a space image at the top-left. The copy in front is smaller.');
+ * }
+ *
+ * // Resize img2 and keep its aspect ratio.
+ * function resizeImage() {
+ * img2.size(50, AUTO);
+ * }
+ *
+ *
+ */
+ /**
+ * @method size
+ * @param {(Number|AUTO)} [w] width of the element, either AUTO, or a number.
+ * @param {(Number|AUTO)} [h] height of the element, either AUTO, or a number.
+ * @chainable
+ */
+ size(w, h) {
+ if (arguments.length === 0) {
+ return { width: this.elt.offsetWidth, height: this.elt.offsetHeight };
+ } else {
+ let aW = w;
+ let aH = h;
+ const AUTO = constants.AUTO;
+ if (aW !== AUTO || aH !== AUTO) {
+ if (aW === AUTO) {
+ aW = h * this.width / this.height;
+ } else if (aH === AUTO) {
+ aH = w * this.height / this.width;
+ }
+ // set diff for cnv vs normal div
+ if (this.elt instanceof HTMLCanvasElement) {
+ const j = {};
+ const k = this.elt.getContext('2d');
+ let prop;
+ for (prop in k) {
+ j[prop] = k[prop];
+ }
+ this.elt.setAttribute('width', aW * this._pInst._pixelDensity);
+ this.elt.setAttribute('height', aH * this._pInst._pixelDensity);
+ this.elt.style.width = aW + 'px';
+ this.elt.style.height = aH + 'px';
+ this._pInst.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);
+ for (prop in j) {
+ this.elt.getContext('2d')[prop] = j[prop];
+ }
+ } else {
+ this.elt.style.width = aW + 'px';
+ this.elt.style.height = aH + 'px';
+ this.elt.width = aW;
+ this.elt.height = aH;
+ }
+ this.width = aW;
+ this.height = aH;
+ if (this._pInst && this._pInst._curElement) {
+ // main canvas associated with p5 instance
+ if (this._pInst._curElement.elt === this.elt) {
+ this._pInst.width = aW;
+ this._pInst.height = aH;
+ }
+ }
+ }
+ return this;
+ }
+ }
+
+ /**
+ * Applies a style to the element by adding a
+ * CSS declaration.
+ *
+ * The first parameter, `property`, is a string. If the name of a style
+ * property is passed, as in `myElement.style('color')`, the method returns
+ * the current value as a string or `null` if it hasn't been set. If a
+ * `property:style` string is passed, as in
+ * `myElement.style('color:deeppink')`, the method sets the style `property`
+ * to `value`.
+ *
+ * The second parameter, `value`, is optional. It sets the property's value.
+ * `value` can be a string, as in
+ * `myElement.style('color', 'deeppink')`, or a
+ * p5.Color object, as in
+ * `myElement.style('color', myColor)`.
+ *
+ * @method style
+ * @param {String} property style property to set.
+ * @returns {String} value of the property.
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a paragraph element and set its font color to "deeppink".
+ * let p = createP('p5*js');
+ * p.position(25, 20);
+ * p.style('color', 'deeppink');
+ *
+ * describe('The text p5*js written in pink on a gray background.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a p5.Color object.
+ * let c = color('deeppink');
+ *
+ * // Create a paragraph element and set its font color using a p5.Color object.
+ * let p = createP('p5*js');
+ * p.position(25, 20);
+ * p.style('color', c);
+ *
+ * describe('The text p5*js written in pink on a gray background.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a paragraph element and set its font color to "deeppink"
+ * // using property:value syntax.
+ * let p = createP('p5*js');
+ * p.position(25, 20);
+ * p.style('color:deeppink');
+ *
+ * describe('The text p5*js written in pink on a gray background.');
+ * }
+ *
+ *
+ *
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create an empty paragraph element and set its font color to "deeppink".
+ * let p = createP();
+ * p.position(5, 5);
+ * p.style('color', 'deeppink');
+ *
+ * // Get the element's color as an RGB color string.
+ * let c = p.style('color');
+ *
+ * // Set the element's inner HTML using the RGB color string.
+ * p.html(c);
+ *
+ * describe('The text "rgb(255, 20, 147)" written in pink on a gray background.');
+ * }
+ *
+ *
+ */
+ /**
+ * @method style
+ * @param {String} property
+ * @param {String|p5.Color} value value to assign to the property.
+ * @return {String} value of the property.
+ * @chainable
+ */
+ style(prop, val) {
+ const self = this;
+
+ if (val instanceof Color) {
+ val =
+ 'rgba(' +
+ val.levels[0] +
+ ',' +
+ val.levels[1] +
+ ',' +
+ val.levels[2] +
+ ',' +
+ val.levels[3] / 255 +
+ ')';
+ }
+
+ if (typeof val === 'undefined') {
+ if (prop.indexOf(':') === -1) {
+ // no value set, so assume requesting a value
+ let styles = window.getComputedStyle(self.elt);
+ let style = styles.getPropertyValue(prop);
+ return style;
+ } else {
+ // value set using `:` in a single line string
+ const attrs = prop.split(';');
+ for (let i = 0; i < attrs.length; i++) {
+ const parts = attrs[i].split(':');
+ if (parts[0] && parts[1]) {
+ this.elt.style[parts[0].trim()] = parts[1].trim();
+ }
+ }
+ }
+ } else {
+ // input provided as key,val pair
+ this.elt.style[prop] = val;
+ if (
+ prop === 'width' ||
+ prop === 'height' ||
+ prop === 'left' ||
+ prop === 'top'
+ ) {
+ let styles = window.getComputedStyle(self.elt);
+ let styleVal = styles.getPropertyValue(prop);
+ let numVal = styleVal.replace(/[^\d.]/g, '');
+ this[prop] = Math.round(parseFloat(numVal, 10));
+ }
+ }
+ return this;
+ }
+
+ /* Helper method called by p5.Element.style() */
+ _translate(...args) {
+ this.elt.style.position = 'absolute';
+ // save out initial non-translate transform styling
+ let transform = '';
+ if (this.elt.style.transform) {
+ transform = this.elt.style.transform.replace(/translate3d\(.*\)/g, '');
+ transform = transform.replace(/translate[X-Z]?\(.*\)/g, '');
+ }
+ if (args.length === 2) {
+ this.elt.style.transform =
+ 'translate(' + args[0] + 'px, ' + args[1] + 'px)';
+ } else if (args.length > 2) {
+ this.elt.style.transform =
+ 'translate3d(' +
+ args[0] +
+ 'px,' +
+ args[1] +
+ 'px,' +
+ args[2] +
+ 'px)';
+ if (args.length === 3) {
+ this.elt.parentElement.style.perspective = '1000px';
+ } else {
+ this.elt.parentElement.style.perspective = args[3] + 'px';
+ }
+ }
+ // add any extra transform styling back on end
+ this.elt.style.transform += transform;
+ return this;
+ }
+
+ /* Helper method called by p5.Element.style() */
+ _rotate(...args) {
+ // save out initial non-rotate transform styling
+ let transform = '';
+ if (this.elt.style.transform) {
+ transform = this.elt.style.transform.replace(/rotate3d\(.*\)/g, '');
+ transform = transform.replace(/rotate[X-Z]?\(.*\)/g, '');
+ }
+
+ if (args.length === 1) {
+ this.elt.style.transform = 'rotate(' + args[0] + 'deg)';
+ } else if (args.length === 2) {
+ this.elt.style.transform =
+ 'rotate(' + args[0] + 'deg, ' + args[1] + 'deg)';
+ } else if (args.length === 3) {
+ this.elt.style.transform = 'rotateX(' + args[0] + 'deg)';
+ this.elt.style.transform += 'rotateY(' + args[1] + 'deg)';
+ this.elt.style.transform += 'rotateZ(' + args[2] + 'deg)';
+ }
+ // add remaining transform back on
+ this.elt.style.transform += transform;
+ return this;
+ }
+
+ /**
+ * Adds an
+ * attribute
+ * to the element.
+ *
+ * This method is useful for advanced tasks. Most commonly-used attributes,
+ * such as `id`, can be set with their dedicated methods. For example,
+ * `nextButton.id('next')` sets an element's `id` attribute. Calling
+ * `nextButton.attribute('id', 'next')` has the same effect.
+ *
+ * The first parameter, `attr`, is the attribute's name as a string. Calling
+ * `myElement.attribute('align')` returns the attribute's current value as a
+ * string or `null` if it hasn't been set.
+ *
+ * The second parameter, `value`, is optional. It's a string used to set the
+ * attribute's value. For example, calling
+ * `myElement.attribute('align', 'center')` sets the element's horizontal
+ * alignment to `center`.
+ *
+ * @method attribute
+ * @return {String} value of the attribute.
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * // Create a container div element and place it at the top-left corner.
+ * let container = createDiv();
+ * container.position(0, 0);
+ *
+ * // Create a paragraph element and place it within the container.
+ * // Set its horizontal alignment to "left".
+ * let p1 = createP('hi');
+ * p1.parent(container);
+ * p1.attribute('align', 'left');
+ *
+ * // Create a paragraph element and place it within the container.
+ * // Set its horizontal alignment to "center".
+ * let p2 = createP('hi');
+ * p2.parent(container);
+ * p2.attribute('align', 'center');
+ *
+ * // Create a paragraph element and place it within the container.
+ * // Set its horizontal alignment to "right".
+ * let p3 = createP('hi');
+ * p3.parent(container);
+ * p3.attribute('align', 'right');
+ *
+ * describe('A gray square with the text "hi" written on three separate lines, each placed further to the right.');
+ * }
+ *
+ *
+ */
+ /**
+ * @method attribute
+ * @param {String} attr attribute to set.
+ * @param {String} value value to assign to the attribute.
+ * @chainable
+ */
+ attribute(attr, value) {
+ //handling for checkboxes and radios to ensure options get
+ //attributes not divs
+ if (
+ this.elt.firstChild != null &&
+ (this.elt.firstChild.type === 'checkbox' ||
+ this.elt.firstChild.type === 'radio')
+ ) {
+ if (typeof value === 'undefined') {
+ return this.elt.firstChild.getAttribute(attr);
+ } else {
+ for (let i = 0; i < this.elt.childNodes.length; i++) {
+ this.elt.childNodes[i].setAttribute(attr, value);
+ }
+ }
+ } else if (typeof value === 'undefined') {
+ return this.elt.getAttribute(attr);
+ } else {
+ this.elt.setAttribute(attr, value);
+ return this;
+ }
+ }
+
+ /**
+ * Removes an attribute from the element.
+ *
+ * The parameter `attr` is the attribute's name as a string. For example,
+ * calling `myElement.removeAttribute('align')` removes its `align`
+ * attribute if it's been set.
+ *
+ * @method removeAttribute
+ * @param {String} attr attribute to remove.
+ * @chainable
+ *
+ * @example
+ *
+ *
+ * let p;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a paragraph element and place it in the center of the canvas.
+ * // Set its "align" attribute to "center".
+ * p = createP('hi');
+ * p.position(0, 20);
+ * p.attribute('align', 'center');
+ *
+ * describe('The text "hi" written in black at the center of a gray square. The text moves to the left edge when double-clicked.');
+ * }
+ *
+ * // Remove the 'align' attribute when the user double-clicks the paragraph.
+ * function doubleClicked() {
+ * p.removeAttribute('align');
+ * }
+ *
+ *
+ */
+ removeAttribute(attr) {
+ if (
+ this.elt.firstChild != null &&
+ (this.elt.firstChild.type === 'checkbox' ||
+ this.elt.firstChild.type === 'radio')
+ ) {
+ for (let i = 0; i < this.elt.childNodes.length; i++) {
+ this.elt.childNodes[i].removeAttribute(attr);
+ }
+ }
+ this.elt.removeAttribute(attr);
+ return this;
+ }
+
+ /**
+ * Returns or sets the element's value.
+ *
+ * Calling `myElement.value()` returns the element's current value.
+ *
+ * The parameter, `value`, is an optional number or string. If provided,
+ * as in `myElement.value(123)`, it's used to set the element's value.
+ *
+ * @method value
+ * @return {String|Number} value of the element.
+ *
+ * @example
+ *
+ *
+ * let input;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * // Create a text input and place it beneath the canvas.
+ * // Set its default value to "hello".
+ * input = createInput('hello');
+ * input.position(0, 100);
+ *
+ * describe('The text from an input box is displayed on a gray square.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Use the input's value to display a message.
+ * let msg = input.value();
+ * text(msg, 0, 55);
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let input;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * // Create a text input and place it beneath the canvas.
+ * // Set its default value to "hello".
+ * input = createInput('hello');
+ * input.position(0, 100);
+ *
+ * describe('The text from an input box is displayed on a gray square. The text resets to "hello" when the user double-clicks the square.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Use the input's value to display a message.
+ * let msg = input.value();
+ * text(msg, 0, 55);
+ * }
+ *
+ * // Reset the input's value.
+ * function doubleClicked() {
+ * input.value('hello');
+ * }
+ *
+ *
+ */
+ /**
+ * @method value
+ * @param {String|Number} value
+ * @chainable
+ */
+ value(...args) {
+ if (args.length > 0) {
+ this.elt.value = args[0];
+ return this;
+ } else {
+ if (this.elt.type === 'range') {
+ return parseFloat(this.elt.value);
+ } else return this.elt.value;
+ }
+ }
+
+ /**
+ * Calls a function when the mouse is pressed over the element.
+ *
+ * Calling `myElement.mousePressed(false)` disables the function.
+ *
+ * Note: Some mobile browsers may also trigger this event when the element
+ * receives a quick tap.
+ *
+ * @param {Function|Boolean} fxn function to call when the mouse is
+ * pressed over the element.
+ * `false` disables the function.
+ * @chainable
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Call randomColor() when the canvas
+ * // is pressed.
+ * cnv.mousePressed(randomColor);
+ *
+ * describe('A gray square changes color when the mouse is pressed.');
+ * }
+ *
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
+ * }
+ *
+ *
+ */
+ mousePressed(fxn) {
+ // Prepend the mouse property setters to the event-listener.
+ // This is required so that mouseButton is set correctly prior to calling the callback (fxn).
+ // For details, see https://github.com/processing/p5.js/issues/3087.
+ const eventPrependedFxn = function (event) {
+ this._pInst.mouseIsPressed = true;
+ this._pInst._setMouseButton(event);
+ // Pass along the return-value of the callback:
+ return fxn.call(this, event);
+ };
+ // Pass along the event-prepended form of the callback.
+ Element._adjustListener('mousedown', eventPrependedFxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when the mouse is pressed twice over the element.
+ *
+ * Calling `myElement.doubleClicked(false)` disables the function.
+ *
+ * @param {Function|Boolean} fxn function to call when the mouse is
+ * double clicked over the element.
+ * `false` disables the function.
+ * @chainable
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Call randomColor() when the
+ * // canvas is double-clicked.
+ * cnv.doubleClicked(randomColor);
+ *
+ * describe('A gray square changes color when the user double-clicks the canvas.');
+ * }
+ *
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
+ * }
+ *
+ *
+ */
+ doubleClicked(fxn) {
+ Element._adjustListener('dblclick', fxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when the mouse wheel scrolls over the element.
+ *
+ * The callback function, `fxn`, is passed an `event` object. `event` has
+ * two numeric properties, `deltaY` and `deltaX`. `event.deltaY` is
+ * negative if the mouse wheel rotates away from the user. It's positive if
+ * the mouse wheel rotates toward the user. `event.deltaX` is positive if
+ * the mouse wheel moves to the right. It's negative if the mouse wheel moves
+ * to the left.
+ *
+ * Calling `myElement.mouseWheel(false)` disables the function.
+ *
+ * @param {Function|Boolean} fxn function to call when the mouse wheel is
+ * scrolled over the element.
+ * `false` disables the function.
+ * @chainable
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Call randomColor() when the
+ * // mouse wheel moves.
+ * cnv.mouseWheel(randomColor);
+ *
+ * describe('A gray square changes color when the user scrolls the mouse wheel over the canvas.');
+ * }
+ *
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
+ * }
+ *
+ *
+ *
+ *
+ *
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Call changeBackground() when the
+ * // mouse wheel moves.
+ * cnv.mouseWheel(changeBackground);
+ *
+ * describe('A gray square. When the mouse wheel scrolls over the square, it changes color and displays shapes.');
+ * }
+ *
+ * function changeBackground(event) {
+ * // Change the background color
+ * // based on deltaY.
+ * if (event.deltaY > 0) {
+ * background('deeppink');
+ * } else if (event.deltaY < 0) {
+ * background('cornflowerblue');
+ * } else {
+ * background(200);
+ * }
+ *
+ * // Draw a shape based on deltaX.
+ * if (event.deltaX > 0) {
+ * circle(50, 50, 20);
+ * } else if (event.deltaX < 0) {
+ * square(40, 40, 20);
+ * }
+ * }
+ *
+ *
+ */
+ mouseWheel(fxn) {
+ Element._adjustListener('wheel', fxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when the mouse is released over the element.
+ *
+ * Calling `myElement.mouseReleased(false)` disables the function.
+ *
+ * Note: Some mobile browsers may also trigger this event when the element
+ * receives a quick tap.
+ *
+ * @param {Function|Boolean} fxn function to call when the mouse is
+ * pressed over the element.
+ * `false` disables the function.
+ * @chainable
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Call randomColor() when a
+ * // mouse press ends.
+ * cnv.mouseReleased(randomColor);
+ *
+ * describe('A gray square changes color when the user releases a mouse press.');
+ * }
+ *
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
+ * }
+ *
+ *
+ */
+ mouseReleased(fxn) {
+ Element._adjustListener('mouseup', fxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when the mouse is pressed and released over the element.
+ *
+ * Calling `myElement.mouseReleased(false)` disables the function.
+ *
+ * Note: Some mobile browsers may also trigger this event when the element
+ * receives a quick tap.
+ *
+ * @param {Function|Boolean} fxn function to call when the mouse is
+ * pressed and released over the element.
+ * `false` disables the function.
+ * @chainable
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Call randomColor() when a
+ * // mouse press ends.
+ * cnv.mouseClicked(randomColor);
+ *
+ * describe('A gray square changes color when the user releases a mouse press.');
+ * }
*
- * The second parameter, `value`, is optional. It's a string used to set the
- * attribute's value. For example, calling
- * `myElement.attribute('align', 'center')` sets the element's horizontal
- * alignment to `center`.
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
+ * }
+ *
+ *
+ */
+ mouseClicked(fxn) {
+ Element._adjustListener('click', fxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when the mouse moves over the element.
*
- * @method attribute
- * @return {String} value of the attribute.
+ * Calling `myElement.mouseMoved(false)` disables the function.
+ *
+ * @param {Function|Boolean} fxn function to call when the mouse
+ * moves over the element.
+ * `false` disables the function.
+ * @chainable
*
* @example
*
*
* function setup() {
- * createCanvas(100, 100);
- *
- * // Create a container div element and place it at the top-left corner.
- * let container = createDiv();
- * container.position(0, 0);
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
- * // Create a paragraph element and place it within the container.
- * // Set its horizontal alignment to "left".
- * let p1 = createP('hi');
- * p1.parent(container);
- * p1.attribute('align', 'left');
+ * background(200);
*
- * // Create a paragraph element and place it within the container.
- * // Set its horizontal alignment to "center".
- * let p2 = createP('hi');
- * p2.parent(container);
- * p2.attribute('align', 'center');
+ * // Call randomColor() when the
+ * // mouse moves.
+ * cnv.mouseMoved(randomColor);
*
- * // Create a paragraph element and place it within the container.
- * // Set its horizontal alignment to "right".
- * let p3 = createP('hi');
- * p3.parent(container);
- * p3.attribute('align', 'right');
+ * describe('A gray square changes color when the mouse moves over the canvas.');
+ * }
*
- * describe('A gray square with the text "hi" written on three separate lines, each placed further to the right.');
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
* }
*
*
*/
- /**
- * @method attribute
- * @param {String} attr attribute to set.
- * @param {String} value value to assign to the attribute.
- * @chainable
- */
- p5.Element.prototype.attribute = function (attr, value) {
- //handling for checkboxes and radios to ensure options get
- //attributes not divs
- if (
- this.elt.firstChild != null &&
- (this.elt.firstChild.type === 'checkbox' ||
- this.elt.firstChild.type === 'radio')
- ) {
- if (typeof value === 'undefined') {
- return this.elt.firstChild.getAttribute(attr);
- } else {
- for (let i = 0; i < this.elt.childNodes.length; i++) {
- this.elt.childNodes[i].setAttribute(attr, value);
- }
- }
- } else if (typeof value === 'undefined') {
- return this.elt.getAttribute(attr);
- } else {
- this.elt.setAttribute(attr, value);
- return this;
- }
- };
+ mouseMoved(fxn) {
+ Element._adjustListener('mousemove', fxn, this);
+ return this;
+ }
/**
- * Removes an attribute from the element.
+ * Calls a function when the mouse moves onto the element.
*
- * The parameter `attr` is the attribute's name as a string. For example,
- * calling `myElement.removeAttribute('align')` removes its `align`
- * attribute if it's been set.
+ * Calling `myElement.mouseOver(false)` disables the function.
*
- * @method removeAttribute
- * @param {String} attr attribute to remove.
+ * @param {Function|Boolean} fxn function to call when the mouse
+ * moves onto the element.
+ * `false` disables the function.
* @chainable
*
* @example
*
*
- * let p;
- *
* function setup() {
- * createCanvas(100, 100);
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
* background(200);
*
- * // Create a paragraph element and place it in the center of the canvas.
- * // Set its "align" attribute to "center".
- * p = createP('hi');
- * p.position(0, 20);
- * p.attribute('align', 'center');
+ * // Call randomColor() when the
+ * // mouse moves onto the canvas.
+ * cnv.mouseOver(randomColor);
*
- * describe('The text "hi" written in black at the center of a gray square. The text moves to the left edge when double-clicked.');
+ * describe('A gray square changes color when the mouse moves onto the canvas.');
* }
*
- * // Remove the 'align' attribute when the user double-clicks the paragraph.
- * function doubleClicked() {
- * p.removeAttribute('align');
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
* }
*
*
*/
- p5.Element.prototype.removeAttribute = function (attr) {
- if (
- this.elt.firstChild != null &&
- (this.elt.firstChild.type === 'checkbox' ||
- this.elt.firstChild.type === 'radio')
- ) {
- for (let i = 0; i < this.elt.childNodes.length; i++) {
- this.elt.childNodes[i].removeAttribute(attr);
- }
- }
- this.elt.removeAttribute(attr);
+ mouseOver(fxn) {
+ Element._adjustListener('mouseover', fxn, this);
return this;
- };
+ }
/**
- * Returns or sets the element's value.
+ * Calls a function when the mouse moves off the element.
*
- * Calling `myElement.value()` returns the element's current value.
- *
- * The parameter, `value`, is an optional number or string. If provided,
- * as in `myElement.value(123)`, it's used to set the element's value.
+ * Calling `myElement.mouseOut(false)` disables the function.
*
- * @method value
- * @return {String|Number} value of the element.
+ * @param {Function|Boolean} fxn function to call when the mouse
+ * moves off the element.
+ * `false` disables the function.
+ * @chainable
*
* @example
*
*
- * let input;
- *
* function setup() {
- * createCanvas(100, 100);
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
- * // Create a text input and place it beneath the canvas.
- * // Set its default value to "hello".
- * input = createInput('hello');
- * input.position(0, 100);
+ * background(200);
*
- * describe('The text from an input box is displayed on a gray square.');
- * }
+ * // Call randomColor() when the
+ * // mouse moves off the canvas.
+ * cnv.mouseOut(randomColor);
*
- * function draw() {
- * background(200);
+ * describe('A gray square changes color when the mouse moves off the canvas.');
+ * }
*
- * // Use the input's value to display a message.
- * let msg = input.value();
- * text(msg, 0, 55);
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
* }
*
*
+ */
+ mouseOut(fxn) {
+ Element._adjustListener('mouseout', fxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when the element is touched.
*
- *
- *
- * let input;
+ * Calling `myElement.touchStarted(false)` disables the function.
*
- * function setup() {
- * createCanvas(100, 100);
+ * Note: Touch functions only work on mobile devices.
*
- * // Create a text input and place it beneath the canvas.
- * // Set its default value to "hello".
- * input = createInput('hello');
- * input.position(0, 100);
+ * @param {Function|Boolean} fxn function to call when the touch
+ * starts.
+ * `false` disables the function.
+ * @chainable
*
- * describe('The text from an input box is displayed on a gray square. The text resets to "hello" when the user double-clicks the square.');
- * }
+ * @example
+ *
+ *
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
- * function draw() {
* background(200);
*
- * // Use the input's value to display a message.
- * let msg = input.value();
- * text(msg, 0, 55);
+ * // Call randomColor() when the
+ * // user touches the canvas.
+ * cnv.touchStarted(randomColor);
+ *
+ * describe('A gray square changes color when the user touches the canvas.');
* }
*
- * // Reset the input's value.
- * function doubleClicked() {
- * input.value('hello');
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
* }
*
*
*/
- /**
- * @method value
- * @param {String|Number} value
- * @chainable
- */
- p5.Element.prototype.value = function (...args) {
- if (args.length > 0) {
- this.elt.value = args[0];
- return this;
- } else {
- if (this.elt.type === 'range') {
- return parseFloat(this.elt.value);
- } else return this.elt.value;
- }
- };
+ touchStarted(fxn) {
+ Element._adjustListener('touchstart', fxn, this);
+ return this;
+ }
/**
- * Shows the current element.
+ * Calls a function when the user touches the element and moves.
*
- * @method show
- * @chainable
+ * Calling `myElement.touchMoved(false)` disables the function.
*
+ * Note: Touch functions only work on mobile devices.
+ *
+ * @param {Function|Boolean} fxn function to call when the touch
+ * moves over the element.
+ * `false` disables the function.
+ * @chainable
* @example
*
*
- * let p;
- *
* function setup() {
- * createCanvas(100, 100);
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
* background(200);
*
- * // Create a paragraph element and hide it.
- * p = createP('p5*js');
- * p.position(10, 10);
- * p.hide();
+ * // Call randomColor() when the
+ * // user touches the canvas
+ * // and moves.
+ * cnv.touchMoved(randomColor);
*
- * describe('A gray square. The text "p5*js" appears when the user double-clicks the square.');
+ * describe('A gray square changes color when the user touches the canvas and moves.');
* }
*
- * // Show the paragraph when the user double-clicks.
- * function doubleClicked() {
- * p.show();
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
* }
*
*
*/
- p5.Element.prototype.show = function () {
- this.elt.style.display = 'block';
+ touchMoved(fxn) {
+ Element._adjustListener('touchmove', fxn, this);
return this;
- };
+ }
/**
- * Hides the current element.
+ * Calls a function when the user stops touching the element.
*
- * @method hide
- * @chainable
+ * Calling `myElement.touchMoved(false)` disables the function.
*
- * @example
- * let p;
+ * Note: Touch functions only work on mobile devices.
*
+ * @param {Function|Boolean} fxn function to call when the touch
+ * ends.
+ * `false` disables the function.
+ * @chainable
+ * @example
+ *
+ *
* function setup() {
- * createCanvas(100, 100);
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
* background(200);
*
- * // Create a paragraph element.
- * p = createP('p5*js');
- * p.position(10, 10);
+ * // Call randomColor() when the
+ * // user touches the canvas,
+ * // then lifts their finger.
+ * cnv.touchEnded(randomColor);
*
- * describe('The text "p5*js" at the center of a gray square. The text disappears when the user double-clicks the square.');
+ * describe('A gray square changes color when the user touches the canvas, then lifts their finger.');
* }
*
- * // Hide the paragraph when the user double-clicks.
- * function doubleClicked() {
- * p.hide();
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
* }
*
*
*/
- p5.Element.prototype.hide = function () {
- this.elt.style.display = 'none';
+ touchEnded(fxn) {
+ Element._adjustListener('touchend', fxn, this);
return this;
- };
+ }
/**
- * Sets the element's width and height.
+ * Calls a function when a file is dragged over the element.
*
- * Calling `myElement.size()` without an argument returns the element's size
- * as an object with the properties `width` and `height`. For example,
- * `{ width: 20, height: 10 }`.
+ * Calling `myElement.dragOver(false)` disables the function.
*
- * The first parameter, `width`, is optional. It's a number used to set the
- * element's width. Calling `myElement.size(10)`
+ * @param {Function|Boolean} fxn function to call when the file is
+ * dragged over the element.
+ * `false` disables the function.
+ * @chainable
*
- * The second parameter, 'height`, is also optional. It's a
- * number used to set the element's height. For example, calling
- * `myElement.size(20, 10)` sets the element's width to 20 pixels and height
- * to 10 pixels.
+ * @example
+ *
+ *
+ * // Drag a file over the canvas to test.
*
- * The constant `AUTO` can be used to adjust one dimension at a time while
- * maintaining the aspect ratio, which is `width / height`. For example,
- * consider an element that's 200 pixels wide and 100 pixels tall. Calling
- * `myElement.size(20, AUTO)` sets the width to 20 pixels and height to 10
- * pixels.
+ * function setup() {
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
- * Note: In the case of elements that need to load data, such as images, wait
- * to call `myElement.size()` until after the data loads.
+ * background(200);
+ *
+ * // Call helloFile() when a
+ * // file is dragged over
+ * // the canvas.
+ * cnv.dragOver(helloFile);
+ *
+ * describe('A gray square. The text "hello, file" appears when a file is dragged over the square.');
+ * }
+ *
+ * function helloFile() {
+ * text('hello, file', 50, 50);
+ * }
+ *
+ *
+ */
+ dragOver(fxn) {
+ Element._adjustListener('dragover', fxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when a file is dragged off the element.
*
- * @method size
- * @return {Object} width and height of the element in an object.
+ * Calling `myElement.dragLeave(false)` disables the function.
*
+ * @param {Function|Boolean} fxn function to call when the file is
+ * dragged off the element.
+ * `false` disables the function.
+ * @chainable
* @example
*
*
+ * // Drag a file over, then off
+ * // the canvas to test.
+ *
* function setup() {
- * createCanvas(100, 100);
+ * // Create a canvas element and
+ * // assign it to cnv.
+ * let cnv = createCanvas(100, 100);
*
* background(200);
*
- * // Create a pink div element and place it at the top-left corner.
- * let div = createDiv();
- * div.position(10, 10);
- * div.style('background-color', 'deeppink');
+ * // Call byeFile() when a
+ * // file is dragged over,
+ * // then off the canvas.
+ * cnv.dragLeave(byeFile);
*
- * // Set the div's width to 80 pixels and height to 20 pixels.
- * div.size(80, 20);
+ * describe('A gray square. The text "bye, file" appears when a file is dragged over, then off the square.');
+ * }
*
- * describe('A gray square with a pink rectangle near its top.');
+ * function byeFile() {
+ * text('bye, file', 50, 50);
* }
*
*
+ */
+ dragLeave(fxn) {
+ Element._adjustListener('dragleave', fxn, this);
+ return this;
+ }
+
+ /**
+ * Calls a function when the element changes.
+ *
+ * Calling `myElement.changed(false)` disables the function.
*
+ * @method changed
+ * @param {Function|Boolean} fxn function to call when the element changes.
+ * `false` disables the function.
+ * @chainable
+ *
+ * @example
*
*
+ * let dropdown;
+ *
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Create a pink div element and place it at the top-left corner.
- * let div = createDiv();
- * div.position(10, 10);
- * div.style('background-color', 'deeppink');
- *
- * // Set the div's width to 80 pixels and height to 40 pixels.
- * div.size(80, 40);
+ * // Create a dropdown menu and add a few color options.
+ * dropdown = createSelect();
+ * dropdown.position(0, 0);
+ * dropdown.option('red');
+ * dropdown.option('green');
+ * dropdown.option('blue');
*
- * // Get the div's size as an object.
- * let s = div.size();
+ * // Call paintBackground() when the color option changes.
+ * dropdown.changed(paintBackground);
*
- * // Display the div's dimensions.
- * div.html(`${s.width} x ${s.height}`);
+ * describe('A gray square with a dropdown menu at the top. The square changes color when an option is selected.');
+ * }
*
- * describe('A gray square with a pink rectangle near its top. The text "80 x 40" is written within the rectangle.');
+ * // Paint the background with the selected color.
+ * function paintBackground() {
+ * let c = dropdown.value();
+ * background(c);
* }
*
*
*
*
*
- * let img1;
- * let img2;
+ * let checkbox;
*
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Load an image of an astronaut on the moon
- * // and place it at the top-left of the canvas.
- * img1 = createImg(
- * 'assets/moonwalk.jpg',
- * 'An astronaut walking on the moon',
- * ''
- * );
- * img1.position(0, 0);
+ * // Create a checkbox and place it beneath the canvas.
+ * checkbox = createCheckbox(' circle');
+ * checkbox.position(0, 100);
*
- * // Load an image of an astronaut on the moon
- * // and place it at the top-left of the canvas.
- * // Resize the image once it's loaded.
- * img2 = createImg(
- * 'assets/moonwalk.jpg',
- * 'An astronaut walking on the moon',
- * '',
- * resizeImage
- * );
- * img2.position(0, 0);
+ * // Call repaint() when the checkbox changes.
+ * checkbox.changed(repaint);
*
- * describe('A gray square two copies of a space image at the top-left. The copy in front is smaller.');
+ * describe('A gray square with a checkbox underneath it that says "circle". A white circle appears when the box is checked and disappears otherwise.');
* }
*
- * // Resize img2 and keep its aspect ratio.
- * function resizeImage() {
- * img2.size(50, AUTO);
+ * // Paint the background gray and determine whether to draw a circle.
+ * function repaint() {
+ * background(200);
+ * if (checkbox.checked() === true) {
+ * circle(50, 50, 30);
+ * }
* }
*
*
*/
- /**
- * @method size
- * @param {(Number|AUTO)} [w] width of the element, either AUTO, or a number.
- * @param {(Number|AUTO)} [h] height of the element, either AUTO, or a number.
- * @chainable
- */
- p5.Element.prototype.size = function (w, h) {
- if (arguments.length === 0) {
- return { width: this.elt.offsetWidth, height: this.elt.offsetHeight };
- } else {
- let aW = w;
- let aH = h;
- const AUTO = fn.AUTO;
- if (aW !== AUTO || aH !== AUTO) {
- if (aW === AUTO) {
- aW = h * this.width / this.height;
- } else if (aH === AUTO) {
- aH = w * this.height / this.width;
- }
- // set diff for cnv vs normal div
- if (this.elt instanceof HTMLCanvasElement) {
- const j = {};
- const k = this.elt.getContext('2d');
- let prop;
- for (prop in k) {
- j[prop] = k[prop];
- }
- this.elt.setAttribute('width', aW * this._pInst._pixelDensity);
- this.elt.setAttribute('height', aH * this._pInst._pixelDensity);
- this.elt.style.width = aW + 'px';
- this.elt.style.height = aH + 'px';
- this._pInst.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);
- for (prop in j) {
- this.elt.getContext('2d')[prop] = j[prop];
- }
- } else {
- this.elt.style.width = aW + 'px';
- this.elt.style.height = aH + 'px';
- this.elt.width = aW;
- this.elt.height = aH;
- }
- this.width = aW;
- this.height = aH;
- if (this._pInst && this._pInst._curElement) {
- // main canvas associated with p5 instance
- if (this._pInst._curElement.elt === this.elt) {
- this._pInst.width = aW;
- this._pInst.height = aH;
- }
- }
- }
- return this;
- }
- };
+ changed(fxn) {
+ Element._adjustListener('change', fxn, this);
+ return this;
+ }
/**
- * Removes the element, stops all audio/video streams, and removes all
- * callback functions.
+ * Calls a function when the element receives input.
*
- * @method remove
+ * `myElement.input()` is often used to with text inputs and sliders. Calling
+ * `myElement.input(false)` disables the function.
+ *
+ * @method input
+ * @param {Function|Boolean} fxn function to call when input is detected within
+ * the element.
+ * `false` disables the function.
+ * @chainable
*
* @example
*
*
- * let p;
+ * let slider;
*
* function setup() {
* createCanvas(100, 100);
*
* background(200);
*
- * // Create a paragraph element.
- * p = createP('p5*js');
- * p.position(10, 10);
+ * // Create a slider and place it beneath the canvas.
+ * slider = createSlider(0, 255, 200);
+ * slider.position(0, 100);
*
- * describe('The text "p5*js" written at the center of a gray square. ');
+ * // Call repaint() when the slider changes.
+ * slider.input(repaint);
+ *
+ * describe('A gray square with a range slider underneath it. The background changes shades of gray when the slider is moved.');
* }
*
- * // Remove the paragraph when the user double-clicks.
- * function doubleClicked() {
- * p.remove();
+ * // Paint the background using slider's value.
+ * function repaint() {
+ * let g = slider.value();
+ * background(g);
+ * }
+ *
+ *
+ *
+ *
+ *
+ * let input;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create an input and place it beneath the canvas.
+ * input = createInput('');
+ * input.position(0, 100);
+ *
+ * // Call repaint() when input is detected.
+ * input.input(repaint);
+ *
+ * describe('A gray square with a text input bar beneath it. Any text written in the input appears in the middle of the square.');
+ * }
+ *
+ * // Paint the background gray and display the input's value.
+ * function repaint() {
+ * background(200);
+ * let msg = input.value();
+ * text(msg, 5, 50);
* }
*
*
*/
- p5.Element.prototype.remove = function () {
- // stop all audios/videos and detach all devices like microphone/camera etc
- // used as input/output for audios/videos.
- if (this instanceof p5.MediaElement) {
- this.stop();
- const sources = this.elt.srcObject;
- if (sources !== null) {
- const tracks = sources.getTracks();
- tracks.forEach(track => {
- track.stop();
- });
- }
- }
-
- // delete the reference in this._pInst._elements
- const index = this._pInst._elements.indexOf(this);
- if (index !== -1) {
- this._pInst._elements.splice(index, 1);
- }
-
- // deregister events
- for (let ev in this._events) {
- this.elt.removeEventListener(ev, this._events[ev]);
- }
- if (this.elt && this.elt.parentNode) {
- this.elt.parentNode.removeChild(this.elt);
- }
- };
+ input(fxn) {
+ Element._adjustListener('input', fxn, this);
+ return this;
+ }
/**
* Calls a function when the user drops a file on the element.
@@ -1424,7 +2395,7 @@ function element(p5, fn){
*
*
*/
- p5.Element.prototype.drop = function (callback, fxn) {
+ drop(callback, fxn) {
// Is the file stuff supported?
if (window.File && window.FileReader && window.FileList && window.Blob) {
if (!this._dragDisabled) {
@@ -1444,7 +2415,7 @@ function element(p5, fn){
}
// Deal with the files
- p5.Element._attachListener(
+ Element._attachListener(
'drop',
function (evt) {
evt.preventDefault();
@@ -1457,7 +2428,7 @@ function element(p5, fn){
// Load each one and trigger the callback
for (const f of files) {
- p5.File._load(f, callback);
+ File._load(f, callback);
}
},
this
@@ -1467,7 +2438,7 @@ function element(p5, fn){
}
return this;
- };
+ }
/**
* Makes the element draggable.
@@ -1537,7 +2508,7 @@ function element(p5, fn){
*
*
*/
- p5.Element.prototype.draggable = function (elmMove) {
+ draggable(elmMove) {
let isTouch = 'ontouchstart' in window;
let x = 0,
@@ -1603,24 +2574,110 @@ function element(p5, fn){
}
return this;
- };
-
- /*** SCHEDULE EVENTS ***/
-
- // Cue inspired by JavaScript setTimeout, and the
- // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org
- // eslint-disable-next-line no-unused-vars
- class Cue {
- constructor(callback, time, id, val) {
- this.callback = callback;
- this.time = time;
- this.id = id;
- this.val = val;
+ }
+
+ /**
+ *
+ * @private
+ * @static
+ * @param {String} ev
+ * @param {Boolean|Function} fxn
+ * @param {Element} ctx
+ * @chainable
+ * @alt
+ * General handler for event attaching and detaching
+ */
+ static _adjustListener(ev, fxn, ctx) {
+ if (fxn === false) {
+ Element._detachListener(ev, ctx);
+ } else {
+ Element._attachListener(ev, fxn, ctx);
+ }
+ return this;
+ }
+
+ /**
+ *
+ * @private
+ * @static
+ * @param {String} ev
+ * @param {Function} fxn
+ * @param {Element} ctx
+ */
+ static _attachListener(ev, fxn, ctx) {
+ // detach the old listener if there was one
+ if (ctx._events[ev]) {
+ Element._detachListener(ev, ctx);
}
+ const f = fxn.bind(ctx);
+ ctx.elt.addEventListener(ev, f, false);
+ ctx._events[ev] = f;
+ }
+
+ /**
+ *
+ * @private
+ * @static
+ * @param {String} ev
+ * @param {Element} ctx
+ */
+ static _detachListener(ev, ctx) {
+ const f = ctx._events[ev];
+ ctx.elt.removeEventListener(ev, f, false);
+ ctx._events[ev] = null;
}
+};
+
+function element(p5, fn){
+ /**
+ * A class to describe an
+ * HTML element.
+ *
+ * Sketches can use many elements. Common elements include the drawing canvas,
+ * buttons, sliders, webcam feeds, and so on.
+ *
+ * All elements share the methods of the `p5.Element` class. They're created
+ * with functions such as createCanvas() and
+ * createButton().
+ *
+ * @class p5.Element
+ * @param {HTMLElement} elt wrapped DOM element.
+ * @param {p5} [pInst] pointer to p5 instance.
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Create a button element and
+ * // place it beneath the canvas.
+ * let btn = createButton('change');
+ * btn.position(0, 100);
+ *
+ * // Call randomColor() when
+ * // the button is pressed.
+ * btn.mousePressed(randomColor);
+ *
+ * describe('A gray square with a button that says "change" beneath it. The square changes color when the user presses the button.');
+ * }
+ *
+ * // Paint the background either
+ * // red, yellow, blue, or green.
+ * function randomColor() {
+ * let c = random(['red', 'yellow', 'blue', 'green']);
+ * background(c);
+ * }
+ *
+ *
+ */
+ p5.Element = Element;
}
export default element;
+export { Element };
if(typeof p5 !== 'undefined'){
element(p5, p5.prototype);
diff --git a/src/dom/p5.File.js b/src/dom/p5.File.js
index 001a575417..7852d4f435 100644
--- a/src/dom/p5.File.js
+++ b/src/dom/p5.File.js
@@ -1,3 +1,63 @@
+/**
+ * @module DOM
+ * @submodule DOM
+ * @for p5.Element
+ */
+
+import { XML } from '../io/p5.XML';
+
+class File {
+ constructor(file, pInst) {
+ this.file = file;
+
+ this._pInst = pInst;
+
+ // Splitting out the file type into two components
+ // This makes determining if image or text etc simpler
+ const typeList = file.type.split('/');
+ this.type = typeList[0];
+ this.subtype = typeList[1];
+ this.name = file.name;
+ this.size = file.size;
+ this.data = undefined;
+ }
+
+
+ static _createLoader(theFile, callback) {
+ const reader = new FileReader();
+ reader.onload = function (e) {
+ const p5file = new File(theFile);
+ if (p5file.file.type === 'application/json') {
+ // Parse JSON and store the result in data
+ p5file.data = JSON.parse(e.target.result);
+ } else if (p5file.file.type === 'text/xml') {
+ // Parse XML, wrap it in p5.XML and store the result in data
+ const parser = new DOMParser();
+ const xml = parser.parseFromString(e.target.result, 'text/xml');
+ p5file.data = new XML(xml.documentElement);
+ } else {
+ p5file.data = e.target.result;
+ }
+ callback(p5file);
+ };
+ return reader;
+ }
+
+ static _load(f, callback) {
+ // Text or data?
+ // This should likely be improved
+ if (/^text\//.test(f.type) || f.type === 'application/json') {
+ File._createLoader(f, callback).readAsText(f);
+ } else if (!/^(video|audio)\//.test(f.type)) {
+ File._createLoader(f, callback).readAsDataURL(f);
+ } else {
+ const file = new File(f);
+ file.data = URL.createObjectURL(f);
+ callback(file);
+ }
+ }
+}
+
function file(p5, fn){
/**
* A class to describe a file.
@@ -87,57 +147,7 @@ function file(p5, fn){
*
*
*/
- p5.File = class File {
- constructor(file, pInst) {
- this.file = file;
-
- this._pInst = pInst;
-
- // Splitting out the file type into two components
- // This makes determining if image or text etc simpler
- const typeList = file.type.split('/');
- this.type = typeList[0];
- this.subtype = typeList[1];
- this.name = file.name;
- this.size = file.size;
- this.data = undefined;
- }
-
-
- static _createLoader(theFile, callback) {
- const reader = new FileReader();
- reader.onload = function (e) {
- const p5file = new p5.File(theFile);
- if (p5file.file.type === 'application/json') {
- // Parse JSON and store the result in data
- p5file.data = JSON.parse(e.target.result);
- } else if (p5file.file.type === 'text/xml') {
- // Parse XML, wrap it in p5.XML and store the result in data
- const parser = new DOMParser();
- const xml = parser.parseFromString(e.target.result, 'text/xml');
- p5file.data = new p5.XML(xml.documentElement);
- } else {
- p5file.data = e.target.result;
- }
- callback(p5file);
- };
- return reader;
- }
-
- static _load(f, callback) {
- // Text or data?
- // This should likely be improved
- if (/^text\//.test(f.type) || f.type === 'application/json') {
- p5.File._createLoader(f, callback).readAsText(f);
- } else if (!/^(video|audio)\//.test(f.type)) {
- p5.File._createLoader(f, callback).readAsDataURL(f);
- } else {
- const file = new p5.File(f);
- file.data = URL.createObjectURL(f);
- callback(file);
- }
- }
- };
+ p5.File = File;
/**
* Underlying
@@ -371,6 +381,7 @@ function file(p5, fn){
}
export default file;
+export { File };
if(typeof p5 !== 'undefined'){
file(p5, p5.prototype);
diff --git a/src/dom/media_element.js b/src/dom/p5.MediaElement.js
similarity index 99%
rename from src/dom/media_element.js
rename to src/dom/p5.MediaElement.js
index 94e9654b0f..3d85047d39 100644
--- a/src/dom/media_element.js
+++ b/src/dom/p5.MediaElement.js
@@ -1,4 +1,10 @@
-import { Element } from '../core/p5.Element';
+/**
+ * @module DOM
+ * @submodule DOM
+ * @for p5.Element
+ */
+
+import { Element } from './p5.Element';
class MediaElement extends Element {
constructor(elt, pInst) {
@@ -1286,10 +1292,21 @@ class MediaElement extends Element {
this._prevTime = playbackTime;
}
-};
+}
-function media(p5, fn){
+// Cue inspired by JavaScript setTimeout, and the
+// Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org
+// eslint-disable-next-line no-unused-vars
+class Cue {
+ constructor(callback, time, id, val) {
+ this.callback = callback;
+ this.time = time;
+ this.id = id;
+ this.val = val;
+ }
+}
+function media(p5, fn){
/**
* Helpers for create methods.
*/
@@ -1297,8 +1314,8 @@ function media(p5, fn){
const node = pInst._userNode ? pInst._userNode : document.body;
node.appendChild(elt);
const c = media
- ? new p5.MediaElement(elt, pInst)
- : new p5.Element(elt, pInst);
+ ? new MediaElement(elt, pInst)
+ : new Element(elt, pInst);
pInst._elements.push(c);
return c;
}
diff --git a/src/io/files.js b/src/io/files.js
index 7f00915914..ba7dd0b8ef 100644
--- a/src/io/files.js
+++ b/src/io/files.js
@@ -1905,7 +1905,7 @@ function files(p5, fn){
// otherwise, parse the arguments
// if first param is a p5Graphics, then saveCanvas
- fn.saveCanvas(args[0].elt, args[1], args[2]);
+ fn.saveCanvas(args[0].canvas, args[1], args[2]);
return;
} else if (args.length === 1 && typeof args[0] === 'string') {
// if 1st param is String and only one arg, assume it is canvas filename
diff --git a/src/io/p5.XML.js b/src/io/p5.XML.js
index 2afd665bb3..fc2907c8b7 100644
--- a/src/io/p5.XML.js
+++ b/src/io/p5.XML.js
@@ -4,74 +4,17 @@
* @requires core
*/
-function xml(p5, fn){
- /**
- * A class to describe an XML object.
- *
- * Each `p5.XML` object provides an easy way to interact with XML data.
- * Extensible Markup Language
- * (XML)
- * is a standard format for sending data between applications. Like HTML, the
- * XML format is based on tags and attributes, as in
- * `<time units="s">1234</time>`.
- *
- * Note: Use loadXML() to load external XML files.
- *
- * @class p5.XML
- * @example
- *
- *
- * let myXML;
- *
- * // Load the XML and create a p5.XML object.
- * function preload() {
- * myXML = loadXML('assets/animals.xml');
- * }
- *
- * function setup() {
- * createCanvas(100, 100);
- *
- * background(200);
- *
- * // Get an array with all mammal tags.
- * let mammals = myXML.getChildren('mammal');
- *
- * // Style the text.
- * textAlign(LEFT, CENTER);
- * textFont('Courier New');
- * textSize(14);
- *
- * // Iterate over the mammals array.
- * for (let i = 0; i < mammals.length; i += 1) {
- *
- * // Calculate the y-coordinate.
- * let y = (i + 1) * 25;
- *
- * // Get the mammal's common name.
- * let name = mammals[i].getContent();
- *
- * // Display the mammal's name.
- * text(name, 20, y);
- * }
- *
- * describe(
- * 'The words "Goat", "Leopard", and "Zebra" written on three separate lines. The text is black on a gray background.'
- * );
- * }
- *
- *
- */
- p5.XML = class {
- constructor(DOM){
- if (!DOM) {
- const xmlDoc = document.implementation.createDocument(null, 'doc');
- this.DOM = xmlDoc.createElement('root');
- } else {
- this.DOM = DOM;
- }
+class XML {
+ constructor(DOM){
+ if (!DOM) {
+ const xmlDoc = document.implementation.createDocument(null, 'doc');
+ this.DOM = xmlDoc.createElement('root');
+ } else {
+ this.DOM = DOM;
}
+ }
- /**
+ /**
* Returns the element's parent element as a new p5.XML
* object.
*
@@ -117,11 +60,11 @@ function xml(p5, fn){
*
*
*/
- getParent() {
- return new p5.XML(this.DOM.parentElement);
- }
+ getParent() {
+ return new XML(this.DOM.parentElement);
+ }
- /**
+ /**
* Returns the element's name as a `String`.
*
* An XML element's name is given by its tag. For example, the element
@@ -166,11 +109,11 @@ function xml(p5, fn){
*
*
+ * let myXML;
+ *
+ * // Load the XML and create a p5.XML object.
+ * function preload() {
+ * myXML = loadXML('assets/animals.xml');
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Get an array with all mammal tags.
+ * let mammals = myXML.getChildren('mammal');
+ *
+ * // Style the text.
+ * textAlign(LEFT, CENTER);
+ * textFont('Courier New');
+ * textSize(14);
+ *
+ * // Iterate over the mammals array.
+ * for (let i = 0; i < mammals.length; i += 1) {
+ *
+ * // Calculate the y-coordinate.
+ * let y = (i + 1) * 25;
+ *
+ * // Get the mammal's common name.
+ * let name = mammals[i].getContent();
+ *
+ * // Display the mammal's name.
+ * text(name, 20, y);
+ * }
+ *
+ * describe(
+ * 'The words "Goat", "Leopard", and "Zebra" written on three separate lines. The text is black on a gray background.'
+ * );
+ * }
+ *
+ *