Adding CoWebsiteManager + first working version of flex video
This commit is contained in:
parent
83fe024c45
commit
9f6c6e0ce1
52
front/dist/index.html
vendored
52
front/dist/index.html
vendored
@ -39,7 +39,53 @@
|
||||
<title>WorkAdventure</title>
|
||||
</head>
|
||||
<body id="body" style="margin: 0">
|
||||
<div id="webRtc" class="webrtc">
|
||||
<div class="main-container">
|
||||
<div id="game" class="game" style="/*background: red;*/">
|
||||
<div id="game-overlay" class="game-overlay" style="/*background: violet*/;">
|
||||
<div id="main-section" class="main-section">
|
||||
<!--<div style="background: lightpink;">a</div>
|
||||
<div style="background: lightpink;">a</div> -->
|
||||
</div>
|
||||
<aside id="sidebar" class="sidebar">
|
||||
<!--<div style="background: lightgreen;">a</div>
|
||||
<div style="background: green;">b</div>
|
||||
<div style="background: darkgreen;">c</div>
|
||||
<div style="background: darkgreen;">d</div>-->
|
||||
</aside>
|
||||
<div id="chat-mode" class="chat-mode three-col" style="display: none;">
|
||||
<!--<div style="background: lightgreen;">a</div>
|
||||
<div style="background: green;">b</div>
|
||||
<div style="background: darkgreen;">c</div>
|
||||
<div style="background: darkolivegreen;">d</div>
|
||||
<div style="background: darkolivegreen;">d</div>
|
||||
<div style="background: darkgreen;">c</div>
|
||||
<div style="background: green;">b</div>
|
||||
<div style="background: lightgreen;">last elem for game</div>-->
|
||||
</div>
|
||||
|
||||
|
||||
<div id="activeCam" class="activeCam">
|
||||
<div id="div-myCamVideo" class="video-container">
|
||||
<video id="myCamVideo" autoplay muted></video>
|
||||
</div>
|
||||
<div class="btn-cam-action">
|
||||
<div class="btn-micro">
|
||||
<img id="microphone" src="resources/logos/microphone.svg">
|
||||
<img id="microphone-close" src="resources/logos/microphone-close.svg">
|
||||
</div>
|
||||
<div class="btn-video">
|
||||
<img id="cinema" src="resources/logos/cinema.svg">
|
||||
<img id="cinema-close" src="resources/logos/cinema-close.svg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="cowebsite" class="cowebsite"></div>
|
||||
</div>
|
||||
<!--
|
||||
<div id="webRtc" class="webrtc">
|
||||
<div id="activeCam" class="activeCam">
|
||||
<div id="div-myCamVideo" class="video-container">
|
||||
<video id="myCamVideo" autoplay muted></video>
|
||||
@ -54,11 +100,9 @@
|
||||
<img id="cinema" src="resources/logos/cinema.svg">
|
||||
<img id="cinema-close" src="resources/logos/cinema-close.svg">
|
||||
</div>
|
||||
<!--<div class="btn-call">
|
||||
<img src="resources/logos/phone.svg">
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div id="webRtcSetup" class="webrtcsetup">
|
||||
<img id="webRtcSetupNoVideo" class="background-img" src="resources/logos/cinema-close.svg">
|
||||
<video id="myCamVideoSetup" autoplay muted></video>
|
||||
|
196
front/dist/resources/style/style.css
vendored
196
front/dist/resources/style/style.css
vendored
@ -27,7 +27,7 @@ video{
|
||||
-webkit-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
.webrtc{
|
||||
/*.webrtc{
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
@ -36,21 +36,22 @@ video{
|
||||
}
|
||||
.webrtc.active{
|
||||
display: block;
|
||||
}
|
||||
}*/
|
||||
|
||||
.webrtc, .activeCam{}
|
||||
.activeCam .video-container{
|
||||
position: absolute;
|
||||
height: 25%;
|
||||
/*.webrtc, .activeCam{}*/
|
||||
/*.activeCam*/ .video-container{
|
||||
position: relative;
|
||||
/*height: 25%;
|
||||
top: 10px;
|
||||
margin: 5px;
|
||||
right: -100px;
|
||||
transition: all 0.2s ease;
|
||||
border-color: black;
|
||||
transition: all 0.2s ease;*/
|
||||
/*border-color: black;
|
||||
border-style: solid;
|
||||
border-width: 0.2px;
|
||||
border-width: 0.2px;*/
|
||||
background-color: #00000099;
|
||||
}
|
||||
.activeCam .video-container i{
|
||||
/*.activeCam*/ .video-container i{
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
height: 65px;
|
||||
@ -63,10 +64,10 @@ video{
|
||||
font-size: 28px;
|
||||
color: white;
|
||||
}
|
||||
.activeCam .video-container img.active{
|
||||
/*.activeCam*/ .video-container img.active{
|
||||
display: block;
|
||||
}
|
||||
.activeCam .video-container img{
|
||||
/*.activeCam*/ .video-container img{
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 15px;
|
||||
@ -78,34 +79,28 @@ video{
|
||||
padding: 10px;
|
||||
z-index: 2;
|
||||
}
|
||||
.activeCam .video-container video{
|
||||
/*.activeCam*/ .video-container video{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.webrtc:hover .activeCam .video-container{
|
||||
/*.webrtc:hover .activeCam .video-container{
|
||||
right: 10px;
|
||||
}
|
||||
.activeCam .video-container#div-myCamVideo{
|
||||
}*/
|
||||
/*.activeCam*/ .video-container#div-myCamVideo{
|
||||
border: none;
|
||||
}
|
||||
.activeCam .video-container video#myCamVideo{
|
||||
width: 200px;
|
||||
height: 113px;
|
||||
/*.activeCam*/
|
||||
|
||||
#div-myCamVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/*CSS size for 2 - 3 elements*/
|
||||
.activeCam .video-container:nth-child(1){
|
||||
/*this is for camera of user*/
|
||||
top: 75%;
|
||||
}
|
||||
.activeCam .video-container:nth-child(2){
|
||||
top: 0%;
|
||||
}
|
||||
.activeCam .video-container:nth-child(3){
|
||||
top: 25%;
|
||||
}
|
||||
.activeCam .video-container:nth-child(4) {
|
||||
top: 50%;
|
||||
video#myCamVideo{
|
||||
width: 15vw;
|
||||
/*width: 200px;*/
|
||||
/*height: 113px;*/
|
||||
}
|
||||
|
||||
/*btn animation*/
|
||||
@ -122,7 +117,7 @@ video{
|
||||
transition-timing-function: ease-in-out;
|
||||
bottom: 20px;
|
||||
}
|
||||
.webrtc:hover .btn-cam-action div{
|
||||
#activeCam:hover .btn-cam-action div{
|
||||
transform: translateY(0);
|
||||
}
|
||||
.btn-cam-action div:hover{
|
||||
@ -237,3 +232,138 @@ video{
|
||||
.webrtcsetup.active{
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
/* New layout */
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
.main-container {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
@media (min-aspect-ratio: 1/1) {
|
||||
.main-container {
|
||||
flex-direction: row
|
||||
}
|
||||
|
||||
.game-overlay {
|
||||
flex-direction: row
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
flex-direction: column
|
||||
}
|
||||
}
|
||||
@media (max-aspect-ratio: 1/1) {
|
||||
.main-container {
|
||||
flex-direction: column
|
||||
}
|
||||
|
||||
.game-overlay {
|
||||
flex-direction: column
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
flex-direction: row
|
||||
}
|
||||
}
|
||||
|
||||
.game {
|
||||
flex-basis: 100%;
|
||||
position: relative; /* Position relative is needed for the game-overlay. */
|
||||
}
|
||||
|
||||
/* A potentially shared website could appear in an iframe in the cowebsite space. */
|
||||
.cowebsite {
|
||||
flex-basis: 100%;
|
||||
transition: flex-basis 0.5s;
|
||||
}
|
||||
|
||||
/*.cowebsite:hover {
|
||||
flex-basis: 100%;
|
||||
}*/
|
||||
|
||||
.cowebsite iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.game-overlay {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* TODO: DO WE NEED FLEX HERE???? WE WANT A SIDEBAR OF EXACTLY 25% (note: flex useful for direction!!!) */
|
||||
}
|
||||
|
||||
.game-overlay.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.game-overlay video {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.main-section {
|
||||
flex: 0 0 75%;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
/*align-items: flex-start;*/
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.main-section div {
|
||||
margin: 5%;
|
||||
flex-basis: 90%;
|
||||
/*flex-shrink: 2;*/
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
flex: 0 0 25%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.sidebar > div {
|
||||
height: 15%;
|
||||
margin: 5%;
|
||||
}
|
||||
|
||||
.chat-mode {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
flex-wrap: wrap;
|
||||
|
||||
padding: 1%;
|
||||
}
|
||||
|
||||
.chat-mode div {
|
||||
margin: 1%;
|
||||
}
|
||||
|
||||
.chat-mode.one-col div {
|
||||
flex-basis: 98%;
|
||||
}
|
||||
|
||||
.chat-mode.two-col div {
|
||||
flex-basis: 48%;
|
||||
}
|
||||
|
||||
.chat-mode.three-col div {
|
||||
flex-basis: 31.333333%;
|
||||
}
|
||||
|
||||
.chat-mode.four-col div {
|
||||
flex-basis: 23%;
|
||||
}
|
||||
|
||||
.chat-mode div:last-child {
|
||||
flex-grow: 5;
|
||||
}
|
||||
|
56
front/src/WebRtc/CoWebsiteManager.ts
Normal file
56
front/src/WebRtc/CoWebsiteManager.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import {HtmlUtils} from "./HtmlUtils";
|
||||
|
||||
export type CoWebsiteStateChangedCallback = () => void;
|
||||
|
||||
export class CoWebsiteManager {
|
||||
|
||||
private static observers = new Array<CoWebsiteStateChangedCallback>();
|
||||
|
||||
public static loadCoWebsite(url: string): void {
|
||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite");
|
||||
cowebsiteDiv.innerHTML = '';
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.id = 'cowebsite-iframe';
|
||||
iframe.src = url;
|
||||
cowebsiteDiv.appendChild(iframe);
|
||||
CoWebsiteManager.fire();
|
||||
}
|
||||
|
||||
public static closeCoWebsite(): void {
|
||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite");
|
||||
cowebsiteDiv.innerHTML = '';
|
||||
CoWebsiteManager.fire();
|
||||
}
|
||||
|
||||
public static getGameSize(): {width: number, height: number} {
|
||||
const iframe = document.getElementById('cowebsite-iframe');
|
||||
if (iframe === null) {
|
||||
return {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
}
|
||||
}
|
||||
if (window.innerWidth >= window.innerHeight) {
|
||||
return {
|
||||
width: window.innerWidth / 2,
|
||||
height: window.innerHeight
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static onStateChange(observer: CoWebsiteStateChangedCallback) {
|
||||
CoWebsiteManager.observers.push(observer);
|
||||
}
|
||||
|
||||
private static fire(): void {
|
||||
for (const callback of CoWebsiteManager.observers) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ export enum DivImportance {
|
||||
* This class is in charge of the video-conference layout.
|
||||
* It receives positioning requests for videos and does its best to place them on the screen depending on the active layout mode.
|
||||
*/
|
||||
export class LayoutManager {
|
||||
class LayoutManager {
|
||||
private mode: LayoutMode = LayoutMode.Presentation;
|
||||
|
||||
private importantDivs: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
|
||||
@ -26,7 +26,7 @@ export class LayoutManager {
|
||||
|
||||
public add(importance: DivImportance, userId: string, html: string): void {
|
||||
const div = document.createElement('div');
|
||||
div.append(html);
|
||||
div.innerHTML = html;
|
||||
div.id = "user-"+userId;
|
||||
|
||||
if (importance === DivImportance.Important) {
|
||||
@ -65,6 +65,7 @@ export class LayoutManager {
|
||||
* Removes the DIV matching userId.
|
||||
*/
|
||||
public remove(userId: string): void {
|
||||
console.log('Removing video for userID '+userId+'.');
|
||||
let div = this.importantDivs.get(userId);
|
||||
if (div !== undefined) {
|
||||
div.remove();
|
||||
@ -81,7 +82,8 @@ export class LayoutManager {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error('Could not find user ID "'+userId+'"');
|
||||
console.log('Cannot remove userID '+userId+'. Already removed?');
|
||||
//throw new Error('Could not find user ID "'+userId+'"');
|
||||
}
|
||||
|
||||
private adjustVideoChatClass(): void {
|
||||
@ -104,6 +106,16 @@ export class LayoutManager {
|
||||
private switchLayoutMode(layoutMode: LayoutMode) {
|
||||
this.mode = layoutMode;
|
||||
|
||||
if (layoutMode === LayoutMode.Presentation) {
|
||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('sidebar').style.display = 'block';
|
||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-section').style.display = 'block';
|
||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('chat-mode').style.display = 'none';
|
||||
} else {
|
||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('sidebar').style.display = 'none';
|
||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-section').style.display = 'none';
|
||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('chat-mode').style.display = 'block';
|
||||
}
|
||||
|
||||
for (let div of this.importantDivs.values()) {
|
||||
this.positionDiv(div, DivImportance.Important);
|
||||
}
|
||||
@ -112,3 +124,7 @@ export class LayoutManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const layoutManager = new LayoutManager();
|
||||
|
||||
export { layoutManager };
|
||||
|
@ -1,3 +1,5 @@
|
||||
import {DivImportance, layoutManager} from "./LayoutManager";
|
||||
|
||||
const videoConstraint: boolean|MediaTrackConstraints = {
|
||||
width: { ideal: 1280 },
|
||||
height: { ideal: 720 },
|
||||
@ -73,8 +75,8 @@ export class MediaManager {
|
||||
}
|
||||
|
||||
activeVisio(){
|
||||
const webRtc = this.getElementByIdOrFail('webRtc');
|
||||
webRtc.classList.add('active');
|
||||
const gameOverlay = this.getElementByIdOrFail('game-overlay');
|
||||
gameOverlay.classList.add('active');
|
||||
}
|
||||
|
||||
enabledCamera() {
|
||||
@ -184,10 +186,11 @@ export class MediaManager {
|
||||
*/
|
||||
addActiveVideo(userId : string, userName: string = ""){
|
||||
this.webrtcInAudio.play();
|
||||
const elementRemoteVideo = this.getElementByIdOrFail("activeCam");
|
||||
|
||||
//const elementRemoteVideo = this.getElementByIdOrFail("activeCam");
|
||||
userName = userName.toUpperCase();
|
||||
const color = this.getColorByString(userName);
|
||||
elementRemoteVideo.insertAdjacentHTML('beforeend', `
|
||||
/*elementRemoteVideo.insertAdjacentHTML('beforeend', `
|
||||
<div id="div-${userId}" class="video-container" style="border-color: ${color};">
|
||||
<div class="connecting-spinner"></div>
|
||||
<div class="rtc-error" style="display: none"></div>
|
||||
@ -195,7 +198,20 @@ export class MediaManager {
|
||||
<img id="microphone-${userId}" src="resources/logos/microphone-close.svg">
|
||||
<video id="${userId}" autoplay></video>
|
||||
</div>
|
||||
`);
|
||||
`);*/
|
||||
|
||||
const html = `
|
||||
<div id="div-${userId}" class="video-container">
|
||||
<div class="connecting-spinner"></div>
|
||||
<div class="rtc-error" style="display: none"></div>
|
||||
<i style="background-color: ${color};">${userName}</i>
|
||||
<img id="microphone-${userId}" src="resources/logos/microphone-close.svg">
|
||||
<video id="${userId}" autoplay></video>
|
||||
</div>
|
||||
`;
|
||||
|
||||
layoutManager.add(DivImportance.Normal, userId, html);
|
||||
|
||||
this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId));
|
||||
}
|
||||
|
||||
@ -274,11 +290,12 @@ export class MediaManager {
|
||||
* @param userId
|
||||
*/
|
||||
removeActiveVideo(userId : string){
|
||||
const element = document.getElementById(`div-${userId}`);
|
||||
/*const element = document.getElementById(`div-${userId}`);
|
||||
if(!element){
|
||||
return;
|
||||
}
|
||||
element.remove();
|
||||
element.remove();*/
|
||||
layoutManager.remove(userId);
|
||||
this.remoteVideo.delete(userId);
|
||||
}
|
||||
|
||||
|
@ -4,16 +4,21 @@ import {DEBUG_MODE, RESOLUTION} from "./Enum/EnvironmentVariable";
|
||||
import {cypressAsserter} from "./Cypress/CypressAsserter";
|
||||
import {LoginScene} from "./Phaser/Login/LoginScene";
|
||||
import {ReconnectingScene} from "./Phaser/Reconnecting/ReconnectingScene";
|
||||
import {gameManager} from "./Phaser/Game/GameManager";
|
||||
import {SelectCharacterScene} from "./Phaser/Login/SelectCharacterScene";
|
||||
import {EnableCameraScene} from "./Phaser/Login/EnableCameraScene";
|
||||
import {FourOFourScene} from "./Phaser/Reconnecting/FourOFourScene";
|
||||
import {CustomizeScene} from "./Phaser/Login/CustomizeScene";
|
||||
import {HtmlUtils} from "./WebRtc/HtmlUtils";
|
||||
import {CoWebsiteManager} from "./WebRtc/CoWebsiteManager";
|
||||
|
||||
//CoWebsiteManager.loadCoWebsite('https://thecodingmachine.com');
|
||||
|
||||
const {width, height} = CoWebsiteManager.getGameSize();
|
||||
|
||||
const config: GameConfig = {
|
||||
title: "WorkAdventure",
|
||||
width: window.innerWidth / RESOLUTION,
|
||||
height: window.innerHeight / RESOLUTION,
|
||||
width: width / RESOLUTION,
|
||||
height: height / RESOLUTION,
|
||||
parent: "game",
|
||||
scene: [LoginScene, SelectCharacterScene, EnableCameraScene, ReconnectingScene, FourOFourScene, CustomizeScene],
|
||||
zoom: RESOLUTION,
|
||||
@ -30,5 +35,12 @@ cypressAsserter.gameStarted();
|
||||
const game = new Phaser.Game(config);
|
||||
|
||||
window.addEventListener('resize', function (event) {
|
||||
game.scale.resize(window.innerWidth / RESOLUTION, window.innerHeight / RESOLUTION);
|
||||
const {width, height} = CoWebsiteManager.getGameSize();
|
||||
|
||||
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
|
||||
});
|
||||
CoWebsiteManager.onStateChange(() => {
|
||||
const {width, height} = CoWebsiteManager.getGameSize();
|
||||
|
||||
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user