├── README.md ├── ball.js ├── brick.js ├── index.html ├── libraries ├── p5.dom.js ├── p5.js └── p5.sound.js ├── paddle.js └── sketch.js /README.md: -------------------------------------------------------------------------------- 1 | # BrickBreaker 2 | Code Repository for Yining Shi's Guest Tutorial 3 | 4 | ### Video Tutorials 5 | Watch the tutorial here! [https://youtu.be/5kEPixL8JoU](https://youtu.be/5kEPixL8JoU) 6 | 7 | ### Play the game! 8 | * https://codingtrain.github.io/BrickBreaker 9 | 10 | ### Viewer Remixes of the Game 11 | * [Colorful Brick Breaker](https://yining1023.github.io/brickBreaker), [Code](https://github.com/yining1023/brickBreaker) 12 | * Add your name and link here! 13 | 14 | ### Getting Started 15 | ```shell 16 | $ git clone https://github.com/CodingTrain/BrickBreaker.git 17 | $ cd BrickBreaker 18 | $ python -m SimpleHTTPServer # $ python3 -m http.server (if you are using python 3) 19 | ``` 20 | Go to localhost:8000, you should be able to see the game interface. 21 | 22 | This is inspired by Danial Shiffman's [Asteroids Coding Challenge](https://www.youtube.com/watch?v=hacZU523FyM) 23 | -------------------------------------------------------------------------------- /ball.js: -------------------------------------------------------------------------------- 1 | function Ball() { 2 | this.pos = createVector(width / 2, height / 2); 3 | 4 | this.r = 30; 5 | this.vel = createVector(1, 1).mult(4); 6 | this.direction = createVector(1, 1); 7 | 8 | this.update = function() { 9 | this.pos.x += this.vel.x * this.direction.x; 10 | this.pos.y += this.vel.y * this.direction.y; 11 | } 12 | 13 | this.display = function() { 14 | ellipse(this.pos.x, this.pos.y, this.r * 2, this.r * 2); 15 | } 16 | 17 | this.checkEdges = function() { 18 | if (this.pos.x > width - this.r && this.direction.x > 0) { 19 | this.direction.x *= -1; 20 | } 21 | if (this.pos.x < this.r && this.direction.x < 0) { 22 | this.direction.x *= -1; 23 | } 24 | if (this.pos.y < this.r && ball.direction.y < 0) this.direction.y *= -1; 25 | } 26 | 27 | this.meets = function(paddle) { 28 | if (this.pos.y < paddle.pos.y && 29 | this.pos.y > paddle.pos.y - this.r && 30 | ball.pos.x > paddle.pos.x - ball.r && 31 | ball.pos.x < paddle.pos.x + paddle.w + ball.r) { 32 | return true; 33 | } else { 34 | return false; 35 | } 36 | } 37 | 38 | this.hits = function(brick) { 39 | var d = dist(this.pos.x, this.pos.y, brick.pos.x, brick.pos.y); 40 | if (d < brick.r + this.r) { 41 | return true; 42 | } else { 43 | return false; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /brick.js: -------------------------------------------------------------------------------- 1 | function Brick(pos, r) { 2 | this.pos = createVector(random(100, width - 100), random(100, height - 400)); 3 | this.r = random(20, 80); 4 | this.total = 6; 5 | 6 | this.display = function() { 7 | push(); 8 | translate(this.pos.x, this.pos.y); 9 | beginShape(); 10 | for (var i = 0; i < this.total; i++) { 11 | var angle = map(i, 0, this.total, 0, TWO_PI); 12 | var r = this.r; 13 | var x = r * cos(angle); 14 | var y = r * sin(angle); 15 | vertex(x, y); 16 | } 17 | endShape(CLOSE); 18 | pop(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Untitled 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /libraries/p5.dom.js: -------------------------------------------------------------------------------- 1 | /*! p5.dom.js v0.2.12 August 17, 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 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) elt.step = step; 416 | if (typeof(value) === "number") elt.value = value; 417 | return addElement(elt, this); 418 | }; 419 | 420 | /** 421 | * Creates a <button></button> element in the DOM. 422 | * Use .size() to set the display size of the button. 423 | * Use .mousePressed() to specify behavior on press. 424 | * Appends to the container node if one is specified, otherwise 425 | * appends to body. 426 | * 427 | * @method createButton 428 | * @param {String} label label displayed on the button 429 | * @param {String} [value] value of the button 430 | * @return {Object/p5.Element} pointer to p5.Element holding created node 431 | * @example 432 | *
433 | * var button; 434 | * function setup() { 435 | * createCanvas(100, 100); 436 | * background(0); 437 | * button = createButton('click me'); 438 | * button.position(19, 19); 439 | * button.mousePressed(changeBG); 440 | * } 441 | * 442 | * function changeBG() { 443 | * var val = random(255); 444 | * background(val); 445 | * } 446 | *
447 | */ 448 | p5.prototype.createButton = function(label, value) { 449 | var elt = document.createElement('button'); 450 | elt.innerHTML = label; 451 | elt.value = value; 452 | if (value) elt.value = value; 453 | return addElement(elt, this); 454 | }; 455 | 456 | /** 457 | * Creates a checkbox <input></input> element in the DOM. 458 | * Calling .checked() on a checkbox returns if it is checked or not 459 | * 460 | * @method createCheckbox 461 | * @param {String} [label] label displayed after checkbox 462 | * @param {boolean} [value] value of the checkbox; checked is true, unchecked is false.Unchecked if no value given 463 | * @return {Object/p5.Element} pointer to p5.Element holding created node 464 | * @example 465 | *
466 | * var checkbox; 467 | * 468 | * function setup() { 469 | * checkbox = createCheckbox('label', false); 470 | * checkbox.changed(myCheckedEvent); 471 | * } 472 | * 473 | * function myCheckedEvent() { 474 | * if (this.checked()) { 475 | * console.log("Checking!"); 476 | * } else { 477 | * console.log("Unchecking!"); 478 | * } 479 | * } 480 | *
481 | */ 482 | p5.prototype.createCheckbox = function() { 483 | var elt = document.createElement('div'); 484 | var checkbox = document.createElement('input'); 485 | checkbox.type = 'checkbox'; 486 | elt.appendChild(checkbox); 487 | //checkbox must be wrapped in p5.Element before label so that label appears after 488 | var self = addElement(elt, this); 489 | self.checked = function(){ 490 | var cb = self.elt.getElementsByTagName('input')[0]; 491 | if (cb) { 492 | if (arguments.length === 0){ 493 | return cb.checked; 494 | }else if(arguments[0]){ 495 | cb.checked = true; 496 | }else{ 497 | cb.checked = false; 498 | } 499 | } 500 | return self; 501 | }; 502 | this.value = function(val){ 503 | self.value = val; 504 | return this; 505 | }; 506 | if (arguments[0]){ 507 | var ran = Math.random().toString(36).slice(2); 508 | var label = document.createElement('label'); 509 | checkbox.setAttribute('id', ran); 510 | label.htmlFor = ran; 511 | self.value(arguments[0]); 512 | label.appendChild(document.createTextNode(arguments[0])); 513 | elt.appendChild(label); 514 | } 515 | if (arguments[1]){ 516 | checkbox.checked = true; 517 | } 518 | return self; 519 | }; 520 | 521 | /** 522 | * Creates a dropdown menu <select></select> element in the DOM. 523 | * @method createSelect 524 | * @param {boolean} [multiple] [true if dropdown should support multiple selections] 525 | * @return {Object/p5.Element} pointer to p5.Element holding created node 526 | * @example 527 | *
528 | * var sel; 529 | * 530 | * function setup() { 531 | * textAlign(CENTER); 532 | * background(200); 533 | * sel = createSelect(); 534 | * sel.position(10, 10); 535 | * sel.option('pear'); 536 | * sel.option('kiwi'); 537 | * sel.option('grape'); 538 | * sel.changed(mySelectEvent); 539 | * } 540 | * 541 | * function mySelectEvent() { 542 | * var item = sel.value(); 543 | * background(200); 544 | * text("it's a "+item+"!", 50, 50); 545 | * } 546 | *
547 | */ 548 | p5.prototype.createSelect = function(mult) { 549 | var elt = document.createElement('select'); 550 | if (mult){ 551 | elt.setAttribute('multiple', 'true'); 552 | } 553 | var self = addElement(elt, this); 554 | self.option = function(name, value){ 555 | var opt = document.createElement('option'); 556 | opt.innerHTML = name; 557 | if (arguments.length > 1) 558 | opt.value = value; 559 | else 560 | opt.value = name; 561 | elt.appendChild(opt); 562 | }; 563 | self.selected = function(value){ 564 | var arr = []; 565 | if (arguments.length > 0){ 566 | for (var i = 0; i < this.elt.length; i++){ 567 | if (value.toString() === this.elt[i].value){ 568 | this.elt.selectedIndex = i; 569 | } 570 | } 571 | return this; 572 | }else{ 573 | if (mult){ 574 | for (var i = 0; i < this.elt.selectedOptions.length; i++){ 575 | arr.push(this.elt.selectedOptions[i].value); 576 | } 577 | return arr; 578 | }else{ 579 | return this.elt.value; 580 | } 581 | } 582 | }; 583 | return self; 584 | }; 585 | 586 | /** 587 | * Creates a radio button <input></input> element in the DOM. 588 | * The .option() method can be used to set options for the radio after it is 589 | * created. The .value() method will return the currently selected option. 590 | * 591 | * @method createRadio 592 | * @param {String} [divId] the id and name of the created div and input field respectively 593 | * @return {Object/p5.Element} pointer to p5.Element holding created node 594 | * @example 595 | *
596 | * var radio; 597 | * 598 | * function setup() { 599 | * radio = createRadio(); 600 | * radio.option("black"); 601 | * radio.option("white"); 602 | * radio.option("gray"); 603 | * radio.style('width', '60px'); 604 | * textAlign(CENTER); 605 | * fill(255, 0, 0); 606 | * } 607 | * 608 | * function draw() { 609 | * var val = radio.value(); 610 | * background(val); 611 | * text(val, width/2, height/2); 612 | * } 613 | *
614 | *
615 | * var radio; 616 | * 617 | * function setup() { 618 | * radio = createRadio(); 619 | * radio.option('apple', 1); 620 | * radio.option('bread', 2); 621 | * radio.option('juice', 3); 622 | * radio.style('width', '60px'); 623 | * textAlign(CENTER); 624 | * } 625 | * 626 | * function draw() { 627 | * background(200); 628 | * var val = radio.value(); 629 | * if (val) { 630 | * text('item cost is $'+val, width/2, height/2); 631 | * } 632 | * } 633 | *
634 | */ 635 | p5.prototype.createRadio = function() { 636 | var radios = document.querySelectorAll("input[type=radio]"); 637 | var count = 0; 638 | if(radios.length > 1){ 639 | var length = radios.length; 640 | var prev=radios[0].name; 641 | var current = radios[1].name; 642 | count = 1; 643 | for(var i = 1; i < length; i++) { 644 | current = radios[i].name; 645 | if(prev != current){ 646 | count++; 647 | } 648 | prev = current; 649 | } 650 | } 651 | else if (radios.length == 1){ 652 | count = 1; 653 | } 654 | var elt = document.createElement('div'); 655 | var self = addElement(elt, this); 656 | var times = -1; 657 | self.option = function(name, value){ 658 | var opt = document.createElement('input'); 659 | opt.type = 'radio'; 660 | opt.innerHTML = name; 661 | if (arguments.length > 1) 662 | opt.value = value; 663 | else 664 | opt.value = name; 665 | opt.setAttribute('name',"defaultradio"+count); 666 | elt.appendChild(opt); 667 | if (name){ 668 | times++; 669 | var ran = Math.random().toString(36).slice(2); 670 | var label = document.createElement('label'); 671 | opt.setAttribute('id', "defaultradio"+count+"-"+times); 672 | label.htmlFor = "defaultradio"+count+"-"+times; 673 | label.appendChild(document.createTextNode(name)); 674 | elt.appendChild(label); 675 | } 676 | return opt; 677 | }; 678 | self.selected = function(){ 679 | var length = this.elt.childNodes.length; 680 | if(arguments.length == 1) { 681 | for (var i = 0; i < length; i+=2){ 682 | if(this.elt.childNodes[i].value == arguments[0]) 683 | this.elt.childNodes[i].checked = true; 684 | } 685 | return this; 686 | } else { 687 | for (var i = 0; i < length; i+=2){ 688 | if(this.elt.childNodes[i].checked == true) 689 | return this.elt.childNodes[i].value; 690 | } 691 | } 692 | }; 693 | self.value = function(){ 694 | var length = this.elt.childNodes.length; 695 | if(arguments.length == 1) { 696 | for (var i = 0; i < length; i+=2){ 697 | if(this.elt.childNodes[i].value == arguments[0]) 698 | this.elt.childNodes[i].checked = true; 699 | } 700 | return this; 701 | } else { 702 | for (var i = 0; i < length; i+=2){ 703 | if(this.elt.childNodes[i].checked == true) 704 | return this.elt.childNodes[i].value; 705 | } 706 | return ""; 707 | } 708 | }; 709 | return self 710 | }; 711 | 712 | /** 713 | * Creates an <input></input> element in the DOM for text input. 714 | * Use .size() to set the display length of the box. 715 | * Appends to the container node if one is specified, otherwise 716 | * appends to body. 717 | * 718 | * @method createInput 719 | * @param {Number} [value] default value of the input box 720 | * @return {Object/p5.Element} pointer to p5.Element holding created node 721 | * @example 722 | *
723 | * function setup(){ 724 | * var inp = createInput(''); 725 | * inp.input(myInputEvent); 726 | * } 727 | * 728 | * function myInputEvent(){ 729 | * console.log('you are typing: ', this.value()); 730 | * } 731 | * 732 | *
733 | */ 734 | p5.prototype.createInput = function(value) { 735 | var elt = document.createElement('input'); 736 | elt.type = 'text'; 737 | if (value) elt.value = value; 738 | return addElement(elt, this); 739 | }; 740 | 741 | /** 742 | * Creates an <input></input> element in the DOM of type 'file'. 743 | * This allows users to select local files for use in a sketch. 744 | * 745 | * @method createFileInput 746 | * @param {Function} [callback] callback function for when a file loaded 747 | * @param {String} [multiple] optional to allow multiple files selected 748 | * @return {Object/p5.Element} pointer to p5.Element holding created DOM element 749 | */ 750 | p5.prototype.createFileInput = function(callback, multiple) { 751 | 752 | // Is the file stuff supported? 753 | if (window.File && window.FileReader && window.FileList && window.Blob) { 754 | // Yup, we're ok and make an input file selector 755 | var elt = document.createElement('input'); 756 | elt.type = 'file'; 757 | 758 | // If we get a second argument that evaluates to true 759 | // then we are looking for multiple files 760 | if (multiple) { 761 | // Anything gets the job done 762 | elt.multiple = 'multiple'; 763 | } 764 | 765 | // Function to handle when a file is selected 766 | // We're simplifying life and assuming that we always 767 | // want to load every selected file 768 | function handleFileSelect(evt) { 769 | // These are the files 770 | var files = evt.target.files; 771 | // Load each one and trigger a callback 772 | for (var i = 0; i < files.length; i++) { 773 | var f = files[i]; 774 | var reader = new FileReader(); 775 | function makeLoader(theFile) { 776 | // Making a p5.File object 777 | var p5file = new p5.File(theFile); 778 | return function(e) { 779 | p5file.data = e.target.result; 780 | callback(p5file); 781 | }; 782 | }; 783 | reader.onload = makeLoader(f); 784 | 785 | // Text or data? 786 | // This should likely be improved 787 | if (f.type.indexOf('text') > -1) { 788 | reader.readAsText(f); 789 | } else { 790 | reader.readAsDataURL(f); 791 | } 792 | } 793 | } 794 | 795 | // Now let's handle when a file was selected 796 | elt.addEventListener('change', handleFileSelect, false); 797 | return addElement(elt, this); 798 | } else { 799 | console.log('The File APIs are not fully supported in this browser. Cannot create element.'); 800 | } 801 | }; 802 | 803 | 804 | /** VIDEO STUFF **/ 805 | 806 | function createMedia(pInst, type, src, callback) { 807 | var elt = document.createElement(type); 808 | 809 | // allow src to be empty 810 | var src = src || ''; 811 | if (typeof src === 'string') { 812 | src = [src]; 813 | } 814 | for (var i=0; i