├── addons ├── .DS_Store ├── p5.dom.js ├── p5.dom.min.js ├── p5.sound.js └── p5.sound.min.js ├── empty-example ├── index.html └── sketch.js ├── p5.js └── p5.min.js /addons/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibernationTheory/p5js-complete/8a401c21d57ed95a800a052c63daf4ba6afdb1cd/addons/.DS_Store -------------------------------------------------------------------------------- /addons/p5.dom.js: -------------------------------------------------------------------------------- 1 | /*! p5.dom.js v0.3.4 Aug 11, 2017 */ 2 | /** 3 | *

The web is much more than just canvas and p5.dom makes it easy to interact 4 | * with other HTML5 objects, including text, hyperlink, image, input, video, 5 | * audio, and webcam.

6 | *

There is a set of creation methods, DOM manipulation methods, and 7 | * an extended p5.Element that supports a range of HTML elements. See the 8 | * 9 | * beyond the canvas tutorial for a full overview of how this addon works. 10 | * 11 | *

Methods and properties shown in black are part of the p5.js core, items in 12 | * blue are part of the p5.dom library. You will need to include an extra file 13 | * in order to access the blue functions. See the 14 | * using a library 15 | * section for information on how to include this library. p5.dom comes with 16 | * p5 complete or you can download the single file 17 | * 18 | * here.

19 | *

See tutorial: beyond the canvas 20 | * for more info on how to use this libary. 21 | * 22 | * @module p5.dom 23 | * @submodule p5.dom 24 | * @for p5.dom 25 | * @main 26 | */ 27 | 28 | (function (root, factory) { 29 | if (typeof define === 'function' && define.amd) 30 | define('p5.dom', ['p5'], function (p5) { (factory(p5));}); 31 | else if (typeof exports === 'object') 32 | factory(require('../p5')); 33 | else 34 | factory(root['p5']); 35 | }(this, function (p5) { 36 | 37 | // ============================================================================= 38 | // p5 additions 39 | // ============================================================================= 40 | 41 | /** 42 | * Searches the page for an element with the given ID, class, or tag name (using the '#' or '.' 43 | * prefixes to specify an ID or class respectively, and none for a tag) and returns it as 44 | * a p5.Element. If a class or tag name is given with more than 1 element, 45 | * only the first element will be returned. 46 | * The DOM node itself can be accessed with .elt. 47 | * Returns null if none found. You can also specify a container to search within. 48 | * 49 | * @method select 50 | * @param {String} name id, class, or tag name of element to search for 51 | * @param {String} [container] id, p5.Element, or HTML element to search within 52 | * @return {Object|p5.Element|Null} p5.Element containing node found 53 | * @example 54 | *

55 | * function setup() { 56 | * createCanvas(100,100); 57 | * //translates canvas 50px down 58 | * select('canvas').position(100, 100); 59 | * } 60 | *
61 | *
62 | * // these are all valid calls to select() 63 | * var a = select('#moo'); 64 | * var b = select('#blah', '#myContainer'); 65 | * var c = select('#foo', b); 66 | * var d = document.getElementById('beep'); 67 | * var e = select('p', d); 68 | *
69 | * 70 | */ 71 | p5.prototype.select = function (e, p) { 72 | var res = null; 73 | var container = getContainer(p); 74 | if (e[0] === '.'){ 75 | e = e.slice(1); 76 | res = container.getElementsByClassName(e); 77 | if (res.length) { 78 | res = res[0]; 79 | } else { 80 | res = null; 81 | } 82 | }else if (e[0] === '#'){ 83 | e = e.slice(1); 84 | res = container.getElementById(e); 85 | }else { 86 | res = container.getElementsByTagName(e); 87 | if (res.length) { 88 | res = res[0]; 89 | } else { 90 | res = null; 91 | } 92 | } 93 | if (res) { 94 | return wrapElement(res); 95 | } else { 96 | return null; 97 | } 98 | }; 99 | 100 | /** 101 | * Searches the page for elements with the given class or tag name (using the '.' prefix 102 | * to specify a class and no prefix for a tag) and returns them as p5.Elements 103 | * in an array. 104 | * The DOM node itself can be accessed with .elt. 105 | * Returns an empty array if none found. 106 | * You can also specify a container to search within. 107 | * 108 | * @method selectAll 109 | * @param {String} name class or tag name of elements to search for 110 | * @param {String} [container] id, p5.Element, or HTML element to search within 111 | * @return {Array} Array of p5.Elements containing nodes found 112 | * @example 113 | *
114 | * function setup() { 115 | * createButton('btn'); 116 | * createButton('2nd btn'); 117 | * createButton('3rd btn'); 118 | * var buttons = selectAll('button'); 119 | * 120 | * for (var i = 0; i < buttons.length; i++){ 121 | * buttons[i].size(100,100); 122 | * } 123 | * } 124 | *
125 | *
126 | * // these are all valid calls to selectAll() 127 | * var a = selectAll('.moo'); 128 | * var b = selectAll('div'); 129 | * var c = selectAll('button', '#myContainer'); 130 | * var d = select('#container'); 131 | * var e = selectAll('p', d); 132 | * var f = document.getElementById('beep'); 133 | * var g = select('.blah', f); 134 | *
135 | * 136 | */ 137 | p5.prototype.selectAll = function (e, p) { 138 | var arr = []; 139 | var res; 140 | var container = getContainer(p); 141 | if (e[0] === '.'){ 142 | e = e.slice(1); 143 | res = container.getElementsByClassName(e); 144 | } else { 145 | res = container.getElementsByTagName(e); 146 | } 147 | if (res) { 148 | for (var j = 0; j < res.length; j++) { 149 | var obj = wrapElement(res[j]); 150 | arr.push(obj); 151 | } 152 | } 153 | return arr; 154 | }; 155 | 156 | /** 157 | * Helper function for select and selectAll 158 | */ 159 | function getContainer(p) { 160 | var container = document; 161 | if (typeof p === 'string' && p[0] === '#'){ 162 | p = p.slice(1); 163 | container = document.getElementById(p) || document; 164 | } else if (p instanceof p5.Element){ 165 | container = p.elt; 166 | } else if (p instanceof HTMLElement){ 167 | container = p; 168 | } 169 | return container; 170 | } 171 | 172 | /** 173 | * Helper function for getElement and getElements. 174 | */ 175 | function wrapElement(elt) { 176 | if(elt.tagName === "INPUT" && elt.type === "checkbox") { 177 | var converted = new p5.Element(elt); 178 | converted.checked = function(){ 179 | if (arguments.length === 0){ 180 | return this.elt.checked; 181 | } else if(arguments[0]) { 182 | this.elt.checked = true; 183 | } else { 184 | this.elt.checked = false; 185 | } 186 | return this; 187 | }; 188 | return converted; 189 | } else if (elt.tagName === "VIDEO" || elt.tagName === "AUDIO") { 190 | return new p5.MediaElement(elt); 191 | } else if ( elt.tagName === "SELECT" ){ 192 | return createSelect( new p5.Element(elt) ); 193 | } 194 | else { 195 | return new p5.Element(elt); 196 | } 197 | } 198 | 199 | /** 200 | * Removes all elements created by p5, except any canvas / graphics 201 | * elements created by createCanvas or createGraphics. 202 | * Event handlers are removed, and element is removed from the DOM. 203 | * @method removeElements 204 | * @example 205 | *
206 | * function setup() { 207 | * createCanvas(100, 100); 208 | * createDiv('this is some text'); 209 | * createP('this is a paragraph'); 210 | * } 211 | * function mousePressed() { 212 | * removeElements(); // this will remove the div and p, not canvas 213 | * } 214 | *
215 | * 216 | */ 217 | p5.prototype.removeElements = function (e) { 218 | for (var i=0; i 246 | * var myDiv; 247 | * function setup() { 248 | * myDiv = createDiv('this is some text'); 249 | * } 250 | * 251 | */ 252 | 253 | /** 254 | * Creates a <p></p> element in the DOM with given inner HTML. Used 255 | * for paragraph length text. 256 | * Appends to the container node if one is specified, otherwise 257 | * appends to body. 258 | * 259 | * @method createP 260 | * @param {String} [html] inner HTML for element created 261 | * @return {Object|p5.Element} pointer to p5.Element holding created node 262 | * @example 263 | *
264 | * var myP; 265 | * function setup() { 266 | * myP = createP('this is some text'); 267 | * } 268 | *
269 | */ 270 | 271 | /** 272 | * Creates a <span></span> element in the DOM with given inner HTML. 273 | * Appends to the container node if one is specified, otherwise 274 | * appends to body. 275 | * 276 | * @method createSpan 277 | * @param {String} [html] inner HTML for element created 278 | * @return {Object|p5.Element} pointer to p5.Element holding created node 279 | * @example 280 | *
281 | * var mySpan; 282 | * function setup() { 283 | * mySpan = createSpan('this is some text'); 284 | * } 285 | *
286 | */ 287 | var tags = ['div', 'p', 'span']; 288 | tags.forEach(function(tag) { 289 | var method = 'create' + tag.charAt(0).toUpperCase() + tag.slice(1); 290 | p5.prototype[method] = function(html) { 291 | var elt = document.createElement(tag); 292 | elt.innerHTML = typeof html === undefined ? "" : html; 293 | return addElement(elt, this); 294 | } 295 | }); 296 | 297 | /** 298 | * Creates an <img> element in the DOM with given src and 299 | * alternate text. 300 | * Appends to the container node if one is specified, otherwise 301 | * appends to body. 302 | * 303 | * @method createImg 304 | * @param {String} src src path or url for image 305 | * @param {String} [alt] alternate text to be used if image does not load 306 | * @param {Function} [successCallback] callback to be called once image data is loaded 307 | * @return {Object|p5.Element} pointer to p5.Element holding created node 308 | * @example 309 | *
310 | * var img; 311 | * function setup() { 312 | * img = createImg('http://p5js.org/img/asterisk-01.png'); 313 | * } 314 | *
315 | */ 316 | p5.prototype.createImg = function() { 317 | var elt = document.createElement('img'); 318 | var args = arguments; 319 | var self; 320 | var setAttrs = function(){ 321 | self.width = elt.offsetWidth || elt.width; 322 | self.height = elt.offsetHeight || elt.height; 323 | if (args.length > 1 && typeof args[1] === 'function'){ 324 | self.fn = args[1]; 325 | self.fn(); 326 | }else if (args.length > 1 && typeof args[2] === 'function'){ 327 | self.fn = args[2]; 328 | self.fn(); 329 | } 330 | }; 331 | elt.src = args[0]; 332 | if (args.length > 1 && typeof args[1] === 'string'){ 333 | elt.alt = args[1]; 334 | } 335 | elt.onload = function(){ 336 | setAttrs(); 337 | } 338 | self = addElement(elt, this); 339 | return self; 340 | }; 341 | 342 | /** 343 | * Creates an <a></a> element in the DOM for including a hyperlink. 344 | * Appends to the container node if one is specified, otherwise 345 | * appends to body. 346 | * 347 | * @method createA 348 | * @param {String} href url of page to link to 349 | * @param {String} html inner html of link element to display 350 | * @param {String} [target] target where new link should open, 351 | * could be _blank, _self, _parent, _top. 352 | * @return {Object|p5.Element} pointer to p5.Element holding created node 353 | * @example 354 | *
355 | * var myLink; 356 | * function setup() { 357 | * myLink = createA('http://p5js.org/', 'this is a link'); 358 | * } 359 | *
360 | */ 361 | p5.prototype.createA = function(href, html, target) { 362 | var elt = document.createElement('a'); 363 | elt.href = href; 364 | elt.innerHTML = html; 365 | if (target) elt.target = target; 366 | return addElement(elt, this); 367 | }; 368 | 369 | /** INPUT **/ 370 | 371 | 372 | /** 373 | * Creates a slider <input></input> element in the DOM. 374 | * Use .size() to set the display length of the slider. 375 | * Appends to the container node if one is specified, otherwise 376 | * appends to body. 377 | * 378 | * @method createSlider 379 | * @param {Number} min minimum value of the slider 380 | * @param {Number} max maximum value of the slider 381 | * @param {Number} [value] default value of the slider 382 | * @param {Number} [step] step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value) 383 | * @return {Object|p5.Element} pointer to p5.Element holding created node 384 | * @example 385 | *
386 | * var slider; 387 | * function setup() { 388 | * slider = createSlider(0, 255, 100); 389 | * slider.position(10, 10); 390 | * slider.style('width', '80px'); 391 | * } 392 | * 393 | * function draw() { 394 | * var val = slider.value(); 395 | * background(val); 396 | * } 397 | *
398 | * 399 | *
400 | * var slider; 401 | * function setup() { 402 | * colorMode(HSB); 403 | * slider = createSlider(0, 360, 60, 40); 404 | * slider.position(10, 10); 405 | * slider.style('width', '80px'); 406 | * } 407 | * 408 | * function draw() { 409 | * var val = slider.value(); 410 | * background(val, 100, 100, 1); 411 | * } 412 | *
413 | */ 414 | p5.prototype.createSlider = function(min, max, value, step) { 415 | var elt = document.createElement('input'); 416 | elt.type = 'range'; 417 | elt.min = min; 418 | elt.max = max; 419 | if (step === 0) { 420 | elt.step = .000000000000000001; // smallest valid step 421 | } else if (step) { 422 | elt.step = step; 423 | } 424 | if (typeof(value) === "number") elt.value = value; 425 | return addElement(elt, this); 426 | }; 427 | 428 | /** 429 | * Creates a <button></button> element in the DOM. 430 | * Use .size() to set the display size of the button. 431 | * Use .mousePressed() to specify behavior on press. 432 | * Appends to the container node if one is specified, otherwise 433 | * appends to body. 434 | * 435 | * @method createButton 436 | * @param {String} label label displayed on the button 437 | * @param {String} [value] value of the button 438 | * @return {Object|p5.Element} pointer to p5.Element holding created node 439 | * @example 440 | *
441 | * var button; 442 | * function setup() { 443 | * createCanvas(100, 100); 444 | * background(0); 445 | * button = createButton('click me'); 446 | * button.position(19, 19); 447 | * button.mousePressed(changeBG); 448 | * } 449 | * 450 | * function changeBG() { 451 | * var val = random(255); 452 | * background(val); 453 | * } 454 | *
455 | */ 456 | p5.prototype.createButton = function(label, value) { 457 | var elt = document.createElement('button'); 458 | elt.innerHTML = label; 459 | if (value) elt.value = value; 460 | return addElement(elt, this); 461 | }; 462 | 463 | /** 464 | * Creates a checkbox <input></input> element in the DOM. 465 | * Calling .checked() on a checkbox returns if it is checked or not 466 | * 467 | * @method createCheckbox 468 | * @param {String} [label] label displayed after checkbox 469 | * @param {boolean} [value] value of the checkbox; checked is true, unchecked is false.Unchecked if no value given 470 | * @return {Object|p5.Element} pointer to p5.Element holding created node 471 | * @example 472 | *
473 | * var checkbox; 474 | * 475 | * function setup() { 476 | * checkbox = createCheckbox('label', false); 477 | * checkbox.changed(myCheckedEvent); 478 | * } 479 | * 480 | * function myCheckedEvent() { 481 | * if (this.checked()) { 482 | * console.log("Checking!"); 483 | * } else { 484 | * console.log("Unchecking!"); 485 | * } 486 | * } 487 | *
488 | */ 489 | p5.prototype.createCheckbox = function() { 490 | var elt = document.createElement('div'); 491 | var checkbox = document.createElement('input'); 492 | checkbox.type = 'checkbox'; 493 | elt.appendChild(checkbox); 494 | //checkbox must be wrapped in p5.Element before label so that label appears after 495 | var self = addElement(elt, this); 496 | self.checked = function(){ 497 | var cb = self.elt.getElementsByTagName('input')[0]; 498 | if (cb) { 499 | if (arguments.length === 0){ 500 | return cb.checked; 501 | }else if(arguments[0]){ 502 | cb.checked = true; 503 | }else{ 504 | cb.checked = false; 505 | } 506 | } 507 | return self; 508 | }; 509 | this.value = function(val){ 510 | self.value = val; 511 | return this; 512 | }; 513 | if (arguments[0]){ 514 | var ran = Math.random().toString(36).slice(2); 515 | var label = document.createElement('label'); 516 | checkbox.setAttribute('id', ran); 517 | label.htmlFor = ran; 518 | self.value(arguments[0]); 519 | label.appendChild(document.createTextNode(arguments[0])); 520 | elt.appendChild(label); 521 | } 522 | if (arguments[1]){ 523 | checkbox.checked = true; 524 | } 525 | return self; 526 | }; 527 | 528 | /** 529 | * Creates a dropdown menu <select></select> element in the DOM. 530 | * It also helps to assign select-box methods to p5.Element when selecting existing select box 531 | * @method createSelect 532 | * @param {boolean} [multiple] true if dropdown should support multiple selections 533 | * @return {p5.Element} 534 | * @example 535 | *
536 | * var sel; 537 | * 538 | * function setup() { 539 | * textAlign(CENTER); 540 | * background(200); 541 | * sel = createSelect(); 542 | * sel.position(10, 10); 543 | * sel.option('pear'); 544 | * sel.option('kiwi'); 545 | * sel.option('grape'); 546 | * sel.changed(mySelectEvent); 547 | * } 548 | * 549 | * function mySelectEvent() { 550 | * var item = sel.value(); 551 | * background(200); 552 | * text("it's a "+item+"!", 50, 50); 553 | * } 554 | *
555 | */ 556 | /** 557 | * @method createSelect 558 | * @param {Object} existing DOM select element 559 | * @return {p5.Element} 560 | */ 561 | 562 | p5.prototype.createSelect = function() { 563 | var elt, self; 564 | var arg = arguments[0]; 565 | if( typeof arg === 'object' && arg.elt.nodeName === 'SELECT' ) { 566 | self = arg; 567 | elt = this.elt = arg.elt; 568 | } else { 569 | elt = document.createElement('select'); 570 | if( arg && typeof arg === 'boolean' ) { 571 | elt.setAttribute('multiple', 'true'); 572 | } 573 | self = addElement(elt, this); 574 | } 575 | self.option = function(name, value) { 576 | var index; 577 | //see if there is already an option with this name 578 | for (var i = 0; i < this.elt.length; i++) { 579 | if(this.elt[i].innerHTML == name) { 580 | index = i; 581 | break; 582 | } 583 | } 584 | //if there is an option with this name we will modify it 585 | if(index !== undefined) { 586 | //if the user passed in false then delete that option 587 | if(value === false) { 588 | this.elt.remove(index); 589 | } else { 590 | //otherwise if the name and value are the same then change both 591 | if(this.elt[index].innerHTML == this.elt[index].value) { 592 | this.elt[index].innerHTML = this.elt[index].value = value; 593 | //otherwise just change the value 594 | } else { 595 | this.elt[index].value = value; 596 | } 597 | } 598 | } 599 | //if it doesn't exist make it 600 | else { 601 | var opt = document.createElement('option'); 602 | opt.innerHTML = name; 603 | if (arguments.length > 1) 604 | opt.value = value; 605 | else 606 | opt.value = name; 607 | elt.appendChild(opt); 608 | } 609 | }; 610 | self.selected = function(value) { 611 | var arr = []; 612 | if (arguments.length > 0) { 613 | for (var i = 0; i < this.elt.length; i++) { 614 | if (value.toString() === this.elt[i].value) { 615 | this.elt.selectedIndex = i; 616 | } 617 | } 618 | return this; 619 | } else { 620 | if (this.elt.getAttribute('multiple')) { 621 | for (var i = 0; i < this.elt.selectedOptions.length; i++) { 622 | arr.push(this.elt.selectedOptions[i].value); 623 | } 624 | return arr; 625 | } else { 626 | return this.elt.value; 627 | } 628 | } 629 | }; 630 | return self; 631 | }; 632 | 633 | /** 634 | * Creates a radio button <input></input> element in the DOM. 635 | * The .option() method can be used to set options for the radio after it is 636 | * created. The .value() method will return the currently selected option. 637 | * 638 | * @method createRadio 639 | * @param {String} [divId] the id and name of the created div and input field respectively 640 | * @return {Object|p5.Element} pointer to p5.Element holding created node 641 | * @example 642 | *
643 | * var radio; 644 | * 645 | * function setup() { 646 | * radio = createRadio(); 647 | * radio.option("black"); 648 | * radio.option("white"); 649 | * radio.option("gray"); 650 | * radio.style('width', '60px'); 651 | * textAlign(CENTER); 652 | * fill(255, 0, 0); 653 | * } 654 | * 655 | * function draw() { 656 | * var val = radio.value(); 657 | * background(val); 658 | * text(val, width/2, height/2); 659 | * } 660 | *
661 | *
662 | * var radio; 663 | * 664 | * function setup() { 665 | * radio = createRadio(); 666 | * radio.option('apple', 1); 667 | * radio.option('bread', 2); 668 | * radio.option('juice', 3); 669 | * radio.style('width', '60px'); 670 | * textAlign(CENTER); 671 | * } 672 | * 673 | * function draw() { 674 | * background(200); 675 | * var val = radio.value(); 676 | * if (val) { 677 | * text('item cost is $'+val, width/2, height/2); 678 | * } 679 | * } 680 | *
681 | */ 682 | p5.prototype.createRadio = function() { 683 | var radios = document.querySelectorAll("input[type=radio]"); 684 | var count = 0; 685 | if(radios.length > 1){ 686 | var length = radios.length; 687 | var prev=radios[0].name; 688 | var current = radios[1].name; 689 | count = 1; 690 | for(var i = 1; i < length; i++) { 691 | current = radios[i].name; 692 | if(prev != current){ 693 | count++; 694 | } 695 | prev = current; 696 | } 697 | } 698 | else if (radios.length == 1){ 699 | count = 1; 700 | } 701 | var elt = document.createElement('div'); 702 | var self = addElement(elt, this); 703 | var times = -1; 704 | self.option = function(name, value){ 705 | var opt = document.createElement('input'); 706 | opt.type = 'radio'; 707 | opt.innerHTML = name; 708 | if (arguments.length > 1) 709 | opt.value = value; 710 | else 711 | opt.value = name; 712 | opt.setAttribute('name',"defaultradio"+count); 713 | elt.appendChild(opt); 714 | if (name){ 715 | times++; 716 | var ran = Math.random().toString(36).slice(2); 717 | var label = document.createElement('label'); 718 | opt.setAttribute('id', "defaultradio"+count+"-"+times); 719 | label.htmlFor = "defaultradio"+count+"-"+times; 720 | label.appendChild(document.createTextNode(name)); 721 | elt.appendChild(label); 722 | } 723 | return opt; 724 | }; 725 | self.selected = function(){ 726 | var length = this.elt.childNodes.length; 727 | if(arguments.length == 1) { 728 | for (var i = 0; i < length; i+=2){ 729 | if(this.elt.childNodes[i].value == arguments[0]) 730 | this.elt.childNodes[i].checked = true; 731 | } 732 | return this; 733 | } else { 734 | for (var i = 0; i < length; i+=2){ 735 | if(this.elt.childNodes[i].checked == true) 736 | return this.elt.childNodes[i].value; 737 | } 738 | } 739 | }; 740 | self.value = function(){ 741 | var length = this.elt.childNodes.length; 742 | if(arguments.length == 1) { 743 | for (var i = 0; i < length; i+=2){ 744 | if(this.elt.childNodes[i].value == arguments[0]) 745 | this.elt.childNodes[i].checked = true; 746 | } 747 | return this; 748 | } else { 749 | for (var i = 0; i < length; i+=2){ 750 | if(this.elt.childNodes[i].checked == true) 751 | return this.elt.childNodes[i].value; 752 | } 753 | return ""; 754 | } 755 | }; 756 | return self 757 | }; 758 | 759 | /** 760 | * Creates an <input></input> element in the DOM for text input. 761 | * Use .size() to set the display length of the box. 762 | * Appends to the container node if one is specified, otherwise 763 | * appends to body. 764 | * 765 | * @method createInput 766 | * @param {Number} [value] default value of the input box 767 | * @param {String} [type] type of text, ie text, password etc. Defaults to text 768 | * @return {Object|p5.Element} pointer to p5.Element holding created node 769 | * @example 770 | *
771 | * function setup(){ 772 | * var inp = createInput(''); 773 | * inp.input(myInputEvent); 774 | * } 775 | * 776 | * function myInputEvent(){ 777 | * console.log('you are typing: ', this.value()); 778 | * } 779 | * 780 | *
781 | */ 782 | p5.prototype.createInput = function(value, type) { 783 | var elt = document.createElement('input'); 784 | elt.type = type ? type : 'text'; 785 | if (value) elt.value = value; 786 | return addElement(elt, this); 787 | }; 788 | 789 | /** 790 | * Creates an <input></input> element in the DOM of type 'file'. 791 | * This allows users to select local files for use in a sketch. 792 | * 793 | * @method createFileInput 794 | * @param {Function} [callback] callback function for when a file loaded 795 | * @param {String} [multiple] optional to allow multiple files selected 796 | * @return {Object|p5.Element} pointer to p5.Element holding created DOM element 797 | * @example 798 | * var input; 799 | * var img; 800 | * 801 | * function setup() { 802 | * input = createFileInput(handleFile); 803 | * input.position(0, 0); 804 | * } 805 | * 806 | * function draw() { 807 | * if (img) { 808 | * image(img, 0, 0, width, height); 809 | * } 810 | * } 811 | * 812 | * function handleFile(file) { 813 | * print(file); 814 | * if (file.type === 'image') { 815 | * img = createImg(file.data); 816 | * img.hide(); 817 | * } 818 | * } 819 | */ 820 | p5.prototype.createFileInput = function(callback, multiple) { 821 | 822 | // Is the file stuff supported? 823 | if (window.File && window.FileReader && window.FileList && window.Blob) { 824 | // Yup, we're ok and make an input file selector 825 | var elt = document.createElement('input'); 826 | elt.type = 'file'; 827 | 828 | // If we get a second argument that evaluates to true 829 | // then we are looking for multiple files 830 | if (multiple) { 831 | // Anything gets the job done 832 | elt.multiple = 'multiple'; 833 | } 834 | 835 | // Function to handle when a file is selected 836 | // We're simplifying life and assuming that we always 837 | // want to load every selected file 838 | function handleFileSelect(evt) { 839 | // These are the files 840 | var files = evt.target.files; 841 | // Load each one and trigger a callback 842 | for (var i = 0; i < files.length; i++) { 843 | var f = files[i]; 844 | var reader = new FileReader(); 845 | function makeLoader(theFile) { 846 | // Making a p5.File object 847 | var p5file = new p5.File(theFile); 848 | return function(e) { 849 | p5file.data = e.target.result; 850 | callback(p5file); 851 | }; 852 | }; 853 | reader.onload = makeLoader(f); 854 | 855 | // Text or data? 856 | // This should likely be improved 857 | if (f.type.indexOf('text') > -1) { 858 | reader.readAsText(f); 859 | } else { 860 | reader.readAsDataURL(f); 861 | } 862 | } 863 | } 864 | 865 | // Now let's handle when a file was selected 866 | elt.addEventListener('change', handleFileSelect, false); 867 | return addElement(elt, this); 868 | } else { 869 | console.log('The File APIs are not fully supported in this browser. Cannot create element.'); 870 | } 871 | }; 872 | 873 | 874 | /** VIDEO STUFF **/ 875 | 876 | function createMedia(pInst, type, src, callback) { 877 | var elt = document.createElement(type); 878 | 879 | // allow src to be empty 880 | var src = src || ''; 881 | if (typeof src === 'string') { 882 | src = [src]; 883 | } 884 | for (var i=0; i