Налаштування лупи (magnifier) для зображень товарів у 1С-Бітрікс
Лупа працює лише коли вихідне зображення достатньо велике. На практиці магазини завантажують фото 800×800, включають magnifier, і користувач при наведенні бачит розмитий пікселевий квадрат — тому що бібліотека намагається збільшити зображення, якого просто немає в потрібній роздільній здатності. Проблема не в JavaScript, а в тому, як Бітрікс зберігає та ресайзит зображення.
Два зображення: відображене та зум-версія
Magnifier-бібліотека (EasyZoom, Drift, jQuery Zoom) працює по одному принципу: в тезі <img> — зменшена версія, в атрибуті data-zoom або батьківського елемента — велика. Без великої версії лупа збільшує те ж маленьке зображення — результат неприйнятний.
У Бітріксі для кожного зображення елемента інфоблока є два поля: PREVIEW_PICTURE та DETAIL_PICTURE. Для magnifier потрібен третій варіант — оригінал без ресайзу. Стандартний компонент catalog.element пропускає всі зображення через CFile::ResizeImageGet(), який записує зменшену копію в /upload/resize_cache/. Оригінал при цьому залишається в /upload/iblock/.
У шаблоні потрібно передавати обидва шляхи:
$fileId = $arResult['DETAIL_PICTURE']['ID'];
$fileInfo = \CFile::GetFileArray($fileId);
// Зменшена версія для відображення
$resized = \CFile::ResizeImageGet($fileId, ['width' => 600, 'height' => 600], BX_RESIZE_IMAGE_PROPORTIONAL);
// Оригінал для зуму
$original = \CHTTP::URN2URI($fileInfo['SRC']);
Налаштування порогової роздільної здатності
Запускати magnifier на зображенні 600×600 безглуздо — зум-ефект з'являється лише при коефіцієнті збільшення менше одиниці. Реальний поріг: оригінал повинен бути мінімум в 2× більше за відображене. Перевірка в шаблоні:
$zoomEnabled = ($fileInfo['WIDTH'] >= 1200 && $fileInfo['HEIGHT'] >= 1200);
Якщо менше — не виводьте атрибут data-zoom, бібліотека не ініціалізується для цього елемента. Користувач не бачить зламаної лупи.
Підключення бібліотеки через Assets Бітрікса
Бібліотеку потрібно підключати через \Bitrix\Main\Page\Asset, а не хардкодити <script> у шаблоні — інакше при кількох компонентах на сторінці буде дублювання:
\Bitrix\Main\Page\Asset::getInstance()->addJs('/local/js/drift.min.js');
\Bitrix\Main\Page\Asset::getInstance()->addCss('/local/css/drift-basic.min.css');
Ініціалізація через inline-скрипт у кінці шаблону:
document.querySelectorAll('.product-zoom-trigger').forEach(function(el) {
new Drift(el.querySelector('img'), {
paneContainer: document.querySelector('.product-zoom-pane'),
zoomFactor: 3,
hoverBoundingBox: true,
});
});
Галерея з кількома зображеннями
Коли у товара кілька фото (MORE_PHOTO), лупа повинна пересоздаватися при зміні активного зображення. Типова помилка — ініціалізація new Drift() один раз при завантаженні. При клику на іншу мініатюру екземпляр залишається прив'язаним до старого <img>, а в DOM вже новий елемент.
Правильно: зберігати екземпляр у змінній і викликати driftInstance.destroy() перед створенням нового при кожному переключенні фото.
Мобільні пристрої
На touch-екранах magnifier марний — hover-події не працюють. Замість лупи потрібен pinch-to-zoom. Бібліотека PhotoSwipe вирішує обидві задачи: на десктопу відкриває повноекранний просмотр зі масштабуванням, на мобільному підтримує жести. Drift та PhotoSwipe можна використовувати одночасно: Drift — лише для pointer: fine (мишка), PhotoSwipe — для pointer: coarse (сенсор). Це визначається через CSS медіа-запит @media (pointer: coarse) та аналогічну перевірку в JS через window.matchMedia().







