Skip to content

Instantly share code, notes, and snippets.

@tylersticka
Last active December 19, 2015 14:09
Show Gist options
  • Save tylersticka/5967626 to your computer and use it in GitHub Desktop.
Save tylersticka/5967626 to your computer and use it in GitHub Desktop.
/**
* fitvids.js is awesome but kind of dependent on pretty
* ideal and predictable markup. Unfortunately, a lot of
* services and sites seem to break it.
*
* This is a dirtier but more forgiving spin on the same
* idea. It is probably worse, but it works.
*
* https://gist.github.com/tylersticka/5967626
*/
(function($, window, undef){
var defaults = {
selectors: [
"iframe[src*='youtube.com']",
"iframe[src*='vimeo.com']"
],
resizeEventDelay: 100,
ratioAttr: "fitstuff-ratio",
width: '100%',
ratio: null,
triggers: {
prep: "fitstuff.prep"
}
};
function FitStuff (el, options) {
this.$el = $(el);
this.init(options);
}
FitStuff.prototype = {
init: function (options) {
// Set up proxies
this.prepItemsProxy = $.proxy(this.prepItems, this);
this.setItemRatioProxy = $.proxy(this.setItemRatio, this);
this.resizeItemsProxy = $.proxy(this.resizeItems, this);
this.resizeItemProxy = $.proxy(this.resizeItem, this);
this.resizeEventProxy = $.proxy(this.resizeEvent, this);
// Options
this.options = $.extend(true, {}, defaults, options);
this.ratioAttr = 'data-' + this.options.ratioAttr;
this.selectors = this.options.selectors;
if (this.options.customSelector)
this.selectors.push(this.options.customSelector);
this.selector = this.selectors.join(', ');
// Prep items
this.prepItems();
// Bind events
this.$el.on(this.options.triggers.prep, this.prepItemsProxy);
$(window).on('resize', this.resizeEventProxy);
},
prepItems: function () {
var $items, $newItems;
$items = this.$el.find(this.selector);
$newItems = (this.$items == undef) ? $items : $items.filter(':not([' + this.ratioAttr + '])');
this.$items = $items;
if (this.options.ratio) {
$newItems.attr(this.ratioAttr, this.options.ratio);
} else {
$newItems.each(this.setItemRatioProxy);
}
if (this.options.width)
$newItems.css('width', this.options.width);
this.resizeItems();
},
setItemRatio: function (index, el) {
var $item = $(el)
, w = $item.attr('width') || $item.width()
, h = $item.attr('height') || $item.height()
, ratio = w / h;
$item.attr(this.ratioAttr, ratio);
},
resizeItems: function () {
this.$items.each(this.resizeItemProxy);
},
resizeItem: function (index, el) {
var $item = $(el)
, ratio = $item.attr(this.ratioAttr)
, w = $item.width()
, h = $item.height();
if (ratio != w / h) {
// original height / original width x new width = new height
$item.css('height', (h / (h * ratio) * w) + 'px');
}
},
resizeEvent: function () {
if (this.timeout)
clearTimeout(this.timeout);
this.timeout = setTimeout(this.resizeItemsProxy, this.options.resizeEventDelay);
}
};
$.fn.fitStuff = function (options) {
return this.each(function(){
new FitStuff(this, options);
});
};
})(jQuery, window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment