imgProcessingProjects/clmtracker/libs/p5.dom.js
clmtracker/libs/p5.dom.jsRaw
1/*! p5.dom.js v0.1.5 November 7, 2014 */
2/**
3 * <p>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.</p>
6 * <p>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 * <a href="https://github.com/lmccart/p5.js/wiki/Beyond-the-canvas">
9 * beyond the canvas tutorial</a> for a full overview of how this addon works.
10 *
11 * <p>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 * <a href="http://p5js.org/libraries/#using-a-library">using a library</a>
15 * section for information on how to include this library. p5.dom comes with
16 * <a href="http://p5js.org/download">p5 complete</a> or you can download the single file
17 * <a href="https://raw.githubusercontent.com/lmccart/p5.js/master/lib/addons/p5.dom.js">
18 * here</a>.</p>
19 * <p>See <a href="https://github.com/lmccart/p5.js/wiki/Beyond-the-canvas">tutorial: beyond the canvas]</a>
20 * for more info on how to use this libary.</a>
21 *
22 * @module p5.dom
23 * @submodule p5.dom
24 * @for p5.dom
25 * @main
26 */
27
28var p5DOM = (function(){
29
30// =============================================================================
31// p5 additions
32// =============================================================================
33
34 /**
35 * Searches the page for an element with given ID and returns it as
36 * a p5.Element. The DOM node itself can be accessed with .elt.
37 * Returns null if none found.
38 *
39 * @method getElement
40 * @param {String} id id of element to search for
41 * @return {Object/p5.Element|Null} p5.Element containing node found
42 */
43 p5.prototype.getElement = function (e) {
44 var res = document.getElementById(e);
45 if (res) {
46 return new p5.Element(res);
47 } else {
48 return null;
49 }
50 };
51
52 /**
53 * Searches the page for elements with given class and returns an
54 * array of p5.Elements. The DOM nodes themselves can be accessed
55 * with .elt. Returns an empty array if none found.
56 *
57 * @method getElements
58 * @param {String} class class name of elements to search for
59 * @return {Array} array of p5.Element wrapped nodes found
60 */
61 p5.prototype.getElements = function (e) {
62 var arr = [];
63 var res = document.getElementsByClassName(e);
64 if (res) {
65 for (var j = 0; j < res.length; j++) {
66 var obj = new p5.Element(res[j]);
67 arr.push(obj);
68 }
69 }
70 return arr;
71 };
72
73 /**
74 * Removes all elements created by p5, except any canvas / graphics
75 * elements created by createCanvas or createGraphics.
76 * Event handlers are removed, and element is removed from the DOM.
77 * @method removeElements
78 * @example
79 * <div class='norender'><code>
80 * function setup() {
81 * createCanvas(100, 100);
82 * createDiv('this is some text');
83 * createP('this is a paragraph');
84 * }
85 * function mousePressed() {
86 * removeElements(); // this will remove the div and p, not canvas
87 * }
88 * </code></div>
89 *
90 */
91 p5.prototype.removeElements = function (e) {
92 for (var i=0; i<this._elements.length; i++) {
93 if (!(this._elements[i].elt instanceof HTMLCanvasElement)) {
94 this._elements[i].remove();
95 }
96 }
97 };
98
99 /**
100 * Helpers for create methods.
101 */
102 function addElement(elt, pInst, media) {
103 var node = pInst._userNode ? pInst._userNode : document.body;
104 node.appendChild(elt);
105 var c = media ? new p5.MediaElement(elt) : new p5.Element(elt);
106 pInst._elements.push(c);
107 return c;
108 }
109
110 /**
111 * Creates a <div></div> element in the DOM with given inner HTML.
112 * Appends to the container node if one is specified, otherwise
113 * appends to body.
114 *
115 * @method createDiv
116 * @param {String} html inner HTML for element created
117 * @return {Object/p5.Element} pointer to p5.Element holding created
118 * node
119 */
120
121 /**
122 * Creates a <p></p> element in the DOM with given inner HTML. Used
123 * for paragraph length text.
124 * Appends to the container node if one is specified, otherwise
125 * appends to body.
126 *
127 * @method createP
128 * @param {String} html inner HTML for element created
129 * @return {Object/p5.Element} pointer to p5.Element holding created
130 * node
131 */
132
133 /**
134 * Creates a <span></span> element in the DOM with given inner HTML.
135 * Appends to the container node if one is specified, otherwise
136 * appends to body.
137 *
138 * @method createSpan
139 * @param {String} html inner HTML for element created
140 * @return {Object/p5.Element} pointer to p5.Element holding created
141 * node
142 */
143 var tags = ['div', 'p', 'span'];
144 tags.forEach(function(tag) {
145 var method = 'create' + tag.charAt(0).toUpperCase() + tag.slice(1);
146 p5.prototype[method] = function(html) {
147 var elt = document.createElement(tag);
148 elt.innerHTML = html;
149 return addElement(elt, this);
150 }
151 });
152
153 /**
154 * Creates an <img /> element in the DOM with given src and
155 * alternate text.
156 * Appends to the container node if one is specified, otherwise
157 * appends to body.
158 *
159 * @method createImg
160 * @param {String} src src path or url for image
161 * @param {String} alt alternate text to be used if image does not
162 * load
163 * @return {Object/p5.Element} pointer to p5.Element holding created
164 * node
165 */
166 p5.prototype.createImg = function(src, alt) {
167 var elt = document.createElement('img');
168 elt.src = src;
169 if (typeof alt !== 'undefined') {
170 elt.alt = alt;
171 }
172 return addElement(elt, this);
173 };
174
175
176 /**
177 * Creates an <a></a> element in the DOM for including a hyperlink.
178 * Appends to the container node if one is specified, otherwise
179 * appends to body.
180 *
181 * @method createA
182 * @param {String} href url of page to link to
183 * @param {String} html inner html of link element to display
184 * @param {String} [target] target where new link should open,
185 * could be _blank, _self, _parent, _top.
186 * @return {Object/p5.Element} pointer to p5.Element holding created
187 * node
188 */
189 p5.prototype.createA = function(href, html, target) {
190 var elt = document.createElement('a');
191 elt.href = href;
192 elt.innerHTML = html;
193 if (target) elt.target = target;
194 return addElement(elt, this);
195 };
196
197 /** INPUT **/
198
199
200 /**
201 * Creates a slider <input></input> element in the DOM.
202 * Use .size() to set the display length of the slider.
203 * Appends to the container node if one is specified, otherwise
204 * appends to body.
205 *
206 * @method createSlider
207 * @param {Number} min minimum value of the slider
208 * @param {Number} max maximum value of the slider
209 * @param {Number} [value] default value of the slider
210 * @return {Object/p5.Element} pointer to p5.Element holding created
211 * node
212 */
213 p5.prototype.createSlider = function(min, max, value) {
214 var elt = document.createElement('input');
215 elt.type = 'range';
216 elt.min = min;
217 elt.max = max;
218 if (value) elt.value = value;
219 return addElement(elt, this);
220 };
221
222 /**
223 * Creates a <button></button> element in the DOM.
224 * Use .size() to set the display size of the button.
225 * Use .mousePressed() to specify behavior on press.
226 * Appends to the container node if one is specified, otherwise
227 * appends to body.
228 *
229 * @method createButton
230 * @param {String} label label displayed on the button
231 * @param {String} [value] value of the button
232 * @return {Object/p5.Element} pointer to p5.Element holding created
233 * node
234 */
235 p5.prototype.createButton = function(label, value) {
236 var elt = document.createElement('button');
237 elt.innerHTML = label;
238 elt.value = value;
239 if (value) elt.value = value;
240 return addElement(elt, this);
241 };
242
243 /**
244 * Creates an <input></input> element in the DOM for text input.
245 * Use .size() to set the display length of the box.
246 * Appends to the container node if one is specified, otherwise
247 * appends to body.
248 *
249 * @method createInput
250 * @param {Number} [value] default value of the input box
251 * @return {Object/p5.Element} pointer to p5.Element holding created
252 * node
253 */
254 p5.prototype.createInput = function(value) {
255 var elt = document.createElement('input');
256 elt.type = 'text';
257 if (value) elt.value = value;
258 return addElement(elt, this);
259 };
260
261 /** VIDEO STUFF **/
262
263 function createMedia(pInst, type, src, callback) {
264 var elt = document.createElement(type);
265 if (typeof src === 'string') {
266 src = [src];
267 }
268 for (var i=0; i<src.length; i++) {
269 var source = document.createElement('source');
270 source.src = src[i];
271 elt.appendChild(source);
272 }
273 if (typeof callback !== 'undefined') {
274 elt.addEventListener('canplaythrough', function() {
275 callback();
276 });
277 }
278
279 var c = addElement(elt, pInst, true);
280 c.loadedmetadata = false;
281 // set width and height onload metadata
282 elt.addEventListener('loadedmetadata', function() {
283 c.width = elt.videoWidth;
284 c.height = elt.videoHeight;
285 c.loadedmetadata = true;
286 });
287
288 return c;
289 }
290 /**
291 * Creates an HTML5 <video> element in the DOM for simple playback
292 * of audio/video. Shown by default, can be hidden with .hide()
293 * and drawn into canvas using video(). Appends to the container
294 * node if one is specified, otherwise appends to body. The first parameter
295 * can be either a single string path to a video file, or an array of string
296 * paths to different formats of the same video. This is useful for ensuring
297 * that your video can play across different browsers, as each supports
298 * different formats. See <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats">this
299 * page for further information about supported formats.
300 *
301 * @method createVideo
302 * @param {String|Array} src path to a video file, or array of paths for
303 * supporting different browsers
304 * @param {Object} [callback] callback function to be called upon
305 * 'canplaythrough' event fire, that is, when the
306 * browser can play the media, and estimates that
307 * enough data has been loaded to play the media
308 * up to its end without having to stop for
309 * further buffering of content
310 * @return {Object/p5.Element} pointer to video p5.Element
311 */
312 p5.prototype.createVideo = function(src, callback) {
313 return createMedia(this, 'video', src, callback);
314 };
315
316 /** AUDIO STUFF **/
317
318 /**
319 * Creates a hidden HTML5 <audio> element in the DOM for simple audio
320 * playback. Appends to the container node if one is specified,
321 * otherwise appends to body. The first parameter
322 * can be either a single string path to a audio file, or an array of string
323 * paths to different formats of the same audio. This is useful for ensuring
324 * that your audio can play across different browsers, as each supports
325 * different formats. See <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats">this
326 * page for further information about supported formats.
327 *
328 * @method createAudio
329 * @param {String|Array} src path to an audio file, or array of paths for
330 * supporting different browsers
331 * @param {Object} [callback] callback function to be called upon
332 * 'canplaythrough' event fire, that is, when the
333 * browser can play the media, and estimates that
334 * enough data has been loaded to play the media
335 * up to its end without having to stop for
336 * further buffering of content
337 * @return {Object/p5.Element} pointer to audio p5.Element
338 */
339 p5.prototype.createAudio = function(src, callback) {
340 return createMedia(this, 'audio', src, callback);
341 };
342
343
344 /** CAMERA STUFF **/
345
346 p5.prototype.VIDEO = 'video';
347 p5.prototype.AUDIO = 'audio';
348
349 navigator.getUserMedia = navigator.getUserMedia ||
350 navigator.webkitGetUserMedia ||
351 navigator.mozGetUserMedia ||
352 navigator.msGetUserMedia;
353
354 /**
355 * Creates a new <video> element that contains the audio/video feed
356 * from a webcam. This can be drawn onto the canvas using video().
357 *
358 * @method createCapture
359 * @param {String/Constant} type type of capture, either VIDEO or
360 * AUDIO if none specified, default both
361 * @return {Object/p5.Element} capture video p5.Element
362 */
363 p5.prototype.createCapture = function(type) {
364 var useVideo, useAudio;
365 if (!type) {
366 useVideo = true;
367 useAudio = true;
368 } else if (type === p5.prototype.VIDEO) {
369 useVideo = true;
370 } else if (type === p5.prototype.AUDIO) {
371 useAudio = true;
372 }
373
374 if (navigator.getUserMedia) {
375 var elt = document.createElement('video');
376 navigator.getUserMedia({video: useVideo, audio: useAudio}, function(stream) {
377 elt.src = window.URL.createObjectURL(stream);
378 elt.play();
379 }, function(e) { console.log(e); });
380 } else {
381 throw 'getUserMedia not supported in this browser';
382 }
383 return addElement(elt, this);
384 };
385
386 /**
387 * Creates element with given tag in the DOM with given content.
388 * Appends to the container node if one is specified, otherwise
389 * appends to body.
390 *
391 * @method createElement
392 * @param {String} tag tag for the new element
393 * @param {String} [content] html content to be inserted into the element
394 * @return {Object/p5.Element} pointer to p5.Element holding created
395 * node
396 */
397 p5.prototype.createElement = function(tag, content) {
398 var elt = document.createElement(tag);
399 if (typeof content !== 'undefined') {
400 elt.innerHTML = content;
401 }
402 return addElement(elt, this);
403 };
404
405
406// =============================================================================
407// p5.Element additions
408// =============================================================================
409 /**
410 *
411 * Adds specified class to the element.
412 *
413 * @for p5.Element
414 * @method addClass
415 * @param {String} class name of class to add
416 * @return {p5.Element}
417 */
418 p5.Element.prototype.addClass = function(c) {
419 if (this.elt.className) {
420 // PEND don't add class more than once
421 //var regex = new RegExp('[^a-zA-Z\d:]?'+c+'[^a-zA-Z\d:]?');
422 //if (this.elt.className.search(/[^a-zA-Z\d:]?hi[^a-zA-Z\d:]?/) === -1) {
423 this.elt.className = this.elt.className+' '+c;
424 //}
425 } else {
426 this.elt.className = c;
427 }
428 return this;
429 }
430
431 /**
432 *
433 * Removes specified class from the element.
434 *
435 * @method removeClass
436 * @param {String} class name of class to remove
437 * @return {p5.Element}
438 */
439 p5.Element.prototype.removeClass = function(c) {
440 var regex = new RegExp('(?:^|\\s)'+c+'(?!\\S)');
441 this.elt.className = this.elt.className.replace(regex, '');
442 this.elt.className = this.elt.className.replace(/^\s+|\s+$/g, ""); //prettify (optional)
443 return this;
444 }
445
446 /**
447 *
448 * Attaches the element as a child to the parent specified.
449 * Accepts either a string ID, DOM node, or p5.Element
450 *
451 * @method child
452 * @param {String|Object} child the ID, DOM node, or p5.Element
453 * to add to the current element
454 * @return {p5.Element}
455 * @example
456 * <div class='norender'><code>
457 * var div0 = createDiv('this is the parent');
458 * var div1 = createDiv('this is the child');
459 * div0.child(div1); // use p5.Element
460 * </code></div>
461 * <div class='norender'><code>
462 * var div0 = createDiv('this is the parent');
463 * var div1 = createDiv('this is the child');
464 * div1.id('apples');
465 * div0.child('apples'); // use id
466 * </code></div>
467 * <div class='norender'><code>
468 * var div0 = createDiv('this is the parent');
469 * var elt = document.getElementById('myChildDiv');
470 * div0.child(elt); // use element from page
471 * </code></div>
472 */
473 p5.Element.prototype.child = function(c) {
474 if (typeof c === 'string') {
475 c = document.getElementById(c);
476 } else if (c instanceof p5.Element) {
477 c = c.elt;
478 }
479 this.elt.appendChild(c);
480 return this;
481 };
482
483
484 /**
485 *
486 * If an argument is given, sets the inner HTML of the element,
487 * replacing any existing html. If no arguments are given, returns
488 * the inner HTML of the element.
489 *
490 * @for p5.Element
491 * @method html
492 * @param {String} [html] the HTML to be placed inside the element
493 * @return {p5.Element|String}
494 */
495 p5.Element.prototype.html = function(html) {
496 if (typeof html !== 'undefined') {
497 this.elt.innerHTML = html;
498 return this;
499 } else {
500 return this.elt.innerHTML;
501 }
502 };
503
504 /**
505 *
506 * Sets the position of the element relative to (0, 0) of the
507 * window. Essentially, sets position:absolute and left and top
508 * properties of style.
509 *
510 * @method position
511 * @param {Number} x x-position relative to upper left of window
512 * @param {Number} y y-position relative to upper left of window
513 * @return {p5.Element}
514 * @example
515 * <div><code class='norender'>
516 * function setup() {
517 * var cnv = createCanvas(100, 100);
518 * // positions canvas 50px to right and 100px
519 * // below upper left corner of the window
520 * cnv.position(50, 100);
521 * }
522 * </code></div>
523 */
524 p5.Element.prototype.position = function(x, y) {
525 this.elt.style.position = 'absolute';
526 this.elt.style.left = x+'px';
527 this.elt.style.top = y+'px';
528 return this;
529 };
530
531 /**
532 *
533 * Sets the given style (css) property of the element with the given value.
534 * If no value is specified, returns the value of the given property,
535 * or undefined if the property is not.
536 *
537 * @method style
538 * @param {String} property property to be set
539 * @param {String} [value] value to assign to property
540 * @return {String|p5.Element} value of property, if no value is specified
541 * or p5.Element
542 * @example
543 * <div><code class="norender">
544 * var myDiv = createDiv("I like pandas.");
545 * myDiv.style("color", "#ff0000");
546 * myDiv.style("font-size", "18px");
547 * </code></div>
548 */
549 p5.Element.prototype.style = function(prop, val) {
550 if (typeof val === 'undefined') {
551 var attrs = prop.split(';');
552 for (var i=0; i<attrs.length; i++) {
553 var parts = attrs[i].split(':');
554 if (parts[0] && parts[1]) {
555 this.elt.style[parts[0].trim()] = parts[1].trim();
556 }
557 }
558 console.log(this.elt.style)
559 } else {
560 this.elt.style[prop] = val;
561 }
562 return this;
563 };
564
565
566 /**
567 *
568 * Adds a new attribute or changes the value of an existing attribute
569 * on the specified element. If no value is specified, returns the
570 * value of the given attribute, or null if attribute is not set.
571 *
572 * @method attribute
573 * @param {String} attr attribute to set
574 * @param {String} [value] value to assign to attribute
575 * @return {String|p5.Element} value of attribute, if no value is
576 * specified or p5.Element
577 * @example
578 * <div class="norender"><code>
579 * var myDiv = createDiv("I like pandas.");
580 *myDiv.attribute("align", "center");
581 * </code></div>
582 */
583 p5.Element.prototype.attribute = function(attr, value) {
584 if (typeof value === 'undefined') {
585 return this.elt.getAttribute(attr);
586 } else {
587 this.elt.setAttribute(attr, value);
588 return this;
589 }
590 };
591
592
593 /**
594 * Either returns the value of the element if no arguments
595 * given, or sets the value of the element.
596 *
597 * @method value
598 * @param {String|Number} [value]
599 * @return {String|p5.Element} value of element, if no value is
600 * specified or p5.Element
601 */
602 p5.Element.prototype.value = function() {
603 if (arguments.length > 0) {
604 this.elt.value = arguments[0];
605 return this;
606 } else {
607 if (this.elt.type === 'range') {
608 return parseFloat(this.elt.value);
609 }
610 else return this.elt.value;
611 }
612 };
613
614 /**
615 *
616 * Shows the current element. Essentially, setting display:block for the style.
617 *
618 * @method show
619 * @return {p5.Element}
620 */
621 p5.Element.prototype.show = function() {
622 this.elt.style.display = 'block';
623 return this;
624 };
625
626 /**
627 * Hides the current element. Essentially, setting display:none for the style.
628 *
629 * @method hide
630 * @return {p5.Element}
631 */
632 p5.Element.prototype.hide = function() {
633 this.elt.style.display = 'none';
634 return this;
635 };
636
637 /**
638 *
639 * Sets the width and height of the element. AUTO can be used to
640 * only adjust one dimension.
641 *
642 * @method size
643 * @param {Number} w width of the element
644 * @param {Number} h height of the element
645 * @return {p5.Element}
646 */
647 p5.Element.prototype.size = function(w, h) {
648 var aW = w;
649 var aH = h;
650 var AUTO = p5.prototype.AUTO;
651
652 if (aW !== AUTO || aH !== AUTO) {
653 if (aW === AUTO) {
654 aW = h * this.elt.width / this.elt.height;
655 } else if (aH === AUTO) {
656 aH = w * this.elt.height / this.elt.width;
657 }
658 // set diff for cnv vs normal div
659 if (this.elt instanceof HTMLCanvasElement) {
660 var j = {};
661 var k = this.elt.getContext('2d');
662 for (var prop in k) {
663 j[prop] = k[prop];
664 }
665 this.elt.setAttribute('width', aW * this._pInst._pixelDensity);
666 this.elt.setAttribute('height', aH * this._pInst._pixelDensity);
667 this.elt.setAttribute('style', 'width:' + aW + 'px !important; height:' + aH + 'px !important;');
668 this._pInst.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);
669 for (var prop in j) {
670 this.elt.getContext('2d')[prop] = j[prop];
671 }
672 } else {
673 this.elt.style.width = aW+'px';
674 this.elt.style.height = aH+'px';
675 this.elt.width = aW;
676 this.elt.height = aH;
677 }
678 this.width = this.elt.offsetWidth;
679 this.height = this.elt.offsetHeight;
680 if (this._pInst) { // main canvas associated with p5 instance
681 if (this._pInst._curElement.elt === this.elt) {
682 this._pInst._setProperty('width', this.elt.offsetWidth);
683 this._pInst._setProperty('height', this.elt.offsetHeight);
684 }
685 }
686 }
687 return this;
688 };
689
690 /**
691 * Removes the element and deregisters all listeners.
692 * @method remove
693 * @example
694 * <div class='norender'><code>
695 * var myDiv = createDiv('this is some text');
696 * myDiv.remove();
697 * </code></div>
698 */
699 p5.Element.prototype.remove = function() {
700 // deregister events
701 for (var ev in this._events) {
702 this.elt.removeEventListener(ev, this._events[ev]);
703 }
704 if (this.elt.parentNode) {
705 this.elt.parentNode.removeChild(this.elt);
706 }
707 delete(this);
708 };
709
710
711
712// =============================================================================
713// p5.MediaElement additions
714// =============================================================================
715
716
717 /**
718 * Extends p5.Element to handle audio and video. In addition to the methods
719 * of p5.Element, it also contains methods for controlling media. It is not
720 * called directly, but p5.MediaElements are created by calling createVideo,
721 * createAudio, and createCapture.
722 *
723 * @class p5.MediaElement
724 * @constructor
725 * @param {String} elt DOM node that is wrapped
726 * @param {Object} [pInst] pointer to p5 instance
727 */
728 p5.MediaElement = function(elt, pInst) {
729 p5.Element.call(this, elt, pInst);
730 };
731 p5.MediaElement.prototype = Object.create(p5.Element.prototype);
732
733
734
735
736 /**
737 * Play an HTML5 media element.
738 *
739 * @method play
740 * @return {p5.Element}
741 */
742 p5.MediaElement.prototype.play = function() {
743 if (this.elt.currentTime === this.elt.duration) {
744 this.elt.currentTime = 0;
745 }
746 this.elt.play();
747 return this;
748 };
749
750 /**
751 * Stops an HTML5 media element (sets current time to zero).
752 *
753 * @method stop
754 * @return {p5.Element}
755 */
756 p5.MediaElement.prototype.stop = function() {
757 this.elt.pause();
758 this.elt.currentTime = 0;
759 return this;
760 };
761
762 /**
763 * Pauses an HTML5 media element.
764 *
765 * @method pause
766 * @return {p5.Element}
767 */
768 p5.MediaElement.prototype.pause = function() {
769 this.elt.pause();
770 return this;
771 };
772
773 /**
774 * Set 'loop' to true for an HTML5 media element, and starts playing.
775 *
776 * @method loop
777 * @return {p5.Element}
778 */
779 p5.MediaElement.prototype.loop = function() {
780 this.elt.setAttribute('loop', true);
781 this.play();
782 return this;
783 };
784 /**
785 * Set 'loop' to false for an HTML5 media element. Element will stop
786 * when it reaches the end.
787 *
788 * @method noLoop
789 * @return {p5.Element}
790 */
791 p5.MediaElement.prototype.noLoop = function() {
792 this.elt.setAttribute('loop', false);
793 return this;
794 };
795
796
797 /**
798 * Set HTML5 media element to autoplay or not.
799 *
800 * @method autoplay
801 * @param {Boolean} autoplay whether the element should autoplay
802 * @return {p5.Element}
803 */
804 p5.MediaElement.prototype.autoplay = function(val) {
805 this.elt.setAttribute('autoplay', val);
806 return this;
807 };
808
809 /**
810 * Sets volume for this HTML5 media element. If no argument is given,
811 * returns the current volume.
812 *
813 * @param {Number} [val] volume between 0.0 and 1.0
814 * @return {Number|p5.MediaElement} current volume or p5.MediaElement
815 * @method volume
816 */
817 p5.MediaElement.prototype.volume = function(val) {
818 if (typeof val === 'undefined') {
819 return this.elt.volume;
820 } else {
821 this.elt.volume = val;
822 }
823 };
824
825 /**
826 * If no arguments are given, returns the current time of the elmeent.
827 * If an argument is given the current time of the element is set to it.
828 *
829 * @method time
830 * @param {Number} [time] time to jump to (in seconds)
831 * @return {Number|p5.MediaElement} current time (in seconds)
832 * or p5.MediaElement
833 */
834 p5.MediaElement.prototype.time = function(val) {
835 if (typeof val === 'undefined') {
836 return this.elt.currentTime;
837 } else {
838 this.elt.currentTime = val;
839 }
840 };
841
842 /**
843 * Returns the duration of the HTML5 media element.
844 *
845 * @method duration
846 * @return {Number} duration
847 */
848 p5.MediaElement.prototype.duration = function() {
849 return this.elt.duration;
850 };
851 p5.MediaElement.prototype.pixels = [];
852 p5.MediaElement.prototype.loadPixels = function() {
853 if (this.loadedmetadata) { // wait for metadata for w/h
854 if (!this.canvas) {
855 this.canvas = document.createElement('canvas');
856 this.canvas.width = this.width;
857 this.canvas.height = this.height;
858 this.drawingContext = this.canvas.getContext('2d');
859 }
860 this.drawingContext.drawImage(this.elt, 0, 0);
861 p5.prototype.loadPixels.call(this);
862 }
863 return this;
864 }
865 p5.MediaElement.prototype.updatePixels = function(x, y, w, h){
866 if (this.loadedmetadata) { // wait for metadata
867 p5.prototype.updatePixels.call(this, x, y, w, h);
868 }
869 return this;
870 }
871 p5.MediaElement.prototype.get = function(x, y, w, h){
872 if (this.loadedmetadata) { // wait for metadata
873 return p5.prototype.get.call(this, x, y, w, h);
874 } else return [0, 0, 0, 255];
875 };
876 p5.MediaElement.prototype.set = function(x, y, imgOrCol){
877 if (this.loadedmetadata) { // wait for metadata
878 p5.prototype.set.call(this, x, y, imgOrCol);
879 }
880 };
881
882})();