MDX предоставляет уникальную возможность комбинировать Markdown и JSX, что позволяет создавать интерактивные компоненты прямо в документации или веб-приложении. Одной из важных задач при работе с визуальными медиа является организация масштабирования изображений (zoom) и использование лайтбоксов для удобного просмотра контента.
Для реализации увеличения изображений можно использовать популярные
библиотеки, например react-medium-image-zoom или
react-inner-image-zoom. Эти библиотеки обеспечивают плавное
масштабирование изображений и интегрируются с JSX-компонентами.
Пример использования react-medium-image-zoom в MDX:
import Zoom from 'react-medium-image-zoom'
import 'react-medium-image-zoom/dist/styles.css'
Ключевые моменты:
оборачивает обычный
![]()
элемент.Лайтбоксы позволяют открывать медиа-контент в модальном окне,
создавая эффект фокусировки на изображении или галерее. Одной из часто
используемых библиотек является react-image-lightbox.
Пример интеграции:
import { useState } from 'react';
import Lightbox from 'react-image-lightbox';
import 'react-image-lightbox/style.css';
const images = [
'/images/photo1.jpg',
'/images/photo2.jpg',
'/images/photo3.jpg'
];
function Gallery() {
const [isOpen, setIsOpen] = useState(false);
const [photoIndex, setPhotoIndex] = useState(0);
return (
<>
{images.map((src, index) => (
{
setPhotoIndex(index);
setIsOpen(true);
}}
/>
))}
{isOpen && (
setIsOpen(false)}
onMovePrevRequ est={() =>
setPhotoIndex((photoIndex + images.length - 1) % images.length)
}
onMoveNextRequ est={() =>
setPhotoIndex((photoIndex + 1) % images.length)
}
/>
)}
>
);
}
Особенности:
nextSrc и
prevSrc.useState.Для создания более интерактивного интерфейса можно комбинировать обе технологии: предварительный zoom при наведении и открытие лайтбокса при клике.
import Zoom from 'react-medium-image-zoom';
import Lightbox from 'react-image-lightbox';
import { useState } from 'react';
import 'react-medium-image-zoom/dist/styles.css';
import 'react-image-lightbox/style.css';
function InteractiveGallery({ images }) {
const [isOpen, setIsOpen] = useState(false);
const [photoIndex, setPhotoIndex] = useState(0);
return (
<>
{images.map((src, index) => (
{
setPhotoIndex(index);
setIsOpen(true);
}}
/>
))}
{isOpen && (
setIsOpen(false)}
onMovePrevRequ est={() =>
setPhotoIndex((photoIndex + images.length - 1) % images.length)
}
onMoveNextRequ est={() =>
setPhotoIndex((photoIndex + 1) % images.length)
}
/>
)}
>
);
}
Преимущества комбинированного подхода:
Для корректного отображения на различных устройствах рекомендуется использовать CSS-медиа-запросы и стили с процентными ширинами:
img {
max-width: 100%;
height: auto;
}
.gallery {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
Рекомендации по стилям: