mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 18:13:31 +00:00
optimize image component
- use new intersection hooks instead of react-intersection-observer - remove motion, replace with css animation - remove unneeded container from Loader component
This commit is contained in:
parent
29991ea95d
commit
805c75a67f
2 changed files with 51 additions and 46 deletions
|
|
@ -1,3 +1,13 @@
|
|||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -5,6 +15,11 @@
|
|||
border-radius: var(--theme-radius-md);
|
||||
}
|
||||
|
||||
.image.animated {
|
||||
opacity: 1;
|
||||
animation: fade-in 0.2s ease-in;
|
||||
}
|
||||
|
||||
.loader {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import clsx from 'clsx';
|
||||
import { motion, MotionConfigProps } from 'motion/react';
|
||||
import { MotionConfigProps } from 'motion/react';
|
||||
import { ForwardedRef, forwardRef, type ImgHTMLAttributes } from 'react';
|
||||
import { Img } from 'react-image';
|
||||
import { InView } from 'react-intersection-observer';
|
||||
|
||||
import styles from './image.module.css';
|
||||
|
||||
import { animationProps } from '/@/shared/components/animations/animation-props';
|
||||
import { Icon } from '/@/shared/components/icon/icon';
|
||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||
import { useInViewport } from '/@/shared/hooks/use-in-viewport';
|
||||
|
||||
interface ImageContainerProps extends MotionConfigProps {
|
||||
children: React.ReactNode;
|
||||
|
|
@ -46,40 +45,40 @@ export function Image({
|
|||
includeUnloader = true,
|
||||
src,
|
||||
}: ImageProps) {
|
||||
const { inViewport, ref } = useInViewport();
|
||||
|
||||
if (src) {
|
||||
return (
|
||||
<InView>
|
||||
{({ inView, ref }) => (
|
||||
<Img
|
||||
className={clsx(styles.image, className)}
|
||||
container={(children) => (
|
||||
<ImageContainer
|
||||
className={containerClassName}
|
||||
enableAnimation={enableAnimation}
|
||||
ref={ref}
|
||||
{...imageContainerProps}
|
||||
>
|
||||
{children}
|
||||
</ImageContainer>
|
||||
)}
|
||||
loader={
|
||||
includeLoader ? (
|
||||
<ImageContainer className={containerClassName}>
|
||||
<ImageLoader className={className} />
|
||||
</ImageContainer>
|
||||
) : null
|
||||
}
|
||||
src={inView ? src : FALLBACK_SVG}
|
||||
unloader={
|
||||
includeUnloader ? (
|
||||
<ImageContainer className={containerClassName}>
|
||||
<ImageUnloader className={className} />
|
||||
</ImageContainer>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
<Img
|
||||
className={clsx(styles.image, className, {
|
||||
[styles.animated]: enableAnimation,
|
||||
})}
|
||||
container={(children) => (
|
||||
<ImageContainer
|
||||
className={containerClassName}
|
||||
enableAnimation={enableAnimation}
|
||||
ref={ref}
|
||||
{...imageContainerProps}
|
||||
>
|
||||
{children}
|
||||
</ImageContainer>
|
||||
)}
|
||||
</InView>
|
||||
loader={
|
||||
includeLoader ? (
|
||||
<ImageContainer className={containerClassName}>
|
||||
<ImageLoader className={className} />
|
||||
</ImageContainer>
|
||||
) : null
|
||||
}
|
||||
src={inViewport ? src : FALLBACK_SVG}
|
||||
unloader={
|
||||
includeUnloader ? (
|
||||
<ImageContainer className={containerClassName}>
|
||||
<ImageUnloader className={className} />
|
||||
</ImageContainer>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -100,24 +99,15 @@ const ImageContainer = forwardRef(
|
|||
}
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className={clsx(styles.imageContainer, className)}
|
||||
ref={ref}
|
||||
{...animationProps.fadeIn}
|
||||
{...props}
|
||||
>
|
||||
<div className={clsx(styles.imageContainer, className)} ref={ref} {...props}>
|
||||
{children}
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
function ImageLoader({ className }: ImageLoaderProps) {
|
||||
return (
|
||||
<div className={clsx(styles.loader, className)}>
|
||||
<Skeleton className={clsx(styles.skeleton, className)} enableAnimation={true} />
|
||||
</div>
|
||||
);
|
||||
return <Skeleton className={clsx(styles.skeleton, styles.loader, className)} />;
|
||||
}
|
||||
|
||||
function ImageUnloader({ className }: ImageUnloaderProps) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue