Browse Source

feat(background alpha) Set background transparency

master
hmuresan 4 years ago
parent
commit
f7c0d4f1fe

+ 3
- 0
config.js View File

@@ -677,6 +677,9 @@ var config = {
677 677
     */
678 678
     // dynamicBrandingUrl: '',
679 679
 
680
+    // Sets the background transparency level. '0' is fully transparent, '1' is opaque.
681
+    // backgroundAlpha: 1,
682
+
680 683
     // The URL of the moderated rooms microservice, if available. If it
681 684
     // is present, a link to the service will be rendered on the welcome page,
682 685
     // otherwise the app doesn't render it.

+ 8
- 0
modules/UI/UI.js View File

@@ -7,6 +7,7 @@ import EventEmitter from 'events';
7 7
 import Logger from 'jitsi-meet-logger';
8 8
 
9 9
 import { isMobileBrowser } from '../../react/features/base/environment/utils';
10
+import { setColorAlpha } from '../../react/features/base/util';
10 11
 import { toggleChat } from '../../react/features/chat';
11 12
 import { setDocumentUrl } from '../../react/features/etherpad';
12 13
 import { setFilmstripVisible } from '../../react/features/filmstrip';
@@ -129,6 +130,13 @@ UI.start = function() {
129 130
         $('body').addClass('mobile-browser');
130 131
     } else {
131 132
         $('body').addClass('desktop-browser');
133
+
134
+        if (config.backgroundAlpha !== undefined) {
135
+            const backgroundColor = $('body').css('background-color');
136
+            const alphaColor = setColorAlpha(backgroundColor, config.backgroundAlpha);
137
+
138
+            $('body').css('background-color', alphaColor);
139
+        }
132 140
     }
133 141
 
134 142
     if (config.iAmRecorder) {

+ 1
- 0
react/features/base/config/configWhitelist.js View File

@@ -17,6 +17,7 @@ export default [
17 17
     'audioLevelsInterval',
18 18
     'apiLogLevels',
19 19
     'avgRtpStatsN',
20
+    'backgroundAlpha',
20 21
 
21 22
     /**
22 23
      * The display name of the CallKit call representing the conference/meeting

+ 59
- 0
react/features/base/util/helpers.js View File

@@ -126,3 +126,62 @@ export function reportError(e: Object, msg: string = '') {
126 126
     console.error(msg, e);
127 127
     window.onerror && window.onerror(msg, null, null, null, e);
128 128
 }
129
+
130
+/**
131
+ * Adds alpha to a color css string.
132
+ *
133
+ * @param {string} color - The color string either in rgb... Or #... Format.
134
+ * @param {number} opacity -The opacity(alpha) to apply to the color. Can take a value between 0 and 1, including.
135
+ * @returns {string} - The color with applied alpha.
136
+ */
137
+export function setColorAlpha(color: string, opacity: number) {
138
+    if (!color) {
139
+        return `rgba(0, 0, 0, ${opacity})`;
140
+    }
141
+
142
+    let b, g, r;
143
+
144
+    try {
145
+        if (color.startsWith('rgb')) {
146
+            [ r, g, b ] = color.split('(')[1].split(')')[0].split(',').map(c => c.trim());
147
+        } else if (color.startsWith('#')) {
148
+            if (color.length === 4) {
149
+                [ r, g, b ] = parseShorthandColor(color);
150
+            } else {
151
+                r = parseInt(color.substring(1, 3), 16);
152
+                g = parseInt(color.substring(3, 5), 16);
153
+                b = parseInt(color.substring(5, 7), 16);
154
+            }
155
+        } else {
156
+            return color;
157
+        }
158
+
159
+        return `rgba(${r}, ${g}, ${b}, ${opacity})`;
160
+    } catch {
161
+        return color;
162
+    }
163
+}
164
+
165
+/**
166
+ * Gets the hexa rgb values for a shorthand css color.
167
+ *
168
+ * @param {string} color -
169
+ * @returns {Array<number>} - Array containing parsed r, g, b values of the color.
170
+ */
171
+function parseShorthandColor(color) {
172
+    let b, g, r;
173
+
174
+    r = color.substring(1, 2);
175
+    r += r;
176
+    r = parseInt(r, 16);
177
+
178
+    g = color.substring(2, 3);
179
+    g += g;
180
+    g = parseInt(g, 16);
181
+
182
+    b = color.substring(3, 4);
183
+    b += b;
184
+    b = parseInt(b, 16);
185
+
186
+    return [ r, g, b ];
187
+}

+ 40
- 1
react/features/conference/components/web/Conference.js View File

@@ -8,6 +8,7 @@ import { getConferenceNameForTitle } from '../../../base/conference';
8 8
 import { connect, disconnect } from '../../../base/connection';
9 9
 import { translate } from '../../../base/i18n';
10 10
 import { connect as reactReduxConnect } from '../../../base/redux';
11
+import { setColorAlpha } from '../../../base/util';
11 12
 import { Chat } from '../../../chat';
12 13
 import { Filmstrip } from '../../../filmstrip';
13 14
 import { CalleeInfoContainer } from '../../../invite';
@@ -61,6 +62,11 @@ const LAYOUT_CLASSNAMES = {
61 62
  */
62 63
 type Props = AbstractProps & {
63 64
 
65
+    /**
66
+     * The alpha(opacity) of the background
67
+     */
68
+    _backgroundAlpha: number,
69
+
64 70
     /**
65 71
      * Whether the local participant is recording the conference.
66 72
      */
@@ -98,6 +104,7 @@ class Conference extends AbstractConference<Props, *> {
98 104
     _onFullScreenChange: Function;
99 105
     _onShowToolbar: Function;
100 106
     _originalOnShowToolbar: Function;
107
+    _setBackground: Function;
101 108
 
102 109
     /**
103 110
      * Initializes a new Conference instance.
@@ -121,6 +128,7 @@ class Conference extends AbstractConference<Props, *> {
121 128
 
122 129
         // Bind event handler so it is only bound once for every instance.
123 130
         this._onFullScreenChange = this._onFullScreenChange.bind(this);
131
+        this._setBackground = this._setBackground.bind(this);
124 132
     }
125 133
 
126 134
     /**
@@ -186,7 +194,8 @@ class Conference extends AbstractConference<Props, *> {
186 194
             <div
187 195
                 className = { _layoutClassName }
188 196
                 id = 'videoconference_page'
189
-                onMouseMove = { this._onShowToolbar }>
197
+                onMouseMove = { this._onShowToolbar }
198
+                ref = { this._setBackground }>
190 199
 
191 200
                 <Notice />
192 201
                 <div id = 'videospace'>
@@ -208,6 +217,35 @@ class Conference extends AbstractConference<Props, *> {
208 217
         );
209 218
     }
210 219
 
220
+    /**
221
+     * Sets custom background opacity based on config. It also applies the
222
+     * opacity on parent element, as the parent element is not accessible directly,
223
+     * only though it's child.
224
+     *
225
+     * @param {Object} element - The DOM element for which to apply opacity.
226
+     *
227
+     * @private
228
+     * @returns {void}
229
+     */
230
+    _setBackground(element) {
231
+        if (!element) {
232
+            return;
233
+        }
234
+
235
+        if (this.props._backgroundAlpha !== undefined) {
236
+            const elemColor = element.style.background;
237
+            const alphaElemColor = setColorAlpha(elemColor, this.props._backgroundAlpha);
238
+
239
+            element.style.background = alphaElemColor;
240
+            if (element.parentElement) {
241
+                const parentColor = element.parentElement.style.background;
242
+                const alphaParentColor = setColorAlpha(parentColor, this.props._backgroundAlpha);
243
+
244
+                element.parentElement.style.background = alphaParentColor;
245
+            }
246
+        }
247
+    }
248
+
211 249
     /**
212 250
      * Updates the Redux state when full screen mode has been enabled or
213 251
      * disabled.
@@ -265,6 +303,7 @@ function _mapStateToProps(state) {
265 303
     return {
266 304
         ...abstractMapStateToProps(state),
267 305
         _iAmRecorder: state['features/base/config'].iAmRecorder,
306
+        _backgroundAlpha: state['features/base/config'].backgroundAlpha,
268 307
         _isLobbyScreenVisible: state['features/base/dialog']?.component === LobbyScreen,
269 308
         _layoutClassName: LAYOUT_CLASSNAMES[getCurrentLayout(state)],
270 309
         _roomName: getConferenceNameForTitle(state),

+ 13
- 0
react/features/large-video/components/LargeVideo.web.js View File

@@ -4,6 +4,7 @@ import React, { Component } from 'react';
4 4
 
5 5
 import { Watermarks } from '../../base/react';
6 6
 import { connect } from '../../base/redux';
7
+import { setColorAlpha } from '../../base/util';
7 8
 import { Subject } from '../../conference';
8 9
 import { fetchCustomBrandingData } from '../../dynamic-branding';
9 10
 import { Captions } from '../../subtitles/';
@@ -12,6 +13,11 @@ declare var interfaceConfig: Object;
12 13
 
13 14
 type Props = {
14 15
 
16
+    /**
17
+     * The alpha(opacity) of the background
18
+     */
19
+    _backgroundAlpha: number,
20
+
15 21
     /**
16 22
      * The user selected background color.
17 23
      */
@@ -121,6 +127,12 @@ class LargeVideo extends Component<Props> {
121 127
 
122 128
         styles.backgroundColor = _customBackgroundColor || interfaceConfig.DEFAULT_BACKGROUND;
123 129
 
130
+        if (this.props._backgroundAlpha !== undefined) {
131
+            const alphaColor = setColorAlpha(styles.backgroundColor, this.props._backgroundAlpha);
132
+
133
+            styles.backgroundColor = alphaColor;
134
+        }
135
+
124 136
         if (_customBackgroundImageUrl) {
125 137
             styles.backgroundImage = `url(${_customBackgroundImageUrl})`;
126 138
             styles.backgroundSize = 'cover';
@@ -144,6 +156,7 @@ function _mapStateToProps(state) {
144 156
     const { isOpen: isChatOpen } = state['features/chat'];
145 157
 
146 158
     return {
159
+        _backgroundAlpha: state['features/base/config'].backgroundAlpha,
147 160
         _customBackgroundColor: backgroundColor,
148 161
         _customBackgroundImageUrl: backgroundImageUrl,
149 162
         _isChatOpen: isChatOpen,

Loading…
Cancel
Save