kaiwa/clientapp/modules/fluidGrid.js

230 lines
6.5 KiB
JavaScript

(function () {
// reference to our currently focused element
var focusedEl;
function getFluidGridFunction(selector) {
return function (focus) {
reOrganize(selector, focus);
};
}
function biggestBox(container, aspectRatio) {
var aspectRatio = aspectRatio || (3 / 4),
height = (container.width * aspectRatio),
res = {};
if (height > container.height) {
return {
height: container.height,
width: container.height / aspectRatio
};
} else {
return {
width: container.width,
height: container.width * aspectRatio
};
}
}
function reOrganize(selector, focus) {
var floor = Math.floor,
elements = $(selector),
howMany = elements.length,
howManyNonFocused = function () {
var hasFocused = !!elements.find('.focused').length;
if (hasFocused && howMany > 1) {
return howMany - 1;
} else if (hasFocused && howMany === 1) {
return 1;
} else {
return howMany;
}
}(),
totalAvailableWidth = window.innerWidth,
totalAvailableHeight = window.innerHeight - 140,
availableWidth = totalAvailableWidth,
availableHeight = totalAvailableHeight,
container = {
width: availableWidth,
height: availableHeight
},
columnPadding = 15,
minimumWidth = 290,
aspectRatio = 3 / 4,
numberOfColumns,
numberOfRows,
numberOfPaddingColumns,
numberOfPaddingRows,
itemDimensions,
totalWidth,
videoWidth,
leftMargin,
videoHeight,
usedHeight,
topMargin,
// do we have one selected?
// this is because having a single
// focused element is not treated
// differently, but we don't want to
// lose that reference.
haveFocusedEl;
// if we passed in a string here (could be "none")
// then we want to either set or clear our current
// focused element.
if (focus) focusedEl = $(focus)[0];
// make sure our cached focused element is still
// attached.
if (focusedEl && !$(focusedEl).parent().length) focusedEl = undefined;
// figure out if we should consider us as having any
// special focused elements
haveFocusedEl = focusedEl && howManyNonFocused > 1;
elements.height(availableHeight);
// how we want the to stack at different numbers
if (haveFocusedEl) {
numberOfColumns = howManyNonFocused - 1;
numberOfRows = 1;
availableHeight = totalAvailableHeight * .2;
} else if (howManyNonFocused === 0) {
return;
} else if (howManyNonFocused === 1) {
numberOfColumns = 1;
numberOfRows = 1;
} else if (howManyNonFocused === 2) {
if (availableWidth > availableHeight) {
numberOfColumns = 2;
numberOfRows = 1;
} else {
numberOfColumns = 1;
numberOfRows = 2;
}
} else if (howManyNonFocused === 3) {
if (availableWidth > availableHeight) {
numberOfColumns = 3;
numberOfRows = 1;
} else {
numberOfColumns = 1;
numberOfRows = 3;
}
} else if (howManyNonFocused === 4) {
numberOfColumns = 2;
numberOfRows = 2;
} else if (howManyNonFocused === 5) {
numberOfColumns = 3;
numberOfRows = 2;
} else if (howManyNonFocused === 6) {
if (availableWidth > availableHeight) {
numberOfColumns = 3;
numberOfRows = 2;
} else {
numberOfColumns = 2;
numberOfRows = 3;
}
}
itemDimensions = biggestBox({
width: availableWidth / numberOfColumns,
height: availableHeight / numberOfRows
});
numberOfPaddingColumns = numberOfColumns - 1;
numberOfPaddingRows = numberOfRows - 1;
totalWidth = itemDimensions.width * numberOfColumns;
videoWidth = function () {
var totalWidthLessPadding = totalWidth - (columnPadding * numberOfPaddingColumns);
return totalWidthLessPadding / numberOfColumns;
}();
leftMargin = (availableWidth - totalWidth) / 2;
videoHeight = itemDimensions.height - ((numberOfRows > 1) ? (columnPadding / numberOfRows) : 0);
usedHeight = (numberOfRows * videoHeight);
topMargin = (availableHeight - usedHeight) / 2;
if (haveFocusedEl) {
elements = elements.not('.focused');
}
elements.each(function (index) {
var order = index,
row = floor(order / numberOfColumns),
column = order % numberOfColumns,
intensity = 12,
rotation = function () {
if (numberOfColumns === 3) {
if (column === 0) {
return 1;
} else if (column === 1) {
return 0;
} else if (column === 2) {
return -1
}
} else if (numberOfColumns === 2) {
intensity = 5;
return column == 1 ? -1 : 1
} else if (numberOfColumns === 1) {
return 0;
}
}(),
transformation = 'rotateY(' + (rotation * intensity) + 'deg)';
if (rotation === 0) {
transformation += ' scale(.98)';
}
var calculatedTop;
if (haveFocusedEl) {
calculatedTop = (totalAvailableHeight * .8) + topMargin + 'px';
} else {
calculatedTop = (row * itemDimensions.height) + topMargin + 'px';
}
$(this).css({
//transform: transformation,
top: calculatedTop,
left: (column * itemDimensions.width) + leftMargin + 'px',
width: videoWidth + 'px',
height: videoHeight + 'px',
position: 'absolute'
});
});
if (haveFocusedEl) {
var focusSize = biggestBox({
height: (totalAvailableHeight * .8),
width: totalAvailableWidth
}, focusedEl.videoHeight / focusedEl.videoWidth);
$(focusedEl).css({
top: 0,
height: focusSize.height - topMargin,
width: focusSize.width,
left: (totalAvailableWidth / 2) - (focusSize.width / 2)
});
}
}
if (typeof exports !== 'undefined') {
module.exports = getFluidGridFunction;
} else {
window.getFluidGridFunction = getFluidGridFunction;
}
})();