Turning video thumbnails into squares. Changes the size of the dominant speaker avatar and fixes some minor thing around those two.
This commit is contained in:
parent
5c0088d2ef
commit
64d8cb2db2
|
@ -9,7 +9,7 @@ html, body{
|
|||
color: #424242;
|
||||
font-family:'Helvetica Neue', Helvetica, sans-serif;
|
||||
font-weight: 400;
|
||||
background: #000000;
|
||||
background: #4E4E4E;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ div.feedbackButton:hover {
|
|||
width: 29px;
|
||||
border-radius: 1px;
|
||||
color: #FFF;
|
||||
background: rgba(0,0,0,0.8);
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 6; /*+1 from #remoteVideos*/
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ div.feedbackButton:hover {
|
|||
}
|
||||
|
||||
#toast-container.notification-bottom-right {
|
||||
bottom: 120px;
|
||||
bottom: 140px;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#remoteVideos .videocontainer>object {
|
||||
cursor: hand;
|
||||
border-radius:1px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.flipVideoX {
|
||||
|
@ -98,6 +99,7 @@
|
|||
#localVideoWrapper>object {
|
||||
cursor: hand;
|
||||
border-radius:1px !important;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
#largeVideo,
|
||||
|
@ -371,7 +373,7 @@
|
|||
padding-right:2px;
|
||||
height:38px;
|
||||
width:auto;
|
||||
background-color: rgba(0,0,0,0.8);
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
border-radius: 1px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
@ -401,8 +403,8 @@
|
|||
|
||||
#dominantSpeaker {
|
||||
visibility: hidden;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
@ -421,12 +423,12 @@
|
|||
}
|
||||
|
||||
#dominantSpeakerAvatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
top: 25px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
top: 50px;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
border-radius: 50px;
|
||||
border-radius: 100px;
|
||||
z-index: 3;
|
||||
visibility: inherit;
|
||||
}
|
||||
|
@ -434,8 +436,8 @@
|
|||
.userAvatar {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 35px;
|
||||
border-radius: 200px;
|
||||
left: 0;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.sharedVideoAvatar {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var interfaceConfig = {
|
||||
CANVAS_EXTRA: 104,
|
||||
CANVAS_RADIUS: 1,
|
||||
CANVAS_RADIUS: 0,
|
||||
SHADOW_COLOR: '#ffffff',
|
||||
INITIAL_TOOLBAR_TIMEOUT: 20000,
|
||||
TOOLBAR_TIMEOUT: 4000,
|
||||
|
@ -14,7 +14,6 @@ var interfaceConfig = {
|
|||
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
|
||||
APP_NAME: "Jitsi Meet",
|
||||
INVITATION_POWERED_BY: true,
|
||||
DOMINANT_SPEAKER_AVATAR_SIZE: 100,
|
||||
TOOLBAR_BUTTONS: ['authentication', 'microphone', 'camera', 'desktop',
|
||||
'recording', 'security', 'invite', 'chat', 'etherpad', 'sharedvideo',
|
||||
'fullscreen', 'sip', 'dialpad', 'settings', 'hangup', 'filmstrip',
|
||||
|
@ -30,5 +29,5 @@ var interfaceConfig = {
|
|||
filmStripOnly: false,
|
||||
RANDOM_AVATAR_URL_PREFIX: "http://abotars.hipch.at/meeple/",
|
||||
RANDOM_AVATAR_URL_SUFFIX: ".png",
|
||||
FILM_STRIP_MAX_HEIGHT: 160
|
||||
FILM_STRIP_MAX_HEIGHT: 120
|
||||
};
|
||||
|
|
|
@ -8,13 +8,16 @@ const LOCAL_LEVEL = 'local';
|
|||
|
||||
let ASDrawContext = null;
|
||||
let audioLevelCanvasCache = {};
|
||||
let dominantSpeakerAudioElement = null;
|
||||
|
||||
function initDominantSpeakerAudioLevels() {
|
||||
let ASRadius = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE / 2;
|
||||
let ASCenter = (interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE + ASRadius) / 2;
|
||||
function initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
|
||||
let ASRadius = dominantSpeakerAvatarSize / 2;
|
||||
let ASCenter = (dominantSpeakerAvatarSize + ASRadius) / 2;
|
||||
|
||||
// Draw a circle.
|
||||
ASDrawContext.beginPath();
|
||||
ASDrawContext.arc(ASCenter, ASCenter, ASRadius, 0, 2 * Math.PI);
|
||||
ASDrawContext.closePath();
|
||||
|
||||
// Add a shadow around the circle
|
||||
ASDrawContext.shadowColor = interfaceConfig.SHADOW_COLOR;
|
||||
|
@ -90,14 +93,14 @@ function getShadowLevel (audioLevel) {
|
|||
let shadowLevel = 0;
|
||||
|
||||
if (audioLevel <= 0.3) {
|
||||
shadowLevel
|
||||
= Math.round(interfaceConfig.CANVAS_EXTRA/2*(audioLevel/0.3));
|
||||
shadowLevel = Math.round(
|
||||
interfaceConfig.CANVAS_EXTRA/2*(audioLevel/0.3));
|
||||
} else if (audioLevel <= 0.6) {
|
||||
shadowLevel
|
||||
= Math.round(interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.3) / 0.3));
|
||||
shadowLevel = Math.round(
|
||||
interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.3) / 0.3));
|
||||
} else {
|
||||
shadowLevel
|
||||
= Math.round(interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.6) / 0.4));
|
||||
shadowLevel = Math.round(
|
||||
interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.6) / 0.4));
|
||||
}
|
||||
|
||||
return shadowLevel;
|
||||
|
@ -124,8 +127,18 @@ function getVideoSpanId(id) {
|
|||
const AudioLevels = {
|
||||
|
||||
init () {
|
||||
ASDrawContext = $('#dominantSpeakerAudioLevel')[0].getContext('2d');
|
||||
initDominantSpeakerAudioLevels();
|
||||
dominantSpeakerAudioElement = $('#dominantSpeakerAudioLevel')[0];
|
||||
ASDrawContext = dominantSpeakerAudioElement.getContext('2d');
|
||||
|
||||
let parentContainer = $("#dominantSpeaker");
|
||||
let dominantSpeakerWidth = parentContainer.width();
|
||||
let dominantSpeakerHeight = parentContainer.height();
|
||||
|
||||
dominantSpeakerAudioElement.width = dominantSpeakerWidth;
|
||||
dominantSpeakerAudioElement.height = dominantSpeakerHeight;
|
||||
|
||||
let dominantSpeakerAvatar = $("#dominantSpeakerAvatar");
|
||||
initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -155,8 +168,10 @@ const AudioLevels = {
|
|||
|
||||
audioLevelCanvas = document.createElement('canvas');
|
||||
audioLevelCanvas.className = "audiolevel";
|
||||
audioLevelCanvas.style.bottom = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
audioLevelCanvas.style.left = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
audioLevelCanvas.style.bottom
|
||||
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
audioLevelCanvas.style.left
|
||||
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||
|
||||
videoSpan.appendChild(audioLevelCanvas);
|
||||
|
@ -213,7 +228,10 @@ const AudioLevels = {
|
|||
return;
|
||||
}
|
||||
|
||||
ASDrawContext.clearRect(0, 0, 300, 300);
|
||||
ASDrawContext.clearRect(0, 0,
|
||||
dominantSpeakerAudioElement.width,
|
||||
dominantSpeakerAudioElement.height);
|
||||
|
||||
if (!audioLevel) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import UIUtil from "../util/UIUtil";
|
||||
|
||||
const thumbAspectRatio = 16.0 / 9.0;
|
||||
const thumbAspectRatio = 1 / 1;
|
||||
|
||||
const FilmStrip = {
|
||||
init () {
|
||||
|
@ -44,11 +44,7 @@ const FilmStrip = {
|
|||
* that we want to take into account when calculating the film strip width.
|
||||
*/
|
||||
calculateThumbnailSize (isSideBarVisible) {
|
||||
// Calculate the available height, which is the inner window height
|
||||
// minus 39px for the header minus 2px for the delimiter lines on the
|
||||
// top and bottom of the large video, minus the 36px space inside the
|
||||
// remoteVideos container used for highlighting shadow.
|
||||
let availableHeight = 100;
|
||||
let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
|
||||
|
||||
let numvids = this.getThumbs(true).length;
|
||||
|
||||
|
@ -84,13 +80,13 @@ const FilmStrip = {
|
|||
availableHeight);
|
||||
|
||||
availableHeight
|
||||
= Math.min( maxHeight,
|
||||
availableWidth / thumbAspectRatio,
|
||||
window.innerHeight - 18);
|
||||
= Math.min( maxHeight, window.innerHeight - 18);
|
||||
|
||||
if (availableHeight < availableWidth / thumbAspectRatio) {
|
||||
availableWidth = Math.floor(availableHeight * thumbAspectRatio);
|
||||
if (availableHeight < availableWidth) {
|
||||
availableWidth = availableHeight;
|
||||
}
|
||||
else
|
||||
availableHeight = availableWidth;
|
||||
|
||||
return {
|
||||
thumbWidth: availableWidth,
|
||||
|
|
|
@ -8,7 +8,6 @@ import FilmStrip from './FilmStrip';
|
|||
import Avatar from "../avatar/Avatar";
|
||||
import {createDeferred} from '../../util/helpers';
|
||||
|
||||
const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
|
||||
const FADE_DURATION_MS = 300;
|
||||
|
||||
export const VIDEO_CONTAINER_TYPE = "camera";
|
||||
|
@ -175,6 +174,8 @@ class VideoContainer extends LargeContainer {
|
|||
this.$avatar = $('#dominantSpeaker');
|
||||
this.$wrapper = $('#largeVideoWrapper');
|
||||
|
||||
this.avatarHeight = $("#dominantSpeakerAvatar").height();
|
||||
|
||||
// This does not work with Temasys plugin - has to be a property to be
|
||||
// copied between new <object> elements
|
||||
//this.$video.on('play', onPlay);
|
||||
|
@ -245,7 +246,7 @@ class VideoContainer extends LargeContainer {
|
|||
containerWidth, containerHeight);
|
||||
|
||||
// update avatar position
|
||||
let top = containerHeight / 2 - avatarSize / 4 * 3;
|
||||
let top = containerHeight / 2 - this.avatarHeight / 4 * 3;
|
||||
|
||||
this.$avatar.css('top', top);
|
||||
|
||||
|
@ -369,6 +370,7 @@ export default class LargeVideoManager {
|
|||
this.videoContainer = new VideoContainer(
|
||||
() => this.resizeContainer(VIDEO_CONTAINER_TYPE));
|
||||
this.addContainer(VIDEO_CONTAINER_TYPE, this.videoContainer);
|
||||
|
||||
// use the same video container to handle and desktop tracks
|
||||
this.addContainer("desktop", this.videoContainer);
|
||||
|
||||
|
@ -382,22 +384,26 @@ export default class LargeVideoManager {
|
|||
});
|
||||
|
||||
if (interfaceConfig.SHOW_JITSI_WATERMARK) {
|
||||
let leftWatermarkDiv = this.$container.find("div.watermark.leftwatermark");
|
||||
let leftWatermarkDiv
|
||||
= this.$container.find("div.watermark.leftwatermark");
|
||||
|
||||
leftWatermarkDiv.css({display: 'block'});
|
||||
|
||||
leftWatermarkDiv.parent().attr('href', interfaceConfig.JITSI_WATERMARK_LINK);
|
||||
leftWatermarkDiv.parent().attr(
|
||||
'href', interfaceConfig.JITSI_WATERMARK_LINK);
|
||||
}
|
||||
|
||||
if (interfaceConfig.SHOW_BRAND_WATERMARK) {
|
||||
let rightWatermarkDiv = this.$container.find("div.watermark.rightwatermark");
|
||||
let rightWatermarkDiv
|
||||
= this.$container.find("div.watermark.rightwatermark");
|
||||
|
||||
rightWatermarkDiv.css({
|
||||
display: 'block',
|
||||
backgroundImage: 'url(images/rightwatermark.png)'
|
||||
});
|
||||
|
||||
rightWatermarkDiv.parent().attr('href', interfaceConfig.BRAND_WATERMARK_LINK);
|
||||
rightWatermarkDiv.parent().attr(
|
||||
'href', interfaceConfig.BRAND_WATERMARK_LINK);
|
||||
}
|
||||
|
||||
if (interfaceConfig.SHOW_POWERED_BY) {
|
||||
|
@ -478,7 +484,8 @@ export default class LargeVideoManager {
|
|||
|
||||
return promise;
|
||||
}).then(() => {
|
||||
// after everything is done check again if there are any pending new streams.
|
||||
// after everything is done check again if there are any pending
|
||||
// new streams.
|
||||
this.updateInProcess = false;
|
||||
this.scheduleLargeVideoUpdate();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue