Online demo:
React component:
React demo app:
Мной разработан модуль, предоставляющий приложениям современный лайтбокс для web, максимально приближающий просмотр фотоизображений на веб-странице к просмотру в телефоне (и превосходящий его по возможостям)
В основе - простые идеи:
Фотки на сайте должно быть также удобно смотреть, как в мобильном приложении, и даже лучше - как в Фотошопе!
Изображения любого разрешения и размера должны подгружаться по требованию, как видео, автоматически, при увеличении масштаба пользователем, а об "оптимизации изображений" для сайта давно следует забыть.
Finally image viewer - современный модуль для просмотра изображений в web, реализующий эти принципы и предоставляющий совершенно иной уровень удобства для пользователя.
- Полная поддержка мобильных браузеров, управление жестами.
- Свободное увеличение до любого масштаба без необходимости удержания картинки пальцами.
- Плавный скроллинг картинки без эффекта трения и остановок.
- При увеличении свыше определённого уровня автоматически подгружается высокое разрешение, если соответствующий файл есть на сервере.
- Естественное листание галереи и выход из нее разнонаправленными свайпами. Поддержка кнопки "назад" на телефоне.
- Возможность обходиться при просмотре с мобильного одной рукой.
Установка react компонента
npm install github:valery-designer/finally-lightbox-react
Применение
Импортируйте сам компонент и reference из react:
import { useRef } from 'react';
import Lightbox from 'finally-lightbox-react';
В начале компонента вашего приложения объявите ссылку на лайтбокс:
const lightboxReference = useRef({});
В конце темплейта компонента вашего приложения разместите сам лайтбокс:
<Lightbox lightboxReference = { lightboxReference } />
Компонент лайтбокса размещается в единственном экземпляре, данные об изображениях передаются ему в виде массива. Это позволяет сохранять приложение лёгким.
Чтобы открыть лайтбокс, нужно вызвать функцию openInLightbox по ссылке на экземпляр лайтбокса и передать ей событие и массив ссылок на изображения.
Пример для отдельного изображения:
<img
src='dog01.jpg'
onClick = {
(e) => {
lightboxReference.current.openInLightbox( e, [
{ src: 'dog01.jpg' }
]);
}
}
/>
В атрибуте src тэга img указывается изображение, отображаемое на странице, а в компоненте открывается изображение, источник когорого указан в массиве. Они могут не совпадать, что позволяет использовать в качестве превью или ссылки на изображение любой элемент страницы.
Далее, компонент пытается подгружать последовательно файлы из того же источника, в имени которых к исходному имени перед расширением добавлены обозначения стадий (stage): st0, st1 и st2. То есть, если исходное имя файла, передаваемое в массиве - cat.jpg, для работы компонента достаточно положить рядом файлы cat.st0.jpg, cat.st1.jpg и cat.st2.jpg, содержащие то же изображение во всё большем разрешении.
При этом, самый большой файл cat.st2.jpg будет загружаться лишь по необходимости - при увеличении масштаба просмотра свыше определенного значения.
Если файл стадии на сервере отсутствует, ничего страшного на произойдёт - компонент будет просто увеличивать существующее изображение.
При подготовке файлов стадий нужно учесть, что все они должны быть одних пропорций (иметь одно и то же соотношение сторон). Также, лучше не делать hires-файл второй (st2) стадии безумно большим - чудес всё-таки не бывает, и вероятны подтормаживания интерфейса.
Полный пример для отдельного изображения:
import './App.css';
import { useRef } from 'react';
import Lightbox from 'finally-lightbox-react';
function App() {
const lightboxReference = useRef({});
return (
<>
<div className="App">
<img
src='dog01.jpg'
onClick = {
(e) => {
lightboxReference.current.openInLightbox( e, [
{ src: 'dog01.jpg' }
]);
}
}
/>
<Lightbox lightboxReference = {lightboxReference } />
</div>
</>
)
}
export default App
Пример применения совместно с компонентами material design
import './App.css';
import { useRef } from 'react';
import Lightbox from 'finally-lightbox-react';
// Material UI components
import ImageList from '@mui/material/ImageList';
import ImageListItem from '@mui/material/ImageListItem';
function App() {
// Reference on lightbox component
const lightboxReference = useRef({});
// Images data array to be sent to the openInLightbox function
const pets = [
{ src:'dog01.jpg', title: 'My dog' },
{ src:'cat01.jpg', title: 'My cat' },
{ src:'dog02.jpg', title: 'Another dog' }
];
return (
<>
<div className="App">
<ImageList cols={ 3 } variant={ 'quilted' }>
{ pets.map((item) => (
<ImageListItem sx={{ aspectRatio: '1 / 1' }} key={item.src}>
<img
src={item.src}
alt={item.title}
onClick = {
(e) => {
lightboxReference.current.openInLightbox(e, pets);
}
}
/>
</ImageListItem>
)) }
</ImageList>
{/* Lightbox component */}
<Lightbox lightboxReference={lightboxReference} />
</div>
</>
)
}
export default App;
Учтите, что компонент всё ещё в процессе разработки на стадии альфа-версии. Он не поддерживает trackpad на устройствах apple, есть также проблемы в Safari для ios.