Created
October 15, 2012 21:29
-
-
Save bsturdivan/3895654 to your computer and use it in GitHub Desktop.
mediaResize - Commented
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(['jquery', 'pkg.utils', 'plugins/widget'], function($, utils) { | |
/** | |
* Finds and resizes media elements in a document | |
* @param {array} mediaObjects | |
* @this - Block level element with child text nodes | |
* @extends cbsi.widget | |
* | |
* Examples: | |
* | |
* <div data-widget="mediaResize"> | |
* <iframe src="youtube.com"></iframe> | |
* <embed> | |
* </div> | |
* | |
*/ | |
$.widget("cbsi.mediaResize", $.cbsi.widget, { | |
options: { | |
mediaObjects: null // Optional predefined array of selectors | |
}, | |
// VARS | |
hasEvents: false, // Events have been added | |
selectors: [ | |
"iframe", | |
"object", | |
"embed" | |
], // Elements to resize | |
// DOM VARS | |
$mediaObjects: null, // Array of found selectors | |
$window: $(window), | |
/** | |
* Instantiate mediaResize | |
* @constructor | |
*/ | |
_create: function() { | |
var self = this; | |
this.mediaObjects = self.options.mediaObjects || this.element.find(this.selectors.join(',')); // Predefined selectors or array of found selectors in the document | |
this.resizeMedia(this.mediaObjects); | |
this._addEvents(); | |
}, | |
/** | |
* Attach all events necessary within the widget | |
* @private | |
*/ | |
_addEvents: function() { | |
if(this.hasEvents) { | |
return; | |
} | |
this.hasEvents = true; | |
// Rerun resizeMedia() on orientation change to account for the new window width | |
this.$window.on('orientationchange.mediaResize', function(e) { | |
self.resizeMedia(this.mediaObjects); | |
}); | |
}, | |
/** | |
* Unbind all events attached within the widget | |
* @private | |
*/ | |
_removeEvents: function() { | |
this.hasEvents = false; | |
this.$window.off('.mediaResize'); | |
}, | |
/** | |
* Resizes media elements in a document | |
* @public | |
* @param {array} mediaObjects - array of elements to be resized | |
*/ | |
resizeMedia: function(mediaObjects) { | |
var winWidth = $(window).width(), | |
numVideos = mediaObjects.length, | |
container, // div to wrap mediaObject | |
aspectRatio, // aspect ratio of the mediaObject | |
originalVideoWidth, // original mediaObject width | |
originalVideoHeight, // original mediaObject height | |
bodyPos, // position in document of mediaObject | |
newEl; // Cloned mediaObject | |
// Return flase if no mediaObjects exist | |
if(numVideos < 1) { return false; } | |
// Loop over mediaObjects, (backward loop tested to be faster) | |
for(;numVideos -- > 0;) { | |
originalVideoWidth = mediaObjects[numVideos].getAttribute('width'); | |
// Exit iteration if window is wider than mediaObject | |
if(winWidth > originalVideoWidth) { | |
continue; | |
} | |
originalVideoHeight = mediaObjects[numVideos].getAttribute('height'); | |
aspectRatio = originalVideoHeight / originalVideoWidth; | |
bodyPos = mediaObjects[numVideos].parentNode; | |
newEl = $(mediaObjects[numVideos].cloneNode(false)); // clone mediaObject to avoid page repaint | |
container = $('<div/>').css({ | |
padding: 0, | |
position: 'relative', | |
width: '100%' | |
}); // create and set styles of container div | |
// Set padding-top to aspect ratio as % to give div height | |
container.css({ paddingTop: (aspectRatio * 100)+"%" }); | |
newEl.css({ | |
height: '100%', | |
left: 0, | |
maxHeight: originalVideoHeight+'px', | |
maxWidth: originalVideoWidth+'px', | |
position: 'absolute', | |
top: 0, | |
width: '100%' | |
}).removeAttr('height').removeAttr('width'); // Remove original height/width attributes from mediaObject | |
container.html(newEl); // append manipulated mediaObject as child of container | |
// replace original mediaObject with container -> newEl | |
bodyPos.replaceChild(container.get(0), mediaObjects[numVideos]); | |
container = null; // Zero out contain for next iteration | |
} | |
}, | |
/** | |
* Unbind all events and uninstantiate the widget | |
* @public | |
*/ | |
destroy: function() { | |
this._removeEvents(); | |
$.Widget.prototype.destroy.call(this); | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment