cf74ca961c
Fixes #4900
90 lines
3.2 KiB
JavaScript
90 lines
3.2 KiB
JavaScript
|
|
(function() {
|
|
function adjustVideos(tagId, centerVideos) {
|
|
const _minContentAspectRatio = 4 / 3.0;
|
|
|
|
function calculateOccupiedArea(canvasWidth, canvasHeight, numColumns, numRows, numChildren) {
|
|
const obj = calculateCellDimensions(canvasWidth, canvasHeight, numColumns, numRows);
|
|
obj.occupiedArea = obj.width * obj.height * numChildren;
|
|
obj.numColumns = numColumns;
|
|
obj.numRows = numRows;
|
|
obj.cellAspectRatio = _minContentAspectRatio;
|
|
return obj;
|
|
}
|
|
|
|
function calculateCellDimensions(canvasWidth, canvasHeight, numColumns, numRows) {
|
|
const obj = {
|
|
width: Math.floor(canvasWidth / numColumns),
|
|
height: Math.floor(canvasHeight / numRows),
|
|
};
|
|
|
|
if (obj.width / obj.height > _minContentAspectRatio) {
|
|
obj.width = Math.min(Math.floor(obj.height * _minContentAspectRatio), Math.floor(canvasWidth / numColumns));
|
|
} else {
|
|
obj.height = Math.min(Math.floor(obj.width / _minContentAspectRatio), Math.floor(canvasHeight / numRows));
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
function findBestConfiguration(canvasWidth, canvasHeight, numChildrenInCanvas) {
|
|
let bestConfiguration = {
|
|
occupiedArea: 0,
|
|
};
|
|
|
|
for (let cols = 1; cols <= numChildrenInCanvas; cols++) {
|
|
let rows = Math.floor(numChildrenInCanvas / cols);
|
|
|
|
// That's a small HACK, different from the original algorithm
|
|
// Sometimes numChildren will be bigger than cols*rows, this means that this configuration
|
|
// can't show all the videos and shouldn't be considered. So we just increment the number of rows
|
|
// and get a configuration which shows all the videos albeit with a few missing slots in the end.
|
|
// For example: with numChildren == 8 the loop will generate cols == 3 and rows == 2
|
|
// cols * rows is 6 so we bump rows to 3 and then cols*rows is 9 which is bigger than 8
|
|
if (numChildrenInCanvas > cols * rows) {
|
|
rows += 1;
|
|
}
|
|
|
|
const currentConfiguration = calculateOccupiedArea(canvasWidth, canvasHeight, cols, rows, numChildrenInCanvas);
|
|
|
|
if (currentConfiguration.occupiedArea > bestConfiguration.occupiedArea) {
|
|
bestConfiguration = currentConfiguration;
|
|
}
|
|
}
|
|
|
|
return bestConfiguration;
|
|
}
|
|
|
|
// http://stackoverflow.com/a/3437825/414642
|
|
const e = $("#" + tagId).parent();
|
|
const x = e.outerWidth() - 1;
|
|
const y = e.outerHeight() - 1;
|
|
|
|
const videos = $("#" + tagId + " video:visible");
|
|
|
|
const best = findBestConfiguration(x, y, videos.length);
|
|
|
|
videos.each(function (i) {
|
|
const row = Math.floor(i / best.numColumns);
|
|
const col = Math.floor(i % best.numColumns);
|
|
|
|
// Free width space remaining to the right and below of the videos
|
|
const remX = (x - best.width * best.numColumns);
|
|
const remY = (y - best.height * best.numRows);
|
|
|
|
// Center videos
|
|
const top = Math.floor(((best.height) * row) + remY / 2);
|
|
const left = Math.floor(((best.width) * col) + remX / 2);
|
|
|
|
const videoTop = `top: ${top}px;`;
|
|
const videoLeft = `left: ${left}px;`;
|
|
|
|
$(this).attr('style', videoTop + videoLeft);
|
|
});
|
|
|
|
videos.attr('width', best.width);
|
|
videos.attr('height', best.height);
|
|
}
|
|
|
|
window.adjustVideos = adjustVideos;
|
|
})();
|