File: D:/HostingSpaces/SBogers10/keystud.komma-mediadesign.nl/wwwroot/public/js/ke_030102_flexgrid.js
/**
* Created by Komma Mediadesign.
* Author: mike
* Date: 7/29/13
*/
(function($){
// Dashboard plugin
$.flexgrid = function(element, options)
{
// Set root
var t = this;
// Set default values
var defaults = {
prefix : 'ke0301_',
speed : 800,
extra : 3, // extra li's
minRatio : 1,
maxRatio : 16/9
};
var $el = $(element);
// Keep information like columns, rows e.d.
t.data = {};
t.delay = 0;
var lastNumCol = null;
// Streamers
var streamers = [
'Horses for a <strong>changing course</strong>',
'High Jump IQ'];
t.init = function()
{
// Extend the defaults with options, save in settings
t.settings = $.extend({}, defaults, options);
// Number of items
t.num = $el.children().size();
//build();
t.lastNumCol = t.data.cols;
};
t.resize = function()
{
t.data.emp = 0;
$el.children('empty').remove();
calculate();
// check if number of columns switched
if(browserName == 'IE' && majorVersion <= 8)
{
$el.children().css({ position: 'relative',float: 'left' });
$el.children('.cta').css({ width: t.data.imgW + 'px', height: t.data.imgH + 'px' });
}
else
{
if(t.data.cols != lastNumCol)
{
rebuild();
lastNumCol = t.data.cols;
position();
}
else
{
position();
}
}
$el.height(t.data.imgH * t.data.rows);
$el.children().not('.clear').css({ width: t.data.imgW + 'px', height: t.data.imgH + 'px' });
$el.children().eq(0).css({ width: t.data.imgW*2 + 'px', height: t.data.imgH*2 + 'px' });
var sw = $('.streamer').attr('data-w'); // streamer width
$('.streamer').css({ width: t.data.imgW*sw + 'px', height: t.data.imgH + 'px' });
};
var calculate = function()
{
/* FLEXGRID;
* Thumbsratio need to be at least 1 / 1 and max 16 / 9
* List Needs to be at least full screen (or longer)
*/
// IE CATCH
if(browserName == 'IE' && majorVersion <= 8)
{
//t.data = { cols : cols, rows : rows, imgW : imgW, imgH : imgH, ratio : ratio, emp : empty };
var cols = 4;
var rows = Math.ceil((t.num+3) / cols);
var imgW = 251;
var ratio = 4/3;
var imgH = imgW / ratio;
var empty = 0;
}
else
{
// #1 Calculation process
var complete = false;
var ignore = [];
var extraEmpty = 0;
while( ! complete)
{
var cols = false;
var empty = extraEmpty;
// Search for the right number of columns, add one empty block if nothing found.
while( ! cols)
{
// Checks how many columns give an optimal view
cols = getFlexCols(empty,ignore);
if(! cols) empty++;
}
var rows = (t.num + empty + 3) / cols; // 3 extra for first large image
var imgW = Math.round($el.width()/cols);
var ratio = false;
for(var r=rows;r>0;r--)
{
if( ! ratio )
{
// Check if we can create a optimal ratio with this amount of rows.
var imgH = Math.round($el.height()/r);
if( (imgW/imgH > t.settings.minRatio) && (imgW/imgH < t.settings.maxRatio) )
{
ratio = imgW/imgH;
}
}
}
if(ratio)
{
//exit while loop
complete = true;
}
// If no perfect ratio found, ignore this number of columns in next search
if( ! complete)
{
ignore.push(cols);
// if ignored everything, and nothing found, add empty
if(ignore.length == 2)
{
extraEmpty++;
ignore = [];
}
}
}
}
t.data = { cols : cols, rows : rows, imgW : imgW, imgH : imgH, ratio : ratio, emp : empty };
};
// Calculate the best number of columns
var getFlexCols = function(empty,ignore)
{
var cols = [1];
var wSize = { w : window.innerWidth || document.documentElement.clientWidth, h : window.innerHeight || document.documentElement.clientHeight };
if(wSize.w > 2500)
{
cols = [7,6,5,4]; // Number of possible columns has to be the same in each width
}
else if(wSize.w > 1500)
{
cols = [7,6,5,4];
}
else if(wSize.w > 1000)
{
cols = [5,4,3,2];
}
else
{
cols = [2,3,4,5];
}
var found = false;
for(var i=0;i<cols.length;i++)
{
if(jQuery.inArray(cols[i], ignore) == -1) // if not in "ignore" array
{
if ( ! found)
{
var total = t.num + empty + 3; // 3 for first photo, + 1 for streamer ()
var rest = total % cols[i];
if(rest == 0) found = cols[i];
}
}
}
if(found) return found;
return false;
};
var build = function()
{
// Calculate sizes
var imgRatio = t.data.ratio;
var imgHeight = ($el.width() / t.data.cols) / imgRatio;
var pSize = { w : $el.width(), h : t.data.rows * imgHeight };
var w = pSize.w / t.data.cols;
var h = pSize.h / t.data.rows;
// Set size of parent
$el.height(imgHeight * t.data.rows);
// Set size of all images
$el.children().not('.clear').css({ width: w + 'px', height: h + 'px' });
// First image is twice as big
$el.children().eq(0).css({ width: w*2 + 'px', height: h*2 + 'px' });
// Do we need a streamer and / or empty div
if(t.data.emp > 0)
{
var index = Math.floor(Math.random() * streamers.length);
var $newStreamer = $('<li class="streamer"><span class="balance valign"></span><span class="inner valign">‘' + streamers[index] + '’</span></li>');
if(t.data.emp == 1)
{
// Add a single Streamer
$newStreamer.css({ width: w + 'px', height: h + 'px' });
$newStreamer.attr('data-w',1);
$el.children().eq(0).after($newStreamer);
// Lower empty
t.data.emp --;
}
if(t.data.emp >= 2)
{
// Add a double Streamer
$newStreamer.css({ width: (w*2) + 'px', height: h + 'px' });
$newStreamer.attr('data-w',2);
$el.children().eq(0).after($newStreamer);
// Lower empty
t.data.emp -= 2;
}
// Fill left over with empty divs
for(var i=0;i< t.data.emp;i++)
{
/*
var pos = Math.round(Math.random() * t.num);
if(pos < 1) pos = 1;
if(pos >= t.num) pos = t.num-1;
*/
// $el.children().eq(t.num).before('<li class="empty"></li>');
// t.num++;
}
$el.children('.empty').css({ width: w + 'px', height: h + 'px' });
}
/*
var $streamer = $el.children('.streamer');
// Cut Streamer
var clipBoard = $streamer.html();
$streamer.remove();
var $newStreamer = $('<li class="streamer">' + clipBoard + '</li>');
$newStreamer.css({ width: w*2 + 'px', height: h + 'px' });
$el.children().eq(0).after($newStreamer);
*/
$el.append('<li class="clear"></li>');
};
var rebuild = function()
{
$el.children().each(function()
{
var originalEq = $(this).attr('data-eq');
$el.children().eq(originalEq).before($(this));
});
$el.children('.streamer').remove();
$el.children('.empty').remove();
$el.children('.clear').remove();
build();
};
var position = function()
{
// Create points grid, set every point to false
var point = [];
for(var r=0; r< t.data.rows;r++)
{
point[r] = [];
for(var c=0; c< t.data.cols;c++)
{
point[r][c] = false;
}
}
// Create elements on points
var index = 0;
// Check each row
var nextCount = 1;
for( r=0; r < t.data.rows;r++)
{
// Check each column in each row
for( c=0; c< t.data.cols;c++)
{
// Check if this point is free
if( ! point[r][c])
{
// Check size
var $li = $el.children().eq(index);
var s = { w : Math.round($li.width()/ t.data.imgW), h : Math.round($li.height()/ t.data.imgH) };
// Check if it fits
var fit = true;
for(var sr=r; sr <= r+(s.h-1);sr++)
{
for(var sc=c; sc <= c+(s.w-1);sc++)
{
if(typeof point[sr] === 'undefined' || typeof point[sr] === null)
{
fit = false;
}
else
{
if(typeof point[sr][sc] === 'undefined' || typeof point[sr][sc] === null) fit = false;
}
}
}
// If it doesn't fit, switch with the next element and check if that fits ( with c-- it goes back one step, so it checks again)
if ( ! fit )
{
var $next = $li.next();
if($next.attr('class') != 'cta' && $next.attr('class') != 'clear')
{
$li.before($next);
if(nextCount < 15) c--;
nextCount++;
}
}
else
{
// If it fits, position the element.
var top = r * t.data.imgH;
var left = c * t.data.imgW;
$li.not('.clear').css({ top: top+'px', left : left+'px' });
index++;
for(sr=r; sr <= r+(s.h-1);sr++)
{
for(sc=c; sc <= c+(s.w-1);sc++)
{
point[sr][sc] = true;
}
}
}
}
}
}
};
t.init();
};
// Add to each element
$.fn.flexgrid = function(options)
{
return this.each(function()
{
// if plugin has not already been attached to the element
if ($(this).data('flexgrid') == undefined)
{
// create a new instance of the plugin
var a = new $.flexgrid(this, options);
$(this).data('flexgrid', a);
}
});
}
})(jQuery);