Merge remote-tracking branch 'remotes/upstream/develop' into tiles-start-positions
This commit is contained in:
commit
7f61e9addd
182 changed files with 17118 additions and 4494 deletions
126
front/src/Stores/BiggestAvailableAreaStore.ts
Normal file
126
front/src/Stores/BiggestAvailableAreaStore.ts
Normal file
|
@ -0,0 +1,126 @@
|
|||
import { get, writable } from "svelte/store";
|
||||
import type { Box } from "../WebRtc/LayoutManager";
|
||||
import { HtmlUtils } from "../WebRtc/HtmlUtils";
|
||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||
import { layoutModeStore } from "./StreamableCollectionStore";
|
||||
|
||||
/**
|
||||
* Tries to find the biggest available box of remaining space (this is a space where we can center the character)
|
||||
*/
|
||||
function findBiggestAvailableArea(): Box {
|
||||
const game = HtmlUtils.querySelectorOrFail<HTMLCanvasElement>("#game canvas");
|
||||
if (get(layoutModeStore) === LayoutMode.VideoChat) {
|
||||
const children = document.querySelectorAll<HTMLDivElement>("div.chat-mode > div");
|
||||
const htmlChildren = Array.from(children.values());
|
||||
|
||||
// No chat? Let's go full center
|
||||
if (htmlChildren.length === 0) {
|
||||
return {
|
||||
xStart: 0,
|
||||
yStart: 0,
|
||||
xEnd: game.offsetWidth,
|
||||
yEnd: game.offsetHeight,
|
||||
};
|
||||
}
|
||||
|
||||
const lastDiv = htmlChildren[htmlChildren.length - 1];
|
||||
// Compute area between top right of the last div and bottom right of window
|
||||
const area1 =
|
||||
(game.offsetWidth - (lastDiv.offsetLeft + lastDiv.offsetWidth)) * (game.offsetHeight - lastDiv.offsetTop);
|
||||
|
||||
// Compute area between bottom of last div and bottom of the screen on whole width
|
||||
const area2 = game.offsetWidth * (game.offsetHeight - (lastDiv.offsetTop + lastDiv.offsetHeight));
|
||||
|
||||
if (area1 < 0 && area2 < 0) {
|
||||
// If screen is full, let's not attempt something foolish and simply center character in the middle.
|
||||
return {
|
||||
xStart: 0,
|
||||
yStart: 0,
|
||||
xEnd: game.offsetWidth,
|
||||
yEnd: game.offsetHeight,
|
||||
};
|
||||
}
|
||||
if (area1 <= area2) {
|
||||
return {
|
||||
xStart: 0,
|
||||
yStart: lastDiv.offsetTop + lastDiv.offsetHeight,
|
||||
xEnd: game.offsetWidth,
|
||||
yEnd: game.offsetHeight,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
xStart: lastDiv.offsetLeft + lastDiv.offsetWidth,
|
||||
yStart: lastDiv.offsetTop,
|
||||
xEnd: game.offsetWidth,
|
||||
yEnd: game.offsetHeight,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Possible destinations: at the center bottom or at the right bottom.
|
||||
const mainSectionChildren = Array.from(
|
||||
document.querySelectorAll<HTMLDivElement>("div.main-section > div").values()
|
||||
);
|
||||
const sidebarChildren = Array.from(document.querySelectorAll<HTMLDivElement>("aside.sidebar > div").values());
|
||||
|
||||
// No presentation? Let's center on the screen
|
||||
if (mainSectionChildren.length === 0) {
|
||||
return {
|
||||
xStart: 0,
|
||||
yStart: 0,
|
||||
xEnd: game.offsetWidth,
|
||||
yEnd: game.offsetHeight,
|
||||
};
|
||||
}
|
||||
|
||||
// At this point, we know we have at least one element in the main section.
|
||||
const lastPresentationDiv = mainSectionChildren[mainSectionChildren.length - 1];
|
||||
|
||||
const presentationArea =
|
||||
(game.offsetHeight - (lastPresentationDiv.offsetTop + lastPresentationDiv.offsetHeight)) *
|
||||
(lastPresentationDiv.offsetLeft + lastPresentationDiv.offsetWidth);
|
||||
|
||||
let leftSideBar: number;
|
||||
let bottomSideBar: number;
|
||||
if (sidebarChildren.length === 0) {
|
||||
leftSideBar = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("sidebar").offsetLeft;
|
||||
bottomSideBar = 0;
|
||||
} else {
|
||||
const lastSideBarChildren = sidebarChildren[sidebarChildren.length - 1];
|
||||
leftSideBar = lastSideBarChildren.offsetLeft;
|
||||
bottomSideBar = lastSideBarChildren.offsetTop + lastSideBarChildren.offsetHeight;
|
||||
}
|
||||
const sideBarArea = (game.offsetWidth - leftSideBar) * (game.offsetHeight - bottomSideBar);
|
||||
|
||||
if (presentationArea <= sideBarArea) {
|
||||
return {
|
||||
xStart: leftSideBar,
|
||||
yStart: bottomSideBar,
|
||||
xEnd: game.offsetWidth,
|
||||
yEnd: game.offsetHeight,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
xStart: 0,
|
||||
yStart: lastPresentationDiv.offsetTop + lastPresentationDiv.offsetHeight,
|
||||
xEnd: /*lastPresentationDiv.offsetLeft + lastPresentationDiv.offsetWidth*/ game.offsetWidth, // To avoid flickering when a chat start, we center on the center of the screen, not the center of the main content area
|
||||
yEnd: game.offsetHeight,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A store that contains the list of (video) peers we are connected to.
|
||||
*/
|
||||
function createBiggestAvailableAreaStore() {
|
||||
const { subscribe, set } = writable<Box>({ xStart: 0, yStart: 0, xEnd: 1, yEnd: 1 });
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
recompute: () => {
|
||||
set(findBiggestAvailableArea());
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const biggestAvailableAreaStore = createBiggestAvailableAreaStore();
|
Loading…
Add table
Add a link
Reference in a new issue