Skip to content

Instantly share code, notes, and snippets.

@bsturdivan
Created October 15, 2012 21:29
Show Gist options
  • Save bsturdivan/3895654 to your computer and use it in GitHub Desktop.
Save bsturdivan/3895654 to your computer and use it in GitHub Desktop.
mediaResize - Commented
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