1
0
Fork 0
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:
Fedor Katurov 2019-11-25 17:45:56 +07:00
parent e227c9660e
commit a42a0adf4a
7 changed files with 126 additions and 54 deletions

View file

@ -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>
); );

View file

@ -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);
}
}
} }

View file

@ -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
); );
} }
); );

View file

@ -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;
}
}
} }
} }

View file

@ -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);
}
} }

View file

@ -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

View file

@ -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;
}
}