aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/Image/BackgroundImage.tsx8
-rw-r--r--src/components/Image/Image.tsx55
2 files changed, 49 insertions, 14 deletions
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<PropTypes> = ({ src, alt }) => {
const classes = useStyles();
@@ -28,8 +28,8 @@ const BackgroundImage: React.FC<PropTypes> = ({ src, alt }) => {
<picture className={classes.root}>
<Image src={src} alt={alt} className={classes.image} />
</picture>
- )
-}
+ );
+};
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<PropTypes> = ({ src, alt, className }) => {
+const Image: React.FC<PropTypes> = React.memo(({
+ src,
+ alt,
+ className,
+ animationDuration = 1000,
+ disableLoading = false
+}) => {
const classes = useStyles();
const [status, setStatus] = useState<Status>('loading');
@@ -33,12 +61,18 @@ const Image: React.FC<PropTypes> = ({ 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 = (
<img
src={src}
alt={alt}
- className={className}
- style={{ display: status === 'success' ? 'inline' : 'none' }}
+ className={`${className} ${classes[status]}`}
+ style={{ transition }}
onLoad={handleLoad}
onError={handleError}
/>
@@ -52,14 +86,15 @@ const Image: React.FC<PropTypes> = ({ src, alt, className }) => {
<div className={classes.container}>
{
(status === 'error' || !src)
- ? <ErrorIcon fontSize="large" />
- : <CircularProgress color="primary" />
+ ? <ErrorIcon className={classes.errorIcon} />
+ : (!disableLoading && <CircularProgress color="primary" />)
}
</div>
- )}
+ )
+ }
</>
);
-};
+});
export default Image;