2022-09-07 10:00:28 +03:00
|
|
|
import React, { FC, useMemo, useState } from 'react';
|
2022-05-11 01:36:09 +03:00
|
|
|
|
|
|
|
type ObjectFit = React.CSSProperties['objectFit'];
|
|
|
|
|
2022-09-07 10:00:28 +03:00
|
|
|
export type CrossfadeImageProps = {
|
2022-05-11 01:36:09 +03:00
|
|
|
src: string;
|
|
|
|
width: string;
|
|
|
|
height: string;
|
|
|
|
objectFit?: ObjectFit;
|
|
|
|
duration?: string;
|
2022-09-07 10:00:28 +03:00
|
|
|
};
|
2022-05-11 01:36:09 +03:00
|
|
|
|
|
|
|
const imgStyle: React.CSSProperties = {
|
|
|
|
position: 'absolute',
|
|
|
|
width: `100%`,
|
|
|
|
height: `100%`,
|
|
|
|
};
|
|
|
|
|
2022-09-07 10:00:28 +03:00
|
|
|
export const CrossfadeImage: FC<CrossfadeImageProps> = ({
|
2022-05-11 01:36:09 +03:00
|
|
|
src = '',
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
objectFit = 'fill',
|
|
|
|
duration = '1s',
|
2022-09-07 10:00:28 +03:00
|
|
|
}) => {
|
2022-05-11 01:36:09 +03:00
|
|
|
const spanStyle: React.CSSProperties = useMemo(
|
|
|
|
() => ({
|
|
|
|
display: 'inline-block',
|
|
|
|
position: 'relative',
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
}),
|
|
|
|
[width, height],
|
|
|
|
);
|
|
|
|
|
|
|
|
const imgStyles = useMemo(
|
|
|
|
() => [
|
|
|
|
{ ...imgStyle, objectFit, opacity: 0, transition: `opacity ${duration}` },
|
|
|
|
{ ...imgStyle, objectFit, opacity: 1, transition: `opacity ${duration}` },
|
|
|
|
{ ...imgStyle, objectFit, opacity: 0 },
|
|
|
|
],
|
|
|
|
[objectFit, duration],
|
|
|
|
);
|
|
|
|
|
|
|
|
const [key, setKey] = useState(0);
|
|
|
|
const [srcs, setSrcs] = useState(['', '']);
|
|
|
|
const nextSrc = src !== srcs[1] ? src : '';
|
|
|
|
|
|
|
|
const onLoadImg = () => {
|
|
|
|
setKey((key + 1) % 3);
|
|
|
|
setSrcs([srcs[1], nextSrc]);
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<span style={spanStyle}>
|
|
|
|
{[...srcs, nextSrc].map(
|
2022-05-12 09:31:31 +03:00
|
|
|
(singleSrc, index) =>
|
|
|
|
singleSrc !== '' && (
|
2022-05-11 01:36:09 +03:00
|
|
|
<img
|
2022-05-12 09:31:31 +03:00
|
|
|
key={singleSrc}
|
|
|
|
src={singleSrc}
|
2022-05-11 01:36:09 +03:00
|
|
|
alt=""
|
|
|
|
style={imgStyles[index]}
|
|
|
|
onLoad={index === 2 ? onLoadImg : undefined}
|
|
|
|
/>
|
|
|
|
),
|
|
|
|
)}
|
|
|
|
</span>
|
|
|
|
);
|
2022-09-07 10:00:28 +03:00
|
|
|
};
|
|
|
|
export default CrossfadeImage;
|
2022-05-11 01:36:09 +03:00
|
|
|
|
|
|
|
CrossfadeImage.defaultProps = {
|
|
|
|
objectFit: 'fill',
|
|
|
|
duration: '3s',
|
|
|
|
};
|