owncast/web/components/ui/CrossfadeImage/CrossfadeImage.tsx
James Young d1f3fffe2f
reafctor: normalize component formatting (#2082)
* refactor: move/rename BanUserButton file

* refactor: move/rename Chart file

* refactor: update generic component filenames to PascalCase

* refactor: update config component filenames to PascalCase

* refactor: update AdminLayout component filename to PascalCase

* refactor: update/move VideoJS component

* chore(eslint): disable bad react/require-default-props rule

* refactor: normalize ActionButton component

* refactor: normalize ActionButtonRow component

* refactor: normalize FollowButton component

* refactor: normalize NotifyButton component

* refactor: normalize ChatActionMessage component

* refactor: normalize ChatContainer component

* refactor: normalize ChatJoinMessage component

* refactor: normalize ChatModerationActionMenu component

* refactor: normalize ChatModerationDetailsModal component

* refactor: normalize ChatModeratorNotification component

* refactor: normalize ChatSocialMessage component

* refactor: normalize ChatSystemMessage component

* refactor: normalize ChatTextField component

* refactor: normalize ChatUserBadge component

* refactor: normalize ChatUserMessage component

* refactor: normalize ContentHeader component

* refactor: normalize OwncastLogo component

* refactor: normalize UserDropdown component

* chore(eslint): modify react/function-component-definition rule

* refactor: normalize CodecSelector component

* refactor: update a bunch of functional components using eslint

* refactor: update a bunch of functional components using eslint, pt2

* refactor: update a bunch of functional components using eslint, pt3

* refactor: replace all component->component default imports with named imports

* refactor: replace all component-stories->component default imports with named imports

* refactor: remove default exports from most components

* chore(eslint): add eslint config files for the components and pages dirs

* fix: use-before-define error in ChatContainer

* Fix ChatContainer import

* Only process .tsx files in Next builds

Co-authored-by: Gabe Kangas <gabek@real-ity.com>
2022-09-07 00:00:28 -07:00

77 lines
1.6 KiB
TypeScript

import React, { FC, useMemo, useState } from 'react';
type ObjectFit = React.CSSProperties['objectFit'];
export type CrossfadeImageProps = {
src: string;
width: string;
height: string;
objectFit?: ObjectFit;
duration?: string;
};
const imgStyle: React.CSSProperties = {
position: 'absolute',
width: `100%`,
height: `100%`,
};
export const CrossfadeImage: FC<CrossfadeImageProps> = ({
src = '',
width,
height,
objectFit = 'fill',
duration = '1s',
}) => {
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(
(singleSrc, index) =>
singleSrc !== '' && (
<img
key={singleSrc}
src={singleSrc}
alt=""
style={imgStyles[index]}
onLoad={index === 2 ? onLoadImg : undefined}
/>
),
)}
</span>
);
};
export default CrossfadeImage;
CrossfadeImage.defaultProps = {
objectFit: 'fill',
duration: '3s',
};