From 8bde9d4e008b0f86f5bd3d0e7f4d5606a30e41f2 Mon Sep 17 00:00:00 2001 From: yanas Date: Thu, 3 Mar 2016 17:38:40 -0600 Subject: [PATCH] Turning video thumbnails into squares. Changes the size of the dominant speaker avatar and fixes some minor thing around those two. --- css/main.css | 6 ++-- css/videolayout_default.css | 20 ++++++----- interface_config.js | 5 ++- modules/UI/audio_levels/AudioLevels.js | 46 ++++++++++++++++++-------- modules/UI/videolayout/FilmStrip.js | 18 ++++------ modules/UI/videolayout/LargeVideo.js | 23 ++++++++----- 6 files changed, 70 insertions(+), 48 deletions(-) diff --git a/css/main.css b/css/main.css index c2fd29963..d2b7d1c41 100644 --- a/css/main.css +++ b/css/main.css @@ -9,7 +9,7 @@ html, body{ color: #424242; font-family:'Helvetica Neue', Helvetica, sans-serif; font-weight: 400; - background: #000000; + background: #4E4E4E; overflow: hidden; } @@ -262,7 +262,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*/ } @@ -336,7 +336,7 @@ div.feedbackButton:hover { } #toast-container.notification-bottom-right { - bottom: 120px; + bottom: 140px; right: 5px; } diff --git a/css/videolayout_default.css b/css/videolayout_default.css index 09f760f75..d34f201f6 100644 --- a/css/videolayout_default.css +++ b/css/videolayout_default.css @@ -84,6 +84,7 @@ #remoteVideos .videocontainer>object { cursor: hand; border-radius:1px; + object-fit: cover; } .flipVideoX { @@ -97,6 +98,7 @@ #localVideoWrapper>object { cursor: hand; border-radius:1px !important; + object-fit: cover; } #largeVideo, @@ -369,7 +371,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; } @@ -399,8 +401,8 @@ #dominantSpeaker { visibility: hidden; - width: 150px; - height: 150px; + width: 300px; + height: 300px; margin: auto; overflow: hidden; position: relative; @@ -419,12 +421,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; } @@ -432,8 +434,8 @@ .userAvatar { height: 100%; position: absolute; - left: 35px; - border-radius: 200px; + left: 0; + border-radius: 2px; } .noMic { diff --git a/interface_config.js b/interface_config.js index f1639c430..e048f46db 100644 --- a/interface_config.js +++ b/interface_config.js @@ -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', 'prezi', 'etherpad', '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 }; diff --git a/modules/UI/audio_levels/AudioLevels.js b/modules/UI/audio_levels/AudioLevels.js index 7e1bc68dd..68568710d 100644 --- a/modules/UI/audio_levels/AudioLevels.js +++ b/modules/UI/audio_levels/AudioLevels.js @@ -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; } diff --git a/modules/UI/videolayout/FilmStrip.js b/modules/UI/videolayout/FilmStrip.js index 2e0a8ce50..52ff3c684 100644 --- a/modules/UI/videolayout/FilmStrip.js +++ b/modules/UI/videolayout/FilmStrip.js @@ -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, diff --git a/modules/UI/videolayout/LargeVideo.js b/modules/UI/videolayout/LargeVideo.js index 9f27bb8b2..42d31bf6a 100644 --- a/modules/UI/videolayout/LargeVideo.js +++ b/modules/UI/videolayout/LargeVideo.js @@ -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; /** @@ -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 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); @@ -355,7 +356,8 @@ export default class LargeVideoManager { this.containers = {}; this.state = VideoContainerType; - this.videoContainer = new VideoContainer(() => this.resizeContainer(VideoContainerType)); + this.videoContainer + = new VideoContainer(() => this.resizeContainer(VideoContainerType)); this.addContainer(VideoContainerType, this.videoContainer); this.width = 0; @@ -368,22 +370,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) { @@ -457,7 +463,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(); });