Skip to content

Commit

Permalink
hopefully fixes merge issues to v0.2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
futuremarc committed Jun 28, 2015
1 parent 3ea98cf commit 2073220
Showing 1 changed file with 292 additions and 2 deletions.
294 changes: 292 additions & 2 deletions lib/addons/p5.dom.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! p5.dom.js v0.2.0 February 2, 2015 */
/*! p5.dom.js v0.2.2 May 30, 2015 */
/**
* <p>The web is much more than just canvas and p5.dom makes it easy to interact
* with other HTML5 objects, including text, hyperlink, image, input, video,
Expand Down Expand Up @@ -997,6 +997,12 @@
*/
p5.MediaElement = function(elt, pInst) {
p5.Element.call(this, elt, pInst);


this._prevTime = 0;
this._cueIDCounter = 0;
this._cues = [];

};
p5.MediaElement.prototype = Object.create(p5.Element.prototype);

Expand All @@ -1013,7 +1019,14 @@
if (this.elt.currentTime === this.elt.duration) {
this.elt.currentTime = 0;
}
this.elt.play();

if (this.elt.readyState > 1) {
this.elt.play();
} else {
// in Chrome, playback cannot resume after being stopped and must reload
this.elt.load();
this.elt.play();
}
return this;
};

Expand Down Expand Up @@ -1148,4 +1161,281 @@
p5.prototype.set.call(this, x, y, imgOrCol);
}
};

/*** CONNECT TO WEB AUDIO API / p5.sound.js ***/

/**
* Send the audio output of this element to a specified audioNode or
* p5.sound object. If no element is provided, connects to p5's master
* output. That connection is established when this method is first called.
* All connections are removed by the .disconnect() method.
*
* This method is meant to be used with the p5.sound.js addon library.
*
* @method connect
* @param {AudioNode|p5.sound object} audioNode AudioNode from the Web
* Audio API, or an object from the
* p5.sound library
*/
p5.MediaElement.prototype.connect = function(obj) {
var audioContext, masterOutput;

// if p5.sound exists, same audio context
if (typeof p5.prototype.getAudioContext === 'function') {
audioContext = p5.prototype.getAudioContext();
masterOutput = p5.soundOut.input;
} else {
try {
audioContext = obj.context;
masterOutput = audioContext.destination
} catch(e) {
throw 'connect() is meant to be used with Web Audio API or p5.sound.js'
}
}

// create a Web Audio MediaElementAudioSourceNode if none already exists
if (!this.audioSourceNode) {
this.audioSourceNode = audioContext.createMediaElementSource(this.elt);

// connect to master output when this method is first called
this.audioSourceNode.connect(masterOutput);
}

// connect to object if provided
if (obj) {
if (obj.input) {
this.audioSourceNode.connect(obj.input);
} else {
this.audioSourceNode.connect(obj);
}
}

// otherwise connect to master output of p5.sound / AudioContext
else {
this.audioSourceNode.connect(masterOutput);
}

};

/**
* Disconnect all Web Audio routing, including to master output.
* This is useful if you want to re-route the output through
* audio effects, for example.
*
* @method disconnect
*/
p5.MediaElement.prototype.disconnect = function() {
if (this.audioSourceNode) {
this.audioSourceNode.disconnect();
} else {
throw 'nothing to disconnect';
}
};


/*** SHOW / HIDE CONTROLS ***/

/**
* Show the default MediaElement controls, as determined by the web browser.
*
* @method showControls
*/
p5.MediaElement.prototype.showControls = function() {
// must set style for the element to show on the page
this.elt.style['text-align'] = 'inherit';
this.elt.controls = true;
};

/**
* Hide the default mediaElement controls.
*
* @method hideControls
*/
p5.MediaElement.prototype.hideControls = function() {
this.elt.controls = false;
};


/*** SCHEDULE EVENTS ***/

/**
* Schedule events to trigger every time a MediaElement
* (audio/video) reaches a playback cue point.
*
* Accepts a callback function, a time (in seconds) at which to trigger
* the callback, and an optional parameter for the callback.
*
* Time will be passed as the first parameter to the callback function,
* and param will be the second parameter.
*
*
* @method addCue
* @param {Number} time Time in seconds, relative to this media
* element's playback. For example, to trigger
* an event every time playback reaches two
* seconds, pass in the number 2. This will be
* passed as the first parameter to
* the callback function.
* @param {Function} callback Name of a function that will be
* called at the given time. The callback will
* receive time and (optionally) param as its
* two parameters.
* @param {Object} [value] An object to be passed as the
* second parameter to the
* callback function.
* @return {Number} id ID of this cue,
* useful for removeCue(id)
* @example
* <div><code>
* function setup() {
* background(255,255,255);
*
* audioEl = createAudio('assets/beat.mp3');
* audioEl.showControls();
*
* // schedule three calls to changeBackground
* audioEl.addCue(0.5, changeBackground, color(255,0,0) );
* audioEl.addCue(1.0, changeBackground, color(0,255,0) );
* audioEl.addCue(2.5, changeBackground, color(0,0,255) );
* audioEl.addCue(3.0, changeBackground, color(0,255,255) );
* audioEl.addCue(4.2, changeBackground, color(255,255,0) );
* audioEl.addCue(5.0, changeBackground, color(255,255,0) );
* }
*
* function changeBackground(val) {
* background(val);
* }
* </code></div>
*/
p5.MediaElement.prototype.addCue = function(time, callback, val) {
var id = this._cueIDCounter++;

var cue = new Cue(callback, time, id, val);
this._cues.push(cue);

if (!this.elt.ontimeupdate) {
this.elt.ontimeupdate = this._onTimeUpdate.bind(this);
}

return id;
};

/**
* Remove a callback based on its ID. The ID is returned by the
* addCue method.
*
* @method removeCue
* @param {Number} id ID of the cue, as returned by addCue
*/
p5.MediaElement.prototype.removeCue = function(id) {
for (var i = 0; i < this._cues.length; i++) {
var cue = this._cues[i];
if (cue.id === id) {
this.cues.splice(i, 1);
}
}

if (this._cues.length === 0) {
this.elt.ontimeupdate = null
}
};

/**
* Remove all of the callbacks that had originally been scheduled
* via the addCue method.
*
* @method clearCues
*/
p5.MediaElement.prototype.clearCues = function() {
this._cues = [];
this.elt.ontimeupdate = null;
};

// private method that checks for cues to be fired if events
// have been scheduled using addCue(callback, time).
p5.MediaElement.prototype._onTimeUpdate = function() {
var playbackTime = this.time();

for (var i = 0 ; i < this._cues.length; i++) {
var callbackTime = this._cues[i].time;
var val = this._cues[i].val;


if (this._prevTime < callbackTime && callbackTime <= playbackTime) {

// pass the scheduled callbackTime as parameter to the callback
this._cues[i].callback(val);
}

}

this._prevTime = playbackTime;
};


// Cue inspired by JavaScript setTimeout, and the
// Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org
var Cue = function(callback, time, id, val) {
this.callback = callback;
this.time = time;
this.id = id;
this.val = val;
};

// =============================================================================
// p5.File
// =============================================================================


/**
* Base class for a file
* Using this for createFileInput
*
* @class p5.File
* @constructor
* @param {File} file File that is wrapped
* @param {Object} [pInst] pointer to p5 instance
*/
p5.File = function(file, pInst) {
/**
* Underlying File object. All normal File methods can be called on this.
*
* @property file
*/
this.file = file;

this._pInst = pInst;

// Splitting out the file type into two components
// This makes determining if image or text etc simpler
var typeList = file.type.split('/');
/**
* File type (image, text, etc.)
*
* @property type
*/
this.type = typeList[0];
/**
* File subtype (usually the file extension jpg, png, xml, etc.)
*
* @property subtype
*/
this.subtype = typeList[1];
/**
* File name
*
* @property name
*/
this.name = file.name;
/**
* File size
*
* @property size
*/
this.size = file.size;

// Data not loaded yet
this.data = undefined;
};

}));

0 comments on commit 2073220

Please sign in to comment.