mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
using backdrop filter for faster rendering
This commit is contained in:
parent
e227c9660e
commit
a42a0adf4a
7 changed files with 126 additions and 54 deletions
|
@ -1,10 +1,9 @@
|
||||||
import React, { AllHTMLAttributes, FC } from 'react';
|
import React, { AllHTMLAttributes, FC } from 'react';
|
||||||
import * as styles from './styles.scss';
|
import * as styles from './styles.scss';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
type IProps = AllHTMLAttributes<HTMLDivElement> & { is_blurred: boolean };
|
type IProps = AllHTMLAttributes<HTMLDivElement> & { is_blurred: boolean };
|
||||||
|
|
||||||
export const BlurWrapper: FC<IProps> = ({ children, is_blurred }) => (
|
export const BlurWrapper: FC<IProps> = ({ children, is_blurred }) => (
|
||||||
<div className={styles.blur} style={{ filter: `blur(${is_blurred ? 15 : 0}px)` }}>
|
<div className={classNames(styles.blur, { [styles.is_blurred]: is_blurred })}>{children}</div>
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,17 @@
|
||||||
filter: blur(0);
|
filter: blur(0);
|
||||||
transition: filter 0.25s;
|
transition: filter 0.25s;
|
||||||
will-change: filter;
|
will-change: filter;
|
||||||
// max-height: 100vh;
|
padding-top: 100px + $gap;
|
||||||
// width: 100vw;
|
|
||||||
// overflow: visible auto;
|
@include tablet {
|
||||||
|
padding-top: 64px + $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is_blurred {
|
||||||
|
filter: blur(15px);
|
||||||
|
|
||||||
|
@include can_backdrop {
|
||||||
|
filter: blur(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useCallback, memo } from 'react';
|
import React, { FC, useCallback, memo, useState, useEffect } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { push as historyPush } from 'connected-react-router';
|
import { push as historyPush } from 'connected-react-router';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
@ -13,9 +13,10 @@ import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
||||||
import { DIALOGS } from '~/redux/modal/constants';
|
import { DIALOGS } from '~/redux/modal/constants';
|
||||||
import { pick } from 'ramda';
|
import { pick } from 'ramda';
|
||||||
import { UserButton } from '../UserButton';
|
import { UserButton } from '../UserButton';
|
||||||
import { Icon } from '~/components/input/Icon';
|
|
||||||
import { Notifications } from '../Notifications';
|
import { Notifications } from '../Notifications';
|
||||||
import { URLS } from '~/constants/urls';
|
import { URLS } from '~/constants/urls';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
user: pick(['username', 'is_user', 'photo'])(selectUser(state)),
|
user: pick(['username', 'is_user', 'photo'])(selectUser(state)),
|
||||||
|
@ -32,41 +33,61 @@ type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {
|
||||||
|
|
||||||
const HeaderUnconnected: FC<IProps> = memo(
|
const HeaderUnconnected: FC<IProps> = memo(
|
||||||
({ user, user: { username, is_user }, showDialog, authLogout, authOpenProfile }) => {
|
({ user, user: { username, is_user }, showDialog, authLogout, authOpenProfile }) => {
|
||||||
|
const [is_scrolled, setIsScrolled] = useState(false);
|
||||||
|
|
||||||
const onLogin = useCallback(() => showDialog(DIALOGS.LOGIN), [showDialog]);
|
const onLogin = useCallback(() => showDialog(DIALOGS.LOGIN), [showDialog]);
|
||||||
const onProfileClick = useCallback(() => authOpenProfile(username), [authOpenProfile, user]);
|
const onProfileClick = useCallback(() => authOpenProfile(username), [authOpenProfile, user]);
|
||||||
|
|
||||||
return (
|
const onScroll = useCallback(() => {
|
||||||
<div className={style.container}>
|
const active = window.scrollY > 64;
|
||||||
<Logo />
|
|
||||||
|
|
||||||
<Filler />
|
if (active !== is_scrolled) setIsScrolled(active);
|
||||||
|
}, [is_scrolled, setIsScrolled]);
|
||||||
|
|
||||||
{is_user && (
|
useEffect(() => {
|
||||||
<div className={style.plugs}>
|
onScroll();
|
||||||
<Link className={style.item} to={URLS.BASE}>
|
}, []);
|
||||||
FLOW
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link className={style.item} to={URLS.BORIS}>
|
useEffect(() => {
|
||||||
BORIS
|
window.addEventListener('scroll', onScroll);
|
||||||
</Link>
|
return () => window.removeEventListener('scroll', onScroll);
|
||||||
|
}, [onScroll]);
|
||||||
|
|
||||||
<div className={style.item}>
|
return createPortal(
|
||||||
<Notifications />
|
<div className={classNames(style.wrap, { [style.is_scrolled]: is_scrolled })}>
|
||||||
|
<div className={style.container}>
|
||||||
|
<Logo />
|
||||||
|
|
||||||
|
<Filler />
|
||||||
|
|
||||||
|
{is_user && (
|
||||||
|
<div className={style.plugs}>
|
||||||
|
<Link className={style.item} to={URLS.BASE}>
|
||||||
|
FLOW
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Link className={style.item} to={URLS.BORIS}>
|
||||||
|
BORIS
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className={style.item}>
|
||||||
|
<Notifications />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{is_user && (
|
{is_user && (
|
||||||
<UserButton user={user} onLogout={authLogout} onProfileClick={onProfileClick} />
|
<UserButton user={user} onLogout={authLogout} onProfileClick={onProfileClick} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!is_user && (
|
{!is_user && (
|
||||||
<Group horizontal className={style.user_button} onClick={onLogin}>
|
<Group horizontal className={style.user_button} onClick={onLogin}>
|
||||||
<div>ВДОХ</div>
|
<div>ВДОХ</div>
|
||||||
</Group>
|
</Group>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</div>,
|
||||||
|
document.body
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,10 +1,39 @@
|
||||||
|
.wrap {
|
||||||
|
height: 64px;
|
||||||
|
z-index: 5;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: background-color 0.5s;
|
||||||
|
|
||||||
|
@include tablet {
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is_scrolled {
|
||||||
|
background: transparentize($content_bg, 0.05);
|
||||||
|
|
||||||
|
@include can_backdrop {
|
||||||
|
background: transparentize($content_bg, 0.25);
|
||||||
|
-webkit-backdrop-filter: blur(5px);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
height: 120px;
|
// padding: $gap;
|
||||||
z-index: 5;
|
box-sizing: border-box;
|
||||||
|
flex: 0 1 $content_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spacer {
|
.spacer {
|
||||||
|
@ -56,6 +85,14 @@
|
||||||
// display: none;
|
// display: none;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include tablet {
|
||||||
|
padding: $gap / 2;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
margin-left: $gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,11 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
// background: transparentize($color: #000000, $amount: 0.5);
|
background: transparentize($color: #000000, $amount: 0.9);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
animation: appear 0.25s forwards;
|
||||||
|
|
||||||
|
@include can_backdrop {
|
||||||
|
backdrop-filter: blur(15px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ render(
|
||||||
[Stage 0]:
|
[Stage 0]:
|
||||||
- check if email is registered at social login
|
- check if email is registered at social login
|
||||||
- friendship
|
- friendship
|
||||||
- password restore
|
|
||||||
- signup?
|
- signup?
|
||||||
- cover change
|
- cover change
|
||||||
- sticky header
|
- sticky header
|
||||||
|
@ -47,6 +46,7 @@ render(
|
||||||
- comment editing
|
- comment editing
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
|
- password restore
|
||||||
- avatar upload
|
- avatar upload
|
||||||
- flow updates
|
- flow updates
|
||||||
- flow infinite scroll
|
- flow infinite scroll
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import "colors";
|
@import 'colors';
|
||||||
|
|
||||||
$cell: 280px;
|
$cell: 280px;
|
||||||
$gap: 10px;
|
$gap: 10px;
|
||||||
|
@ -31,9 +31,9 @@ $extra_light: 200;
|
||||||
|
|
||||||
$upload_button_height: 52px;
|
$upload_button_height: 52px;
|
||||||
|
|
||||||
$font: Montserrat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
$font: Montserrat, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
|
||||||
"Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
|
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||||
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
'Noto Color Emoji';
|
||||||
|
|
||||||
$font_48_semibold: $semibold 48px $font;
|
$font_48_semibold: $semibold 48px $font;
|
||||||
$font_48_bold: $bold 48px $font;
|
$font_48_bold: $bold 48px $font;
|
||||||
|
@ -61,14 +61,11 @@ $font_8_semibold: $semibold 8px $font;
|
||||||
$font_cell_title: $bold 30px $font;
|
$font_cell_title: $bold 30px $font;
|
||||||
$font_hero_title: $bold 40px $font;
|
$font_hero_title: $bold 40px $font;
|
||||||
|
|
||||||
$shadow_depth_1: transparentize(black, 0.8) 0 1px,
|
$shadow_depth_1: transparentize(black, 0.8) 0 1px, inset transparentize(white, 0.98) 0 1px;
|
||||||
inset transparentize(white, 0.98) 0 1px;
|
$shadow_depth_2: transparentize(black, 0.8) 0 2px, inset transparentize(white, 0.98) 0 1px;
|
||||||
$shadow_depth_2: transparentize(black, 0.8) 0 2px,
|
|
||||||
inset transparentize(white, 0.98) 0 1px;
|
|
||||||
|
|
||||||
$comment_shadow: $shadow_depth_2;
|
$comment_shadow: $shadow_depth_2;
|
||||||
$node_shadow: transparentize(black, 0.8) 0 2px,
|
$node_shadow: transparentize(black, 0.8) 0 2px, transparentize(black, 0.8) 0 2px 4px;
|
||||||
transparentize(black, 0.8) 0 2px 4px;
|
|
||||||
|
|
||||||
$tag_height: 26px;
|
$tag_height: 26px;
|
||||||
|
|
||||||
|
@ -77,18 +74,15 @@ $input_shadow_error: inset $red 0 0 0 1px;
|
||||||
$input_shadow_filled: $input_shadow;
|
$input_shadow_filled: $input_shadow;
|
||||||
|
|
||||||
@mixin outer_shadow() {
|
@mixin outer_shadow() {
|
||||||
box-shadow: inset transparentize(white, 0.95) 0 1px,
|
box-shadow: inset transparentize(white, 0.95) 0 1px, transparentize(black, 0.8) -1px -1px;
|
||||||
transparentize(black, 0.8) -1px -1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin inner_shadow() {
|
@mixin inner_shadow() {
|
||||||
box-shadow: inset transparentize(white, 0.95) 0 -1px,
|
box-shadow: inset transparentize(white, 0.95) 0 -1px, inset transparentize(black, 0.5) 0 1px;
|
||||||
inset transparentize(black, 0.5) 0 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin input_shadow() {
|
@mixin input_shadow() {
|
||||||
box-shadow: inset transparentize(white, 0.92) 0 -1px,
|
box-shadow: inset transparentize(white, 0.92) 0 -1px, inset transparentize(black, 0.8) 0 1px;
|
||||||
inset transparentize(black, 0.8) 0 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin modal_mixin() {
|
@mixin modal_mixin() {
|
||||||
|
@ -104,7 +98,7 @@ $input_shadow_filled: $input_shadow;
|
||||||
position: $position;
|
position: $position;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: " ";
|
content: ' ';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -150,3 +144,9 @@ $input_shadow_filled: $input_shadow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin can_backdrop {
|
||||||
|
@supports ((-webkit-backdrop-filter: blur(5px)) or (backdrop-filter: blur(5px))) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue