├── 01_basics ├── index.html ├── libraries │ ├── matter.js │ ├── p5.dom.js │ ├── p5.js │ └── p5.sound.js └── sketch.js ├── 02_bouncing_balls ├── index.html ├── libraries │ ├── matter.js │ ├── p5.dom.js │ ├── p5.js │ └── p5.sound.js └── sketch.js ├── 03_chain ├── index.html ├── libraries │ ├── matter.js │ ├── p5.dom.js │ ├── p5.js │ └── p5.sound.js └── sketch.js └── README.md /01_basics/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /01_basics/libraries/p5.dom.js: -------------------------------------------------------------------------------- 1 | /*! p5.dom.js v0.2.13 Oct 1, 2016 */ 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 | // p5 additions 38 | // ============================================================================= 39 | 40 | /** 41 | * Searches the page for an element with the given ID, class, or tag name (using the '#' or '.' 42 | * prefixes to specify an ID or class respectively, and none for a tag) and returns it as 43 | * a p5.Element. If a class or tag name is given with more than 1 element, 44 | * only the first element will be returned. 45 | * The DOM node itself can be accessed with .elt. 46 | * Returns null if none found. You can also specify a container to search within. 47 | * 48 | * @method select 49 | * @param {String} name id, class, or tag name of element to search for 50 | * @param {String} [container] id, p5.Element, or HTML element to search within 51 | * @return {Object/p5.Element|Null} p5.Element containing node found 52 | * @example 53 | *

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