Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 6205cbb

Browse files
authored
Merge pull request #6659 from matrix-org/palid/fix/backdrop-blur
Optimize background image from avatar on left panel
2 parents d15ef70 + 618cc70 commit 6205cbb

File tree

13 files changed

+86
-258
lines changed

13 files changed

+86
-258
lines changed

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
"cheerio": "^1.0.0-rc.9",
6565
"classnames": "^2.2.6",
6666
"commonmark": "^0.29.3",
67-
"context-filter-polyfill": "^0.2.4",
6867
"counterpart": "^0.18.6",
6968
"diff-dom": "^4.2.2",
7069
"diff-match-patch": "^1.0.5",
@@ -196,7 +195,6 @@
196195
"decoderWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js",
197196
"decoderWorker\\.min\\.wasm": "<rootDir>/__mocks__/empty.js",
198197
"waveWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js",
199-
"context-filter-polyfill": "<rootDir>/__mocks__/empty.js",
200198
"workers/(.+)\\.worker\\.ts": "<rootDir>/__mocks__/workerMock.js",
201199
"RecorderWorklet": "<rootDir>/__mocks__/empty.js"
202200
},

res/css/structures/_BackdropPanel.scss

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,15 @@ limitations under the License.
2121
height: 100vh;
2222
width: 100%;
2323
overflow: hidden;
24-
25-
&::before {
26-
content: " ";
27-
position: absolute;
28-
left: 0;
29-
top: 0;
30-
height: 100vh;
31-
width: 100%;
32-
background-color: var(--lp-background-overlay);
33-
}
24+
filter: blur(var(--lp-background-blur));
3425
}
3526

36-
.mx_BackdropPanel--canvas {
27+
.mx_BackdropPanel--image {
3728
position: absolute;
3829
top: 0;
3930
left: 0;
4031
min-height: 100%;
4132
z-index: 0;
4233
pointer-events: none;
4334
overflow: hidden;
44-
45-
&:nth-of-type(2n-1) {
46-
opacity: 0.2;
47-
}
48-
&:nth-of-type(2n) {
49-
opacity: 0.1;
50-
}
5135
}

res/css/structures/_GroupFilterPanel.scss

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,23 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
.mx_MatrixChat--with-avatar {
18-
.mx_GroupFilterPanel {
19-
background-color: transparent;
20-
}
17+
$groupFilterPanelWidth: 56px; // only applies in this file, used for calculations
18+
19+
.mx_GroupFilterPanelContainer {
20+
flex-grow: 0;
21+
flex-shrink: 0;
22+
width: $groupFilterPanelWidth;
23+
height: 100%;
24+
25+
// Create another flexbox so the GroupFilterPanel fills the container
26+
display: flex;
27+
flex-direction: column;
28+
29+
// GroupFilterPanel handles its own CSS
2130
}
2231

2332
.mx_GroupFilterPanel {
33+
z-index: 1;
2434
background-color: $groupFilterPanel-bg-color;
2535
flex: 1;
2636
cursor: pointer;

res/css/structures/_LeftPanel.scss

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
$groupFilterPanelWidth: 56px; // only applies in this file, used for calculations
1817
$roomListCollapsedWidth: 68px;
1918

2019
.mx_MatrixChat--with-avatar {
@@ -27,8 +26,17 @@ $roomListCollapsedWidth: 68px;
2726
.mx_LeftPanel_wrapper {
2827
display: flex;
2928
max-width: 50%;
29+
30+
.mx_LeftPanel_wrapper--user {
31+
background-color: $roomlist-bg-color;
32+
display: flex;
33+
overflow: hidden;
34+
position: relative;
35+
}
3036
}
3137

38+
39+
3240
.mx_LeftPanel {
3341
background-color: $roomlist-bg-color;
3442
// TODO decrease this once Spaces launches as it'll no longer need to include the 56px Community Panel
@@ -39,19 +47,6 @@ $roomListCollapsedWidth: 68px;
3947
contain: content;
4048
position: relative;
4149

42-
.mx_LeftPanel_GroupFilterPanelContainer {
43-
flex-grow: 0;
44-
flex-shrink: 0;
45-
flex-basis: $groupFilterPanelWidth;
46-
height: 100%;
47-
48-
// Create another flexbox so the GroupFilterPanel fills the container
49-
display: flex;
50-
flex-direction: column;
51-
52-
// GroupFilterPanel handles its own CSS
53-
}
54-
5550
// Note: The 'room list' in this context is actually everything that isn't the tag
5651
// panel, such as the menu options, breadcrumbs, filtering, etc
5752
.mx_LeftPanel_roomListContainer {

res/css/structures/_SpacePanel.scss

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,14 @@ $activeBorderTransparentGap: 1px;
2222
$activeBackgroundColor: $roomtile-selected-bg-color;
2323
$activeBorderColor: $secondary-fg-color;
2424

25-
.mx_MatrixChat--with-avatar {
26-
.mx_SpacePanel {
27-
background-color: transparent;
28-
}
29-
}
30-
3125
.mx_SpacePanel {
3226
background-color: $groupFilterPanel-bg-color;
3327
flex: 0 0 auto;
3428
padding: 0;
3529
margin: 0;
3630
position: relative;
31+
// Fix for the blurred avatar-background
32+
z-index: 1;
3733

3834
// Create another flexbox so the Panel fills the container
3935
display: flex;

res/themes/dark/css/_dark.scss

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,7 @@ $appearance-tab-border-color: $room-highlight-color;
240240

241241
// blur amounts for left left panel (only for element theme)
242242
:root {
243-
--llp-background-blur: 160px;
244-
--lp-background-blur: 90px;
245-
--lp-background-overlay: rgba(255, 255, 255, 0.055);
243+
--lp-background-blur: 45px;
246244
}
247245

248246
$composer-shadow-color: rgba(0, 0, 0, 0.28);

res/themes/light/css/_light.scss

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,7 @@ $appearance-tab-border-color: $input-darker-bg-color;
363363

364364
// blur amounts for left left panel (only for element theme)
365365
:root {
366-
--llp-background-blur: 120px;
367-
--lp-background-blur: 60px;
368-
--lp-background-overlay: rgba(0, 0, 0, 0.055);
366+
--lp-background-blur: 30px;
369367
}
370368
$composer-shadow-color: rgba(0, 0, 0, 0.04);
371369

src/components/structures/BackdropPanel.tsx

Lines changed: 22 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -14,153 +14,31 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import React, { createRef } from "react";
18-
import "context-filter-polyfill";
19-
20-
import UIStore from "../../stores/UIStore";
17+
import React, { CSSProperties } from "react";
2118

2219
interface IProps {
23-
backgroundImage?: CanvasImageSource;
24-
}
25-
26-
interface IState {
27-
// Left Panel image
28-
lpImage?: string;
29-
// Left-left panel image
30-
llpImage?: string;
20+
backgroundImage?: string;
21+
blurMultiplier?: number;
3122
}
3223

33-
export default class BackdropPanel extends React.PureComponent<IProps, IState> {
34-
private leftLeftPanelRef = createRef<HTMLCanvasElement>();
35-
private leftPanelRef = createRef<HTMLCanvasElement>();
36-
37-
private sizes = {
38-
leftLeftPanelWidth: 0,
39-
leftPanelWidth: 0,
40-
height: 0,
41-
};
42-
private style = getComputedStyle(document.documentElement);
43-
44-
public state: IState = {};
45-
46-
public componentDidMount() {
47-
UIStore.instance.on("SpacePanel", this.onResize);
48-
UIStore.instance.on("GroupFilterPanelContainer", this.onResize);
49-
this.onResize();
50-
}
51-
52-
public componentWillUnmount() {
53-
UIStore.instance.off("SpacePanel", this.onResize);
54-
UIStore.instance.on("GroupFilterPanelContainer", this.onResize);
55-
}
56-
57-
public componentDidUpdate(prevProps: IProps) {
58-
if (prevProps.backgroundImage !== this.props.backgroundImage) {
59-
this.setState({});
60-
this.onResize();
24+
export const BackdropPanel: React.FC<IProps> = ({ backgroundImage, blurMultiplier }) => {
25+
if (!backgroundImage) return null;
26+
27+
const styles: CSSProperties = {};
28+
if (blurMultiplier) {
29+
const rootStyle = getComputedStyle(document.documentElement);
30+
const blurValue = rootStyle.getPropertyValue('--lp-background-blur');
31+
const pixelsValue = blurValue.replace('px', '');
32+
const parsed = parseInt(pixelsValue, 10);
33+
if (!isNaN(parsed)) {
34+
styles.filter = `blur(${parsed * blurMultiplier}px)`;
6135
}
6236
}
63-
64-
private onResize = () => {
65-
if (this.props.backgroundImage) {
66-
const groupFilterPanelDimensions = UIStore.instance.getElementDimensions("GroupFilterPanelContainer");
67-
const spacePanelDimensions = UIStore.instance.getElementDimensions("SpacePanel");
68-
const roomListDimensions = UIStore.instance.getElementDimensions("LeftPanel");
69-
this.sizes = {
70-
leftLeftPanelWidth: spacePanelDimensions?.width ?? groupFilterPanelDimensions?.width ?? 0,
71-
leftPanelWidth: roomListDimensions?.width ?? 0,
72-
height: UIStore.instance.windowHeight,
73-
};
74-
this.refreshBackdropImage();
75-
}
76-
};
77-
78-
private refreshBackdropImage = (): void => {
79-
const leftLeftPanelContext = this.leftLeftPanelRef.current.getContext("2d");
80-
const leftPanelContext = this.leftPanelRef.current.getContext("2d");
81-
const { leftLeftPanelWidth, leftPanelWidth, height } = this.sizes;
82-
const width = leftLeftPanelWidth + leftPanelWidth;
83-
const { backgroundImage } = this.props;
84-
85-
const imageWidth = (backgroundImage as ImageBitmap).width;
86-
const imageHeight = (backgroundImage as ImageBitmap).height;
87-
88-
const contentRatio = imageWidth / imageHeight;
89-
const containerRatio = width / height;
90-
let resultHeight;
91-
let resultWidth;
92-
if (contentRatio > containerRatio) {
93-
resultHeight = height;
94-
resultWidth = height * contentRatio;
95-
} else {
96-
resultWidth = width;
97-
resultHeight = width / contentRatio;
98-
}
99-
100-
// This value has been chosen to be as close with rendering as the css-only
101-
// backdrop-filter: blur effect was, mostly takes effect for vertical pictures.
102-
const x = width * 0.1;
103-
const y = (height - resultHeight) / 2;
104-
105-
this.leftLeftPanelRef.current.width = leftLeftPanelWidth;
106-
this.leftLeftPanelRef.current.height = height;
107-
this.leftPanelRef.current.width = (window.screen.width * 0.5);
108-
this.leftPanelRef.current.height = height;
109-
110-
const spacesBlur = this.style.getPropertyValue('--llp-background-blur');
111-
const roomListBlur = this.style.getPropertyValue('--lp-background-blur');
112-
113-
leftLeftPanelContext.filter = `blur(${spacesBlur})`;
114-
leftPanelContext.filter = `blur(${roomListBlur})`;
115-
leftLeftPanelContext.drawImage(
116-
backgroundImage,
117-
0, 0,
118-
imageWidth, imageHeight,
119-
x,
120-
y,
121-
resultWidth,
122-
resultHeight,
123-
);
124-
leftPanelContext.drawImage(
125-
backgroundImage,
126-
0, 0,
127-
imageWidth, imageHeight,
128-
x - leftLeftPanelWidth,
129-
y,
130-
resultWidth,
131-
resultHeight,
132-
);
133-
this.setState({
134-
lpImage: this.leftPanelRef.current.toDataURL('image/jpeg', 1),
135-
llpImage: this.leftLeftPanelRef.current.toDataURL('image/jpeg', 1),
136-
137-
});
138-
};
139-
140-
public render() {
141-
if (!this.props.backgroundImage) return null;
142-
return <div className="mx_BackdropPanel">
143-
{ this.state?.llpImage !== 'data:,' && <img
144-
className="mx_BackdropPanel--canvas"
145-
src={this.state.llpImage} /> }
146-
147-
{ this.state?.lpImage !== 'data:,' && <img
148-
className="mx_BackdropPanel--canvas"
149-
src={this.state.lpImage} /> }
150-
<canvas
151-
ref={this.leftLeftPanelRef}
152-
className="mx_BackdropPanel--canvas"
153-
style={{
154-
display: this.state.lpImage ? 'none' : 'block',
155-
}}
156-
/>
157-
<canvas
158-
style={{
159-
display: this.state.lpImage ? 'none' : 'block',
160-
}}
161-
ref={this.leftPanelRef}
162-
className="mx_BackdropPanel--canvas"
163-
/>
164-
</div>;
165-
}
166-
}
37+
return <div className="mx_BackdropPanel">
38+
<img
39+
style={styles}
40+
className="mx_BackdropPanel--image"
41+
src={backgroundImage} />
42+
</div>;
43+
};
44+
export default BackdropPanel;

0 commit comments

Comments
 (0)