From e8519bdddd31a33ace25ffbcb73273c1573e9c33 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Fri, 14 Aug 2020 16:51:19 +0300 Subject: feat: apply cool transitions to Image --- src/components/Image/BackgroundImage.tsx | 8 ++--- src/components/Image/Image.tsx | 55 ++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 14 deletions(-) (limited to 'src/components/Image') diff --git a/src/components/Image/BackgroundImage.tsx b/src/components/Image/BackgroundImage.tsx index 824f667..e749d10 100644 --- a/src/components/Image/BackgroundImage.tsx +++ b/src/components/Image/BackgroundImage.tsx @@ -7,7 +7,7 @@ interface PropTypes { alt?: string; } -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles({ root: { position: 'absolute', width: '100%', @@ -19,7 +19,7 @@ const useStyles = makeStyles(theme => ({ width: '100%', height: '100%' } -})); +}); const BackgroundImage: React.FC = ({ src, alt }) => { const classes = useStyles(); @@ -28,8 +28,8 @@ const BackgroundImage: React.FC = ({ src, alt }) => { {alt} - ) -} + ); +}; export default BackgroundImage; diff --git a/src/components/Image/Image.tsx b/src/components/Image/Image.tsx index 7736e8a..1898716 100644 --- a/src/components/Image/Image.tsx +++ b/src/components/Image/Image.tsx @@ -1,14 +1,19 @@ -import React, { useState, useCallback } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import CircularProgress from '@material-ui/core/CircularProgress'; import ErrorIcon from '@material-ui/icons/BrokenImage'; +import grey from '@material-ui/core/colors/grey'; interface PropTypes { src?: string; alt?: string; className?: string; + animationDuration?: number; + disableLoading?: boolean; } +type Status = 'success' | 'loading' | 'error'; + const useStyles = makeStyles(theme => ({ container: { width: '100%', @@ -16,12 +21,35 @@ const useStyles = makeStyles(theme => ({ display: 'flex', alignItems: 'center', justifyContent: 'center' + }, + success: { + opacity: '100%', + filterBrightness: '100%', + filterSaturate: '100%' + }, + loading: { + opacity: 0, + filterBrightness: 0, + filterSaturate: '20%', + position: 'absolute' + }, + error: { + display: 'none' + }, + errorIcon: { + color: grey[300], + width: theme.spacing(6), + height: theme.spacing(6) } })); -type Status = 'success' |'loading' | 'error'; - -const Image: React.FC = ({ src, alt, className }) => { +const Image: React.FC = React.memo(({ + src, + alt, + className, + animationDuration = 1000, + disableLoading = false +}) => { const classes = useStyles(); const [status, setStatus] = useState('loading'); @@ -33,12 +61,18 @@ const Image: React.FC = ({ src, alt, className }) => { setStatus('error'); }, [setStatus]); + const transition = useMemo(() => ` + filterBrightness ${animationDuration * 0.75}ms cubic-bezier(0.4, 0.0, 0.2, 1), + filterSaturate ${animationDuration}ms cubic-bezier(0.4, 0.0, 0.2, 1), + opacity ${animationDuration / 2}ms cubic-bezier(0.4, 0.0, 0.2, 1) + `, [animationDuration]); + const image = ( {alt} @@ -52,14 +86,15 @@ const Image: React.FC = ({ src, alt, className }) => {
{ (status === 'error' || !src) - ? - : + ? + : (!disableLoading && ) }
- )} + ) + } ); -}; +}); export default Image; -- cgit v1.2.3