mirror of
https://github.com/element-hq/element-web
synced 2024-11-26 19:26:04 +03:00
Properly cache blur effect
This commit is contained in:
parent
bdb5f3bb9f
commit
a999cad49d
4 changed files with 58 additions and 31 deletions
|
@ -20,6 +20,7 @@ limitations under the License.
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: ' ';
|
content: ' ';
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
@import "../../light/css/_paths.scss";
|
@import "../../light/css/_paths.scss";
|
||||||
@import "../../light/css/_fonts.scss";
|
@import "../../light/css/_fonts.scss";
|
||||||
@import "../../light/css/_light.scss";
|
@import "../../light/css/_light.scss";
|
||||||
// important this goes before _mods,
|
|
||||||
// as $groupFilterPanel-background-blur-amount and
|
|
||||||
// $roomlist-background-blur-amount
|
|
||||||
// are overridden in _dark.scss
|
|
||||||
@import "_dark.scss";
|
@import "_dark.scss";
|
||||||
@import "../../light/css/_mods.scss";
|
@import "../../light/css/_mods.scss";
|
||||||
@import "../../../../res/css/_components.scss";
|
@import "../../../../res/css/_components.scss";
|
||||||
|
|
|
@ -23,48 +23,54 @@ interface IProps {
|
||||||
backgroundImage?: CanvasImageSource;
|
backgroundImage?: CanvasImageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class BackdropPanel extends React.PureComponent<IProps> {
|
interface IState {
|
||||||
private spacesCanvasRef = createRef<HTMLCanvasElement>();
|
// Left Panel image
|
||||||
private roomListCanvasRef = createRef<HTMLCanvasElement>();
|
lpImage?: string;
|
||||||
|
// Left-left panel image
|
||||||
|
llpImage?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class BackdropPanel extends React.PureComponent<IProps, IState> {
|
||||||
|
private leftLeftPanelRef = createRef<HTMLCanvasElement>();
|
||||||
|
private leftPanelRef = createRef<HTMLCanvasElement>();
|
||||||
|
|
||||||
private sizes = {
|
private sizes = {
|
||||||
spacePanelWidth: 0,
|
leftLeftPanelWidth: 0,
|
||||||
roomListWidth: 0,
|
leftPanelWidth: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
};
|
};
|
||||||
private style = getComputedStyle(document.documentElement);
|
private style = getComputedStyle(document.documentElement);
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
this.state = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
UIStore.instance.on("SpacePanel", this.onResize);
|
UIStore.instance.on("SpacePanel", this.onResize);
|
||||||
UIStore.instance.on("LeftPanel", this.onResize);
|
UIStore.instance.on("GroupFilterPanelContainer", this.onResize);
|
||||||
this.onResize();
|
this.onResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
UIStore.instance.off("SpacePanel", this.onResize);
|
UIStore.instance.off("SpacePanel", this.onResize);
|
||||||
UIStore.instance.off("LeftPanel", this.onResize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidUpdate(prevProps: IProps) {
|
public componentDidUpdate(prevProps: IProps) {
|
||||||
if (this.props.backgroundImage) {
|
if (prevProps.backgroundImage !== this.props.backgroundImage) {
|
||||||
|
this.setState({});
|
||||||
this.onResize();
|
this.onResize();
|
||||||
}
|
}
|
||||||
if (prevProps.backgroundImage && !this.props.backgroundImage) {
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onResize = () => {
|
private onResize = () => {
|
||||||
if (this.props.backgroundImage) {
|
if (this.props.backgroundImage) {
|
||||||
|
const groupFilterPanelDimensions = UIStore.instance.getElementDimensions("GroupFilterPanelContainer");
|
||||||
const spacePanelDimensions = UIStore.instance.getElementDimensions("SpacePanel");
|
const spacePanelDimensions = UIStore.instance.getElementDimensions("SpacePanel");
|
||||||
const roomListDimensions = UIStore.instance.getElementDimensions("LeftPanel");
|
const roomListDimensions = UIStore.instance.getElementDimensions("LeftPanel");
|
||||||
this.sizes = {
|
this.sizes = {
|
||||||
spacePanelWidth: spacePanelDimensions?.width ?? 0,
|
leftLeftPanelWidth: spacePanelDimensions?.width ?? groupFilterPanelDimensions?.width ?? 0,
|
||||||
roomListWidth: roomListDimensions?.width ?? 0,
|
leftPanelWidth: roomListDimensions?.width ?? 0,
|
||||||
height: UIStore.instance.windowHeight,
|
height: UIStore.instance.windowHeight,
|
||||||
};
|
};
|
||||||
this.refreshBackdropImage();
|
this.refreshBackdropImage();
|
||||||
|
@ -72,10 +78,10 @@ export default class BackdropPanel extends React.PureComponent<IProps> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private refreshBackdropImage = (): void => {
|
private refreshBackdropImage = (): void => {
|
||||||
const spacesCtx = this.spacesCanvasRef.current.getContext("2d");
|
const spacesCtx = this.leftLeftPanelRef.current.getContext("2d");
|
||||||
const roomListCtx = this.roomListCanvasRef.current.getContext("2d");
|
const roomListCtx = this.leftPanelRef.current.getContext("2d");
|
||||||
const { spacePanelWidth, roomListWidth, height } = this.sizes;
|
const { leftLeftPanelWidth, leftPanelWidth, height } = this.sizes;
|
||||||
const width = spacePanelWidth + roomListWidth;
|
const width = leftLeftPanelWidth + leftPanelWidth;
|
||||||
const { backgroundImage } = this.props;
|
const { backgroundImage } = this.props;
|
||||||
|
|
||||||
const imageWidth = (backgroundImage as ImageBitmap).width
|
const imageWidth = (backgroundImage as ImageBitmap).width
|
||||||
|
@ -98,11 +104,11 @@ export default class BackdropPanel extends React.PureComponent<IProps> {
|
||||||
const x = (width - resultWidth) / 2;
|
const x = (width - resultWidth) / 2;
|
||||||
const y = (height - resultHeight) / 2;
|
const y = (height - resultHeight) / 2;
|
||||||
|
|
||||||
this.spacesCanvasRef.current.width = spacePanelWidth;
|
this.leftLeftPanelRef.current.width = leftLeftPanelWidth;
|
||||||
this.spacesCanvasRef.current.height = height;
|
this.leftLeftPanelRef.current.height = height;
|
||||||
this.roomListCanvasRef.current.width = roomListWidth;
|
this.leftPanelRef.current.width = (window.screen.width * 0.5) - leftLeftPanelWidth;
|
||||||
this.roomListCanvasRef.current.height = height;
|
this.leftPanelRef.current.height = height;
|
||||||
this.roomListCanvasRef.current.style.transform = `translateX(${spacePanelWidth}px)`;
|
this.leftPanelRef.current.style.transform = `translateX(${leftLeftPanelWidth}px)`;
|
||||||
|
|
||||||
const spacesBlur = this.style.getPropertyValue('--roomlist-background-blur-amount');
|
const spacesBlur = this.style.getPropertyValue('--roomlist-background-blur-amount');
|
||||||
const roomListBlur = this.style.getPropertyValue('--groupFilterPanel-background-blur-amount');
|
const roomListBlur = this.style.getPropertyValue('--groupFilterPanel-background-blur-amount');
|
||||||
|
@ -122,29 +128,49 @@ export default class BackdropPanel extends React.PureComponent<IProps> {
|
||||||
backgroundImage,
|
backgroundImage,
|
||||||
0, 0,
|
0, 0,
|
||||||
imageWidth, imageHeight,
|
imageWidth, imageHeight,
|
||||||
x - spacePanelWidth,
|
x - leftLeftPanelWidth,
|
||||||
y,
|
y,
|
||||||
resultWidth,
|
resultWidth,
|
||||||
resultHeight,
|
resultHeight,
|
||||||
);
|
);
|
||||||
|
this.setState({
|
||||||
|
lpImage: this.leftPanelRef.current.toDataURL('image/jpeg', 1),
|
||||||
|
llpImage: this.leftLeftPanelRef.current.toDataURL('image/jpeg', 1),
|
||||||
|
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
if (!this.props.backgroundImage) return null;
|
if (!this.props.backgroundImage) return null;
|
||||||
return <div className="mx_BackdropPanel">
|
return <div className="mx_BackdropPanel">
|
||||||
<canvas
|
<img
|
||||||
ref={this.spacesCanvasRef}
|
|
||||||
className="mx_BackdropPanel--canvas"
|
className="mx_BackdropPanel--canvas"
|
||||||
style={{
|
style={{
|
||||||
opacity: .19,
|
opacity: .19,
|
||||||
}}
|
}}
|
||||||
|
src={this.state.llpImage} />
|
||||||
|
<img
|
||||||
|
className="mx_BackdropPanel--canvas"
|
||||||
|
style={{
|
||||||
|
opacity: .12,
|
||||||
|
}}
|
||||||
|
src={this.state.lpImage} />
|
||||||
|
<canvas
|
||||||
|
ref={this.leftLeftPanelRef
|
||||||
|
}
|
||||||
|
className="mx_BackdropPanel--canvas"
|
||||||
|
style={{
|
||||||
|
display: this.state.lpImage ? 'none' : 'block',
|
||||||
|
opacity: .19,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<canvas
|
<canvas
|
||||||
style={{
|
style={{
|
||||||
|
display: this.state.lpImage ? 'none' : 'block',
|
||||||
transform: `translateX(0)`,
|
transform: `translateX(0)`,
|
||||||
opacity: .12,
|
opacity: .12,
|
||||||
}}
|
}}
|
||||||
ref={this.roomListCanvasRef}
|
ref={this.leftPanelRef}
|
||||||
className="mx_BackdropPanel--canvas"
|
className="mx_BackdropPanel--canvas"
|
||||||
/>
|
/>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
|
@ -69,6 +69,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
private ref: React.RefObject<HTMLDivElement> = createRef();
|
private ref: React.RefObject<HTMLDivElement> = createRef();
|
||||||
private listContainerRef: React.RefObject<HTMLDivElement> = createRef();
|
private listContainerRef: React.RefObject<HTMLDivElement> = createRef();
|
||||||
private groupFilterPanelWatcherRef: string;
|
private groupFilterPanelWatcherRef: string;
|
||||||
|
private groupFilterPanelContainer = createRef<HTMLDivElement>();
|
||||||
private bgImageWatcherRef: string;
|
private bgImageWatcherRef: string;
|
||||||
private focusedElement = null;
|
private focusedElement = null;
|
||||||
private isDoingStickyHeaders = false;
|
private isDoingStickyHeaders = false;
|
||||||
|
@ -93,6 +94,9 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
UIStore.instance.trackElementDimensions("LeftPanel", this.ref.current);
|
UIStore.instance.trackElementDimensions("LeftPanel", this.ref.current);
|
||||||
UIStore.instance.trackElementDimensions("ListContainer", this.listContainerRef.current);
|
UIStore.instance.trackElementDimensions("ListContainer", this.listContainerRef.current);
|
||||||
|
if (this.groupFilterPanelContainer.current) {
|
||||||
|
UIStore.instance.trackElementDimensions("GroupFilterPanelContainer", this.groupFilterPanelContainer.current);
|
||||||
|
}
|
||||||
UIStore.instance.on("ListContainer", this.refreshStickyHeaders);
|
UIStore.instance.on("ListContainer", this.refreshStickyHeaders);
|
||||||
// Using the passive option to not block the main thread
|
// Using the passive option to not block the main thread
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners
|
// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners
|
||||||
|
@ -420,7 +424,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
let leftLeftPanel;
|
let leftLeftPanel;
|
||||||
if (this.state.showGroupFilterPanel) {
|
if (this.state.showGroupFilterPanel) {
|
||||||
leftLeftPanel = (
|
leftLeftPanel = (
|
||||||
<div className="mx_LeftPanel_GroupFilterPanelContainer">
|
<div className="mx_LeftPanel_GroupFilterPanelContainer" ref={this.groupFilterPanelContainer}>
|
||||||
<GroupFilterPanel />
|
<GroupFilterPanel />
|
||||||
{ SettingsStore.getValue("feature_custom_tags") ? <CustomRoomTagPanel /> : null }
|
{ SettingsStore.getValue("feature_custom_tags") ? <CustomRoomTagPanel /> : null }
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue