bigbluebutton-Github/bigbluebutton-html5/client/compatibility/adjust-videos.js

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;
})();