mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
fixed image preloading for swiper
This commit is contained in:
parent
71764af45f
commit
e2ffdcd1f2
2 changed files with 28 additions and 12 deletions
|
@ -1,16 +1,24 @@
|
||||||
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import SwiperCore, { Keyboard, Navigation, Pagination, SwiperOptions } from 'swiper';
|
import Image from 'next/future/image';
|
||||||
|
import SwiperCore, {
|
||||||
|
Keyboard,
|
||||||
|
Navigation,
|
||||||
|
Pagination,
|
||||||
|
SwiperOptions,
|
||||||
|
} from 'swiper';
|
||||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||||
import SwiperClass from 'swiper/types/swiper-class';
|
import SwiperClass from 'swiper/types/swiper-class';
|
||||||
|
|
||||||
import { ImagePreloader } from '~/components/media/ImagePreloader';
|
import { ImagePreloader } from '~/components/media/ImagePreloader';
|
||||||
import { INodeComponentProps } from '~/constants/node';
|
import { INodeComponentProps } from '~/constants/node';
|
||||||
|
import { ImagePresets } from '~/constants/urls';
|
||||||
import { useModal } from '~/hooks/modal/useModal';
|
import { useModal } from '~/hooks/modal/useModal';
|
||||||
import { useImageModal } from '~/hooks/navigation/useImageModal';
|
import { useImageModal } from '~/hooks/navigation/useImageModal';
|
||||||
import { useNodeImages } from '~/hooks/node/useNodeImages';
|
import { useNodeImages } from '~/hooks/node/useNodeImages';
|
||||||
import { normalizeBrightColor } from '~/utils/color';
|
import { normalizeBrightColor } from '~/utils/color';
|
||||||
|
import { getURL } from '~/utils/dom';
|
||||||
|
|
||||||
import styles from './styles.module.scss';
|
import styles from './styles.module.scss';
|
||||||
|
|
||||||
|
@ -27,7 +35,9 @@ const breakpoints: SwiperOptions['breakpoints'] = {
|
||||||
const pagination = { type: 'fraction' as const };
|
const pagination = { type: 'fraction' as const };
|
||||||
|
|
||||||
const NodeImageSwiperBlock: FC<IProps> = observer(({ node }) => {
|
const NodeImageSwiperBlock: FC<IProps> = observer(({ node }) => {
|
||||||
const [controlledSwiper, setControlledSwiper] = useState<SwiperClass | undefined>(undefined);
|
const [controlledSwiper, setControlledSwiper] = useState<
|
||||||
|
SwiperClass | undefined
|
||||||
|
>(undefined);
|
||||||
const showPhotoSwiper = useImageModal();
|
const showPhotoSwiper = useImageModal();
|
||||||
const { isOpened: isModalActive } = useModal();
|
const { isOpened: isModalActive } = useModal();
|
||||||
|
|
||||||
|
@ -38,7 +48,7 @@ const NodeImageSwiperBlock: FC<IProps> = observer(({ node }) => {
|
||||||
enabled: !isModalActive,
|
enabled: !isModalActive,
|
||||||
onlyInViewport: true,
|
onlyInViewport: true,
|
||||||
}),
|
}),
|
||||||
[isModalActive]
|
[isModalActive],
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateSwiper = useCallback(() => {
|
const updateSwiper = useCallback(() => {
|
||||||
|
@ -53,14 +63,17 @@ const NodeImageSwiperBlock: FC<IProps> = observer(({ node }) => {
|
||||||
|
|
||||||
const onOpenPhotoSwipe = useCallback(
|
const onOpenPhotoSwipe = useCallback(
|
||||||
(index: number) => {
|
(index: number) => {
|
||||||
if (index !== controlledSwiper?.activeIndex && controlledSwiper?.slideTo) {
|
if (
|
||||||
|
index !== controlledSwiper?.activeIndex &&
|
||||||
|
controlledSwiper?.slideTo
|
||||||
|
) {
|
||||||
controlledSwiper.slideTo(index, 300);
|
controlledSwiper.slideTo(index, 300);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
showPhotoSwiper(images, index);
|
showPhotoSwiper(images, index);
|
||||||
},
|
},
|
||||||
[images, controlledSwiper, showPhotoSwiper]
|
[images, controlledSwiper, showPhotoSwiper],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -116,12 +129,16 @@ const NodeImageSwiperBlock: FC<IProps> = observer(({ node }) => {
|
||||||
>
|
>
|
||||||
{images.map((file, i) => (
|
{images.map((file, i) => (
|
||||||
<SwiperSlide className={styles.slide} key={file.id}>
|
<SwiperSlide className={styles.slide} key={file.id}>
|
||||||
<ImagePreloader
|
<Image
|
||||||
file={file}
|
src={getURL(file, ImagePresets['1600'])}
|
||||||
|
width={file.metadata?.width}
|
||||||
|
height={file.metadata?.height}
|
||||||
onLoad={updateSwiper}
|
onLoad={updateSwiper}
|
||||||
onClick={() => onOpenPhotoSwipe(i)}
|
onClick={() => onOpenPhotoSwipe(i)}
|
||||||
className={styles.image}
|
className={styles.image}
|
||||||
color={normalizeBrightColor(file?.metadata?.dominant_color)}
|
color={normalizeBrightColor(file?.metadata?.dominant_color)}
|
||||||
|
alt=""
|
||||||
|
priority={i < 2}
|
||||||
/>
|
/>
|
||||||
</SwiperSlide>
|
</SwiperSlide>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -95,12 +95,12 @@
|
||||||
width: auto;
|
width: auto;
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
//transform: translate(0, 10px);
|
|
||||||
transform: scale(0.99);
|
transform: scale(0.99);
|
||||||
filter: brightness(50%) saturate(0.5);
|
filter: brightness(50%) saturate(0.5);
|
||||||
transition: opacity 0.5s, filter 0.5s, transform 0.5s;
|
transition: opacity 0.5s, filter 0.5s, transform 0.5s;
|
||||||
padding-bottom: $gap * 1.5;
|
padding-bottom: $gap * 1.5;
|
||||||
padding-top: $gap;
|
padding-top: $gap;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&:global(.swiper-slide-active) {
|
&:global(.swiper-slide-active) {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@ -117,12 +117,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
max-height: calc(100vh - 70px - 70px);
|
max-inline-size: min(calc(100vh - 70px - 70px), 100vw);
|
||||||
max-width: 100%;
|
block-size: auto;
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
transition: box-shadow 1s;
|
transition: box-shadow 1s;
|
||||||
box-shadow: transparentize(black, 0.7) 0 3px 5px;
|
box-shadow: transparentize(black, 0.7) 0 3px 5px;
|
||||||
opacity: 0;
|
|
||||||
|
|
||||||
:global(.swiper-slide-active) & {
|
:global(.swiper-slide-active) & {
|
||||||
box-shadow: transparentize(black, 0.9) 0 10px 5px 4px,
|
box-shadow: transparentize(black, 0.9) 0 10px 5px 4px,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue