From f3dbeea09172c456d56d6b86c3766de0654749a3 Mon Sep 17 00:00:00 2001 From: Ilya Daynatovich Date: Fri, 11 Nov 2016 16:05:41 +0200 Subject: [PATCH 1/3] Make filmstrip indicators to resize dynamically --- css/_variables.scss | 4 +- css/_videolayout_default.scss | 141 ++++++++++++++-------------- modules/UI/videolayout/FilmStrip.js | 102 +++++++++++++++----- 3 files changed, 152 insertions(+), 95 deletions(-) diff --git a/css/_variables.scss b/css/_variables.scss index 117fb2a14..a473813c2 100644 --- a/css/_variables.scss +++ b/css/_variables.scss @@ -13,8 +13,8 @@ $hangupFontSize: 2em; $defaultToolbarSize: 50px; // Video layout. -$thumbnailToolbarHeight: 22px; -$thumbnailIndicatorBorder: 0px; +$thumbnailToolbarHeight: 3em; +$thumbnailIndicatorBorder: 0; $thumbnailIndicatorSize: $thumbnailToolbarHeight; $thumbnailVideoMargin: 2px; diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss index dbc9afb47..56160ce9f 100644 --- a/css/_videolayout_default.scss +++ b/css/_videolayout_default.scss @@ -47,7 +47,76 @@ top: 0; padding: $toolbarPadding; padding-bottom: 0; - height: $thumbnailIndicatorSize + $toolbarPadding; + + span.indicator { + position: relative; + font-size: 8px; + text-align: center; + line-height: $thumbnailToolbarHeight; + display: none; + padding: 0; + margin-right: em(5, 8); + float: left; + @include circle($thumbnailIndicatorSize); + box-sizing: border-box; + z-index: 3; + background: $dominantSpeakerBg; + color: $thumbnailPictogramColor; + border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor; + + &:last-child { + margin-right: 0; + } + + .indicatoricon { + position: absolute; + top: 50%; + left: 0; + @include transform(translateY(-50%)); + width: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; + height: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; + line-height: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; + } + + .connection { + position: relative; + margin: 0 auto; + width: 12px; + height: 8px; + + &_empty + { + @include topLeft(); + max-width: 12px; + width: 12px; + color: #8B8B8B;/*#FFFFFF*/ + overflow: hidden; + } + + &_lost + { + @include topLeft(); + max-width: 12px; + width: 12px; + color: #8B8B8B; + overflow: visible; + } + + &_full + { + @include topLeft(); + max-width: 12px; + width: 12px; + color: #FFFFFF;/*#15A1ED*/ + overflow: hidden; + } + } + + .icon-connection, + .icon-connection-lost { + font-size: 1em; + } + } } .videocontainer__hoverOverlay { @@ -217,72 +286,6 @@ background: $connectionIndicatorBg; } -.videocontainer__toptoolbar span.indicator { - position: relative; - font-size: 8pt; - text-align: center; - line-height: $thumbnailToolbarHeight; - display: none; - padding: 0; - margin-right: 5px; - float: left; - @include circle($thumbnailIndicatorSize); - box-sizing: border-box; - z-index: 3; - background: $dominantSpeakerBg; - color: $thumbnailPictogramColor; - border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor; - - .indicatoricon { - position: absolute; - top: 50%; - left: 0; - @include transform(translateY(-50%)); - width: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; - height: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; - line-height: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; - } - - .connection { - position: relative; - margin: 0 auto; - width: 12px; - height: 8px; - - &_empty - { - @include topLeft(); - max-width: 12px; - width: 12px; - color: #8B8B8B;/*#FFFFFF*/ - overflow: hidden; - } - - &_lost - { - @include topLeft(); - max-width: 12px; - width: 12px; - color: #8B8B8B; - overflow: visible; - } - - &_full - { - @include topLeft(); - max-width: 12px; - width: 12px; - color: #FFFFFF;/*#15A1ED*/ - overflow: hidden; - } - } - - .icon-connection, - .icon-connection-lost { - font-size: 6pt; - } -} - .remotevideomenu { display: inline-block; @@ -400,8 +403,10 @@ .userAvatar { @include maxSize(60px); - @include circle(50%); @include absoluteAligning(); + border-radius: 50%; + height: 50%; + width: auto; } .sharedVideoAvatar { diff --git a/modules/UI/videolayout/FilmStrip.js b/modules/UI/videolayout/FilmStrip.js index 2f0a24300..18e0dce1f 100644 --- a/modules/UI/videolayout/FilmStrip.js +++ b/modules/UI/videolayout/FilmStrip.js @@ -3,6 +3,15 @@ import UIEvents from "../../../service/UI/UIEvents"; import UIUtil from "../util/UIUtil"; +/** + * Contains sizes of thumbnails + * @type {{SMALL: number, MEDIUM: number}} + */ +const ThumbnailSizes = { + SMALL: 60, + MEDIUM: 80 +}; + const FilmStrip = { /** * @@ -368,39 +377,82 @@ const FilmStrip = { return new Promise(resolve => { let thumbs = this.getThumbs(!forceUpdate); - if(thumbs.localThumb) - thumbs.localThumb.animate({ - height: local.thumbHeight, - width: local.thumbWidth - }, { - queue: false, - duration: animate ? 500 : 0, - complete: resolve - }); - if(thumbs.remoteThumbs) - thumbs.remoteThumbs.animate({ - height: remote.thumbHeight, - width: remote.thumbWidth - }, { - queue: false, - duration: animate ? 500 : 0, - complete: resolve - }); + let promises = []; - this.filmStrip.animate({ - // adds 2 px because of small video 1px border - height: remote.thumbHeight + 2 - }, { - queue: false, - duration: animate ? 500 : 0 - }); + if(thumbs.localThumb) { + promises.push(new Promise((resolve) => { + thumbs.localThumb.animate({ + height: local.thumbHeight, + width: local.thumbWidth + }, this._getAnimateOptions(animate, resolve)); + })); + } + if(thumbs.remoteThumbs) { + promises.push(new Promise((resolve) => { + thumbs.remoteThumbs.animate({ + height: remote.thumbHeight, + width: remote.thumbWidth + }, this._getAnimateOptions(animate, resolve)); + })); + } + promises.push(new Promise((resolve) => { + this.filmStrip.animate({ + // adds 2 px because of small video 1px border + height: remote.thumbHeight + 2 + }, this._getAnimateOptions(animate, resolve)); + })); + promises.push(new Promise((resolve) => { + let fontSize = this._getIndicatorFontSize(remote.thumbHeight); + this.filmStrip.find('.indicator').animate({ + fontSize + }, this._getAnimateOptions(animate, resolve)); + })); if (!animate) { resolve(); } + + Promise.all(promises).then(resolve); }); }, + /** + * Helper method. Returns options for jQuery animation + * @param animate {Boolean} - animation flag + * @param cb {Function} - complete callback + * @returns {Object} - animation options object + * @private + */ + _getAnimateOptions(animate, cb = $.noop) { + return { + queue: false, + duration: animate ? 500 : 0, + complete: cb + }; + }, + + /** + * Returns font size for indicators according to current + * height of thumbnail + * @param height + * @returns {Number} - font size for current height + * @private + */ + _getIndicatorFontSize(height) { + const { SMALL, MEDIUM } = ThumbnailSizes; + let fontSize; + + if (height <= SMALL) { + fontSize = 5; + } else if (height > SMALL && height <= MEDIUM) { + fontSize = 6; + } else { + fontSize = 8; + } + + return fontSize; + }, + /** * Returns thumbnails of the filmstrip * @param only_visible From 3bd4f1d5d846040730585f8723caf8b8b20950a4 Mon Sep 17 00:00:00 2001 From: Ilya Daynatovich Date: Fri, 11 Nov 2016 17:09:07 +0200 Subject: [PATCH 2/3] Updated layout --- css/_variables.scss | 4 +- css/_videolayout_default.scss | 194 +++++++++++++++------------- modules/UI/videolayout/FilmStrip.js | 35 ++--- 3 files changed, 127 insertions(+), 106 deletions(-) diff --git a/css/_variables.scss b/css/_variables.scss index a473813c2..bcb237171 100644 --- a/css/_variables.scss +++ b/css/_variables.scss @@ -13,9 +13,9 @@ $hangupFontSize: 2em; $defaultToolbarSize: 50px; // Video layout. -$thumbnailToolbarHeight: 3em; +$thumbnailToolbarHeight: 22px; $thumbnailIndicatorBorder: 0; -$thumbnailIndicatorSize: $thumbnailToolbarHeight; +$thumbnailIndicatorSize: 3em; $thumbnailVideoMargin: 2px; /** diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss index 56160ce9f..de86b1be0 100644 --- a/css/_videolayout_default.scss +++ b/css/_videolayout_default.scss @@ -22,110 +22,128 @@ height: 100%; background-color: black; } -} -/** - * The toolbar of the video thumbnail. - */ -.videocontainer__toolbar, -.videocontainer__toptoolbar { - position: absolute; - left: 0; - z-index: 3; - width: 100%; - box-sizing: border-box; // Includes the padding in the 100% width. -} - -.videocontainer__toolbar { - bottom: 0; - padding: 0 5px 0 5px; - height: $thumbnailToolbarHeight; -} - -.videocontainer__toptoolbar { - $toolbarPadding: 5px; - top: 0; - padding: $toolbarPadding; - padding-bottom: 0; - - span.indicator { - position: relative; - font-size: 8px; - text-align: center; - line-height: $thumbnailToolbarHeight; - display: none; - padding: 0; - margin-right: em(5, 8); - float: left; - @include circle($thumbnailIndicatorSize); - box-sizing: border-box; + /** + * The toolbar of the video thumbnail. + */ + &__toolbar, + &__toptoolbar { + position: absolute; + left: 0; z-index: 3; - background: $dominantSpeakerBg; - color: $thumbnailPictogramColor; - border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor; + width: 100%; + box-sizing: border-box; // Includes the padding in the 100% width. + } - &:last-child { - margin-right: 0; - } + &__toolbar { + bottom: 0; + padding: 0 5px 0 5px; + height: $thumbnailToolbarHeight; + } - .indicatoricon { - position: absolute; - top: 50%; - left: 0; - @include transform(translateY(-50%)); - width: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; - height: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; - line-height: $thumbnailIndicatorSize - 2 * $thumbnailIndicatorBorder; - } + &__toptoolbar { + $toolbarPadding: 5px; + top: 0; + padding: $toolbarPadding; + padding-bottom: 0; - .connection { + span.indicator { position: relative; - margin: 0 auto; - width: 12px; - height: 8px; + font-size: 8px; + text-align: center; + line-height: $thumbnailIndicatorSize; + display: none; + padding: 0; + margin-right: em(5, 8); + float: left; + @include circle($thumbnailIndicatorSize); + box-sizing: border-box; + z-index: 3; + background: $dominantSpeakerBg; + color: $thumbnailPictogramColor; + border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor; - &_empty - { - @include topLeft(); - max-width: 12px; - width: 12px; - color: #8B8B8B;/*#FFFFFF*/ - overflow: hidden; + &:last-child { + margin-right: 0; } - &_lost - { - @include topLeft(); - max-width: 12px; - width: 12px; - color: #8B8B8B; - overflow: visible; + .indicatoricon { + position: absolute; + top: 50%; + left: 0; + @include transform(translateY(-50%)); + width: 100%; } - &_full - { - @include topLeft(); - max-width: 12px; + .connection { + position: relative; + margin: 0 auto; width: 12px; - color: #FFFFFF;/*#15A1ED*/ - overflow: hidden; - } - } + height: 8px; - .icon-connection, - .icon-connection-lost { - font-size: 1em; + &_empty + { + @include topLeft(); + max-width: 12px; + width: 12px; + color: #8B8B8B;/*#FFFFFF*/ + overflow: hidden; + } + + &_lost + { + @include topLeft(); + max-width: 12px; + width: 12px; + color: #8B8B8B; + overflow: visible; + } + + &_full + { + @include topLeft(); + max-width: 12px; + width: 12px; + color: #FFFFFF;/*#15A1ED*/ + overflow: hidden; + } + } + + .icon-connection, + .icon-connection-lost { + font-size: 1em; + } } } -} -.videocontainer__hoverOverlay { - position: relative; - width: 100%; - height: 100%; - visibility: hidden; - background: rgba(0,0,0,.6); - z-index: 2; + &_small { + span.indicator { + font-size: 5px; + + .connection { + height: 5px; + } + } + } + + &_medium { + span.indicator { + font-size: 6px; + + .connection { + height: 6px; + } + } + } + + &__hoverOverlay { + position: relative; + width: 100%; + height: 100%; + visibility: hidden; + background: rgba(0,0,0,.6); + z-index: 2; + } } #localVideoWrapper { diff --git a/modules/UI/videolayout/FilmStrip.js b/modules/UI/videolayout/FilmStrip.js index 18e0dce1f..ccc3cd160 100644 --- a/modules/UI/videolayout/FilmStrip.js +++ b/modules/UI/videolayout/FilmStrip.js @@ -401,12 +401,8 @@ const FilmStrip = { height: remote.thumbHeight + 2 }, this._getAnimateOptions(animate, resolve)); })); - promises.push(new Promise((resolve) => { - let fontSize = this._getIndicatorFontSize(remote.thumbHeight); - this.filmStrip.find('.indicator').animate({ - fontSize - }, this._getAnimateOptions(animate, resolve)); - })); + + this._setThumbnailsClasses(remote.thumbHeight); if (!animate) { resolve(); @@ -432,25 +428,32 @@ const FilmStrip = { }, /** - * Returns font size for indicators according to current - * height of thumbnail + * Set thumbnail classes according to the current size of thumbnail * @param height - * @returns {Number} - font size for current height * @private */ - _getIndicatorFontSize(height) { + _setThumbnailsClasses(height) { const { SMALL, MEDIUM } = ThumbnailSizes; - let fontSize; + const { localThumb, remoteThumbs } = this.getThumbs(); + let smallClass = 'videocontainer_small'; + let mediumClass = 'videocontainer_medium'; + let className = ''; if (height <= SMALL) { - fontSize = 5; + className = smallClass; } else if (height > SMALL && height <= MEDIUM) { - fontSize = 6; - } else { - fontSize = 8; + className = mediumClass; } - return fontSize; + localThumb + .removeClass(`${smallClass} ${mediumClass}`) + .addClass(className); + + if (remoteThumbs) { + remoteThumbs + .removeClass(`${smallClass} ${mediumClass}`) + .addClass(className); + } }, /** From 9bc24e1caa42b90ff12a1d47b38e93ca8d10faa9 Mon Sep 17 00:00:00 2001 From: Ilya Daynatovich Date: Mon, 14 Nov 2016 12:45:28 +0200 Subject: [PATCH 3/3] Fix aligning of indicator icon; Update logic for dynamically change of thumb indicators via font-size --- css/_mixins.scss | 2 +- css/_videolayout_default.scss | 39 +++------------------ modules/UI/util/UIUtil.js | 53 +++++++++++++++++++++++++++++ modules/UI/videolayout/FilmStrip.js | 47 +++++-------------------- 4 files changed, 66 insertions(+), 75 deletions(-) diff --git a/css/_mixins.scss b/css/_mixins.scss index c8914a8db..acf7c9679 100644 --- a/css/_mixins.scss +++ b/css/_mixins.scss @@ -63,7 +63,7 @@ top: 50%; left: 50%; position: absolute; - @include transform(translate(-50%, -50%)) + @include transform(translate(-50%, -50%)); } /** diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss index de86b1be0..a8679b5dc 100644 --- a/css/_videolayout_default.scss +++ b/css/_videolayout_default.scss @@ -68,33 +68,24 @@ } .indicatoricon { - position: absolute; - top: 50%; - left: 0; - @include transform(translateY(-50%)); - width: 100%; + @include absoluteAligning(); } .connection { position: relative; + display: inline-block; margin: 0 auto; - width: 12px; - height: 8px; + left: 0; + @include transform(translate(0, -50%)); &_empty { - @include topLeft(); - max-width: 12px; - width: 12px; color: #8B8B8B;/*#FFFFFF*/ overflow: hidden; } &_lost { - @include topLeft(); - max-width: 12px; - width: 12px; color: #8B8B8B; overflow: visible; } @@ -102,8 +93,6 @@ &_full { @include topLeft(); - max-width: 12px; - width: 12px; color: #FFFFFF;/*#15A1ED*/ overflow: hidden; } @@ -116,26 +105,6 @@ } } - &_small { - span.indicator { - font-size: 5px; - - .connection { - height: 5px; - } - } - } - - &_medium { - span.indicator { - font-size: 6px; - - .connection { - height: 6px; - } - } - } - &__hoverOverlay { position: relative; width: 100%; diff --git a/modules/UI/util/UIUtil.js b/modules/UI/util/UIUtil.js index 64dacaa0c..c35a17b96 100644 --- a/modules/UI/util/UIUtil.js +++ b/modules/UI/util/UIUtil.js @@ -27,6 +27,25 @@ const SHOW_CLASSES = { 'list-item': 'show-list-item' }; +/** + * Contains sizes of thumbnails + * @type {{SMALL: number, MEDIUM: number}} + */ +const ThumbnailSizes = { + SMALL: 60, + MEDIUM: 80 +}; + +/** + * Contains font sizes for thumbnail indicators + * @type {{SMALL: number, MEDIUM: number}} + */ +const IndicatorFontSizes = { + SMALL: 5, + MEDIUM: 6, + NORMAL: 8 +}; + /** * Created by hristo on 12/22/14. */ @@ -463,6 +482,7 @@ const SHOW_CLASSES = { if (indicators.length <= 0) { indicatorSpan = document.createElement('span'); + indicatorSpan.className = 'indicator'; indicatorSpan.id = indicatorId; @@ -475,6 +495,8 @@ const SHOW_CLASSES = { APP.translation.translateElement($(indicatorSpan)); } + this._resizeIndicator(indicatorSpan); + document.getElementById(videoSpanId) .querySelector('.videocontainer__toptoolbar') .appendChild(indicatorSpan); @@ -483,6 +505,37 @@ const SHOW_CLASSES = { } return indicatorSpan; + }, + + /** + * Resizing indicator element passing via argument + * according to the current thumbnail size + * @param {HTMLElement} indicator - indicator element + * @private + */ + _resizeIndicator(indicator) { + let height = $('#localVideoContainer').height(); + let fontSize = this.getIndicatorFontSize(height); + $(indicator).css('font-size', fontSize); + }, + + /** + * Returns font size for indicators according to current + * height of thumbnail + * @param {Number} - height - current height of thumbnail + * @returns {Number} - font size for current height + */ + getIndicatorFontSize(height) { + const { SMALL, MEDIUM } = ThumbnailSizes; + let fontSize = IndicatorFontSizes.NORMAL; + + if (height <= SMALL) { + fontSize = IndicatorFontSizes.SMALL; + } else if (height > SMALL && height <= MEDIUM) { + fontSize = IndicatorFontSizes.MEDIUM; + } + + return fontSize; } }; diff --git a/modules/UI/videolayout/FilmStrip.js b/modules/UI/videolayout/FilmStrip.js index ccc3cd160..b1515f885 100644 --- a/modules/UI/videolayout/FilmStrip.js +++ b/modules/UI/videolayout/FilmStrip.js @@ -3,15 +3,6 @@ import UIEvents from "../../../service/UI/UIEvents"; import UIUtil from "../util/UIUtil"; -/** - * Contains sizes of thumbnails - * @type {{SMALL: number, MEDIUM: number}} - */ -const ThumbnailSizes = { - SMALL: 60, - MEDIUM: 80 -}; - const FilmStrip = { /** * @@ -402,7 +393,14 @@ const FilmStrip = { }, this._getAnimateOptions(animate, resolve)); })); - this._setThumbnailsClasses(remote.thumbHeight); + promises.push(new Promise(() => { + let { localThumb } = this.getThumbs(); + let height = localThumb.height(); + let fontSize = UIUtil.getIndicatorFontSize(height); + this.filmStrip.find('.indicator').animate({ + fontSize + }, this._getAnimateOptions(animate, resolve)); + })); if (!animate) { resolve(); @@ -427,35 +425,6 @@ const FilmStrip = { }; }, - /** - * Set thumbnail classes according to the current size of thumbnail - * @param height - * @private - */ - _setThumbnailsClasses(height) { - const { SMALL, MEDIUM } = ThumbnailSizes; - const { localThumb, remoteThumbs } = this.getThumbs(); - let smallClass = 'videocontainer_small'; - let mediumClass = 'videocontainer_medium'; - let className = ''; - - if (height <= SMALL) { - className = smallClass; - } else if (height > SMALL && height <= MEDIUM) { - className = mediumClass; - } - - localThumb - .removeClass(`${smallClass} ${mediumClass}`) - .addClass(className); - - if (remoteThumbs) { - remoteThumbs - .removeClass(`${smallClass} ${mediumClass}`) - .addClass(className); - } - }, - /** * Returns thumbnails of the filmstrip * @param only_visible