Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
eoefans-web/src/components/image/index.tsx
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
107 lines (101 sloc)
2.52 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useCallback, useMemo, useState, memo, ReactElement } from "react"; | |
import { InView } from "react-intersection-observer"; | |
import { Once } from "@utils/index"; | |
import { ImageProps } from "./imagetype"; | |
import styles from "./image.module.less"; | |
import { | |
getImageSize, | |
getResizeHeight, | |
fallbackUrl as DefaultFallbackUrl, | |
ImageSize, | |
} from "./tool"; | |
import { styled } from "@mui/material"; | |
/** | |
* @description 图片预加载hook | |
*/ | |
function useLoading(url: string) { | |
const [obj, setObj] = useState<ImageSize & { isLoaded: boolean }>({ | |
width: 0, | |
height: 0, | |
again: false, | |
isLoaded: false, | |
success: true, | |
}); | |
useMemo(async () => { | |
const res = await getImageSize(url); | |
setObj(() => ({ ...res, isLoaded: true })); | |
}, [url]); | |
return obj; | |
} | |
/** | |
*@description 图片组件库,默认支持图片加载fallback。 | |
*/ | |
export default memo(function Image({ | |
url, | |
width = 200, | |
height, | |
fallbackUrl = DefaultFallbackUrl, | |
observer, | |
callback, | |
children, | |
}: ImageProps & { | |
children?: ReactElement; | |
}) { | |
const res = useLoading(url), | |
{ isLoaded, success } = res, | |
real_width = width, | |
real_height = height || getResizeHeight(res, real_width), | |
real_fallback_url = fallbackUrl || DefaultFallbackUrl; | |
const once_callback = useCallback(Once(callback!!), []); | |
return ( | |
<InView> | |
{({ inView, ref, entry }) => ( | |
<BorderDiv ref={ref} className={styles.imgWrapper}> | |
<img | |
width={real_width} | |
height={real_height} | |
src={isLoaded && success ? url : real_fallback_url} | |
style={{ | |
opacity: isLoaded ? 1.0 : 0.09, | |
}} | |
alt='' | |
loading='lazy' | |
/> | |
<>{observer && inView && once_callback(inView)}</> | |
{children} | |
</BorderDiv> | |
)} | |
</InView> | |
); | |
}); | |
export function ImageBasic({ | |
url, | |
observer, | |
callback, | |
children, | |
title, | |
...resProps | |
}: ImageProps & { | |
title: string; | |
children?: ReactElement; | |
[k: string]: any; | |
}) { | |
const once_callback = useCallback(Once(callback!!), []); | |
return ( | |
<InView> | |
{({ inView, ref, entry }) => ( | |
<BorderDiv ref={ref} className={styles.imgWrapper}> | |
<img src={url} alt={title} loading='lazy' {...resProps} /> | |
<>{observer && inView && once_callback(inView)}</> | |
{children} | |
</BorderDiv> | |
)} | |
</InView> | |
); | |
} | |
const BorderDiv = styled("div")(({ theme }) => ({ | |
borderRadius: "8px", | |
[theme.breakpoints.down("sm")]: { | |
borderRadius: "4px", | |
}, | |
})); |