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

Commit

Permalink
Merge pull request #6659 from matrix-org/palid/fix/backdrop-blur
Browse files Browse the repository at this point in the history
Optimize background image from avatar on left panel
  • Loading branch information
Palid authored Aug 23, 2021
2 parents d15ef70 + 618cc70 commit 6205cbb
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 258 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
"cheerio": "^1.0.0-rc.9",
"classnames": "^2.2.6",
"commonmark": "^0.29.3",
"context-filter-polyfill": "^0.2.4",
"counterpart": "^0.18.6",
"diff-dom": "^4.2.2",
"diff-match-patch": "^1.0.5",
Expand Down Expand Up @@ -196,7 +195,6 @@
"decoderWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js",
"decoderWorker\\.min\\.wasm": "<rootDir>/__mocks__/empty.js",
"waveWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js",
"context-filter-polyfill": "<rootDir>/__mocks__/empty.js",
"workers/(.+)\\.worker\\.ts": "<rootDir>/__mocks__/workerMock.js",
"RecorderWorklet": "<rootDir>/__mocks__/empty.js"
},
Expand Down
20 changes: 2 additions & 18 deletions res/css/structures/_BackdropPanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,15 @@ limitations under the License.
height: 100vh;
width: 100%;
overflow: hidden;

&::before {
content: " ";
position: absolute;
left: 0;
top: 0;
height: 100vh;
width: 100%;
background-color: var(--lp-background-overlay);
}
filter: blur(var(--lp-background-blur));
}

.mx_BackdropPanel--canvas {
.mx_BackdropPanel--image {
position: absolute;
top: 0;
left: 0;
min-height: 100%;
z-index: 0;
pointer-events: none;
overflow: hidden;

&:nth-of-type(2n-1) {
opacity: 0.2;
}
&:nth-of-type(2n) {
opacity: 0.1;
}
}
18 changes: 14 additions & 4 deletions res/css/structures/_GroupFilterPanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,23 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_MatrixChat--with-avatar {
.mx_GroupFilterPanel {
background-color: transparent;
}
$groupFilterPanelWidth: 56px; // only applies in this file, used for calculations

.mx_GroupFilterPanelContainer {
flex-grow: 0;
flex-shrink: 0;
width: $groupFilterPanelWidth;
height: 100%;

// Create another flexbox so the GroupFilterPanel fills the container
display: flex;
flex-direction: column;

// GroupFilterPanel handles its own CSS
}

.mx_GroupFilterPanel {
z-index: 1;
background-color: $groupFilterPanel-bg-color;
flex: 1;
cursor: pointer;
Expand Down
23 changes: 9 additions & 14 deletions res/css/structures/_LeftPanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

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

.mx_MatrixChat--with-avatar {
Expand All @@ -27,8 +26,17 @@ $roomListCollapsedWidth: 68px;
.mx_LeftPanel_wrapper {
display: flex;
max-width: 50%;

.mx_LeftPanel_wrapper--user {
background-color: $roomlist-bg-color;
display: flex;
overflow: hidden;
position: relative;
}
}



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

.mx_LeftPanel_GroupFilterPanelContainer {
flex-grow: 0;
flex-shrink: 0;
flex-basis: $groupFilterPanelWidth;
height: 100%;

// Create another flexbox so the GroupFilterPanel fills the container
display: flex;
flex-direction: column;

// GroupFilterPanel handles its own CSS
}

// Note: The 'room list' in this context is actually everything that isn't the tag
// panel, such as the menu options, breadcrumbs, filtering, etc
.mx_LeftPanel_roomListContainer {
Expand Down
8 changes: 2 additions & 6 deletions res/css/structures/_SpacePanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,14 @@ $activeBorderTransparentGap: 1px;
$activeBackgroundColor: $roomtile-selected-bg-color;
$activeBorderColor: $secondary-fg-color;

.mx_MatrixChat--with-avatar {
.mx_SpacePanel {
background-color: transparent;
}
}

.mx_SpacePanel {
background-color: $groupFilterPanel-bg-color;
flex: 0 0 auto;
padding: 0;
margin: 0;
position: relative;
// Fix for the blurred avatar-background
z-index: 1;

// Create another flexbox so the Panel fills the container
display: flex;
Expand Down
4 changes: 1 addition & 3 deletions res/themes/dark/css/_dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,7 @@ $appearance-tab-border-color: $room-highlight-color;

// blur amounts for left left panel (only for element theme)
:root {
--llp-background-blur: 160px;
--lp-background-blur: 90px;
--lp-background-overlay: rgba(255, 255, 255, 0.055);
--lp-background-blur: 45px;
}

$composer-shadow-color: rgba(0, 0, 0, 0.28);
Expand Down
4 changes: 1 addition & 3 deletions res/themes/light/css/_light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,7 @@ $appearance-tab-border-color: $input-darker-bg-color;

// blur amounts for left left panel (only for element theme)
:root {
--llp-background-blur: 120px;
--lp-background-blur: 60px;
--lp-background-overlay: rgba(0, 0, 0, 0.055);
--lp-background-blur: 30px;
}
$composer-shadow-color: rgba(0, 0, 0, 0.04);

Expand Down
166 changes: 22 additions & 144 deletions src/components/structures/BackdropPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,153 +14,31 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { createRef } from "react";
import "context-filter-polyfill";

import UIStore from "../../stores/UIStore";
import React, { CSSProperties } from "react";

interface IProps {
backgroundImage?: CanvasImageSource;
}

interface IState {
// Left Panel image
lpImage?: string;
// Left-left panel image
llpImage?: string;
backgroundImage?: string;
blurMultiplier?: number;
}

export default class BackdropPanel extends React.PureComponent<IProps, IState> {
private leftLeftPanelRef = createRef<HTMLCanvasElement>();
private leftPanelRef = createRef<HTMLCanvasElement>();

private sizes = {
leftLeftPanelWidth: 0,
leftPanelWidth: 0,
height: 0,
};
private style = getComputedStyle(document.documentElement);

public state: IState = {};

public componentDidMount() {
UIStore.instance.on("SpacePanel", this.onResize);
UIStore.instance.on("GroupFilterPanelContainer", this.onResize);
this.onResize();
}

public componentWillUnmount() {
UIStore.instance.off("SpacePanel", this.onResize);
UIStore.instance.on("GroupFilterPanelContainer", this.onResize);
}

public componentDidUpdate(prevProps: IProps) {
if (prevProps.backgroundImage !== this.props.backgroundImage) {
this.setState({});
this.onResize();
export const BackdropPanel: React.FC<IProps> = ({ backgroundImage, blurMultiplier }) => {
if (!backgroundImage) return null;

const styles: CSSProperties = {};
if (blurMultiplier) {
const rootStyle = getComputedStyle(document.documentElement);
const blurValue = rootStyle.getPropertyValue('--lp-background-blur');
const pixelsValue = blurValue.replace('px', '');
const parsed = parseInt(pixelsValue, 10);
if (!isNaN(parsed)) {
styles.filter = `blur(${parsed * blurMultiplier}px)`;
}
}

private onResize = () => {
if (this.props.backgroundImage) {
const groupFilterPanelDimensions = UIStore.instance.getElementDimensions("GroupFilterPanelContainer");
const spacePanelDimensions = UIStore.instance.getElementDimensions("SpacePanel");
const roomListDimensions = UIStore.instance.getElementDimensions("LeftPanel");
this.sizes = {
leftLeftPanelWidth: spacePanelDimensions?.width ?? groupFilterPanelDimensions?.width ?? 0,
leftPanelWidth: roomListDimensions?.width ?? 0,
height: UIStore.instance.windowHeight,
};
this.refreshBackdropImage();
}
};

private refreshBackdropImage = (): void => {
const leftLeftPanelContext = this.leftLeftPanelRef.current.getContext("2d");
const leftPanelContext = this.leftPanelRef.current.getContext("2d");
const { leftLeftPanelWidth, leftPanelWidth, height } = this.sizes;
const width = leftLeftPanelWidth + leftPanelWidth;
const { backgroundImage } = this.props;

const imageWidth = (backgroundImage as ImageBitmap).width;
const imageHeight = (backgroundImage as ImageBitmap).height;

const contentRatio = imageWidth / imageHeight;
const containerRatio = width / height;
let resultHeight;
let resultWidth;
if (contentRatio > containerRatio) {
resultHeight = height;
resultWidth = height * contentRatio;
} else {
resultWidth = width;
resultHeight = width / contentRatio;
}

// This value has been chosen to be as close with rendering as the css-only
// backdrop-filter: blur effect was, mostly takes effect for vertical pictures.
const x = width * 0.1;
const y = (height - resultHeight) / 2;

this.leftLeftPanelRef.current.width = leftLeftPanelWidth;
this.leftLeftPanelRef.current.height = height;
this.leftPanelRef.current.width = (window.screen.width * 0.5);
this.leftPanelRef.current.height = height;

const spacesBlur = this.style.getPropertyValue('--llp-background-blur');
const roomListBlur = this.style.getPropertyValue('--lp-background-blur');

leftLeftPanelContext.filter = `blur(${spacesBlur})`;
leftPanelContext.filter = `blur(${roomListBlur})`;
leftLeftPanelContext.drawImage(
backgroundImage,
0, 0,
imageWidth, imageHeight,
x,
y,
resultWidth,
resultHeight,
);
leftPanelContext.drawImage(
backgroundImage,
0, 0,
imageWidth, imageHeight,
x - leftLeftPanelWidth,
y,
resultWidth,
resultHeight,
);
this.setState({
lpImage: this.leftPanelRef.current.toDataURL('image/jpeg', 1),
llpImage: this.leftLeftPanelRef.current.toDataURL('image/jpeg', 1),

});
};

public render() {
if (!this.props.backgroundImage) return null;
return <div className="mx_BackdropPanel">
{ this.state?.llpImage !== 'data:,' && <img
className="mx_BackdropPanel--canvas"
src={this.state.llpImage} /> }

{ this.state?.lpImage !== 'data:,' && <img
className="mx_BackdropPanel--canvas"
src={this.state.lpImage} /> }
<canvas
ref={this.leftLeftPanelRef}
className="mx_BackdropPanel--canvas"
style={{
display: this.state.lpImage ? 'none' : 'block',
}}
/>
<canvas
style={{
display: this.state.lpImage ? 'none' : 'block',
}}
ref={this.leftPanelRef}
className="mx_BackdropPanel--canvas"
/>
</div>;
}
}
return <div className="mx_BackdropPanel">
<img
style={styles}
className="mx_BackdropPanel--image"
src={backgroundImage} />
</div>;
};
export default BackdropPanel;
Loading

0 comments on commit 6205cbb

Please sign in to comment.