Setting Up Magnifier (Image Zoom Loupe) in 1C-Bitrix
Magnifier works only when source image is large enough. Stores upload 800×800 photos, enable magnifier, user sees blurry pixelated square on hover — because library tries zooming image in insufficient resolution. Problem is not JavaScript but how Bitrix stores and resizes images.
Two Images: Display and Zoom Version
Magnifier libraries (EasyZoom, Drift, jQuery Zoom) work one way: <img> tag contains small version, data-zoom or parent element's href contains large. Without large version, loupe zooms same small image — unacceptable result.
Bitrix has two fields for each iblock element image: PREVIEW_PICTURE and DETAIL_PICTURE. For magnifier need third — original without resize. Standard catalog.element component passes images through CFile::ResizeImageGet(), saving reduced copy to /upload/resize_cache/. Original stays in /upload/iblock/.
Template must pass both paths:
$fileId = $arResult['DETAIL_PICTURE']['ID'];
$fileInfo = \CFile::GetFileArray($fileId);
// Reduced for display
$resized = \CFile::ResizeImageGet($fileId, ['width' => 600, 'height' => 600], BX_RESIZE_IMAGE_PROPORTIONAL);
// Original for zoom
$original = \CHTTP::URN2URI($fileInfo['SRC']);
Resolution Threshold Setup
Running magnifier on 600×600 image pointless — zoom effect appears only with scaling coefficient less than one. Real threshold: original must be 2× larger than displayed. Check in template:
$zoomEnabled = ($fileInfo['WIDTH'] >= 1200 && $fileInfo['HEIGHT'] >= 1200);
If smaller — don't output data-zoom attribute, library doesn't initialize for this element. User doesn't see broken loupe.
Connecting Library via Bitrix Assets
Connect library via \Bitrix\Main\Page\Asset, not hardcode <script> in template — prevents duplication with multiple components on page:
\Bitrix\Main\Page\Asset::getInstance()->addJs('/local/js/drift.min.js');
\Bitrix\Main\Page\Asset::getInstance()->addCss('/local/css/drift-basic.min.css');
Initialize via inline-script at template end:
document.querySelectorAll('.product-zoom-trigger').forEach(function(el) {
new Drift(el.querySelector('img'), {
paneContainer: document.querySelector('.product-zoom-pane'),
zoomFactor: 3,
hoverBoundingBox: true,
});
});
Gallery with Multiple Images
When product has multiple photos (MORE_PHOTO), loupe must recreate on active image change. Typical error — initialize new Drift() once on load. Clicking another thumbnail — instance stays bound to old <img>, new element already in DOM.
Correct: store instance in variable, call driftInstance.destroy() before creating new on each photo switch.
Mobile Devices
On touch screens magnifier useless — hover doesn't work. Need pinch-to-zoom. PhotoSwipe solves both: desktop opens fullscreen zoom view, mobile supports gestures. Use Drift and PhotoSwipe simultaneously: Drift for pointer: fine (mouse), PhotoSwipe for pointer: coarse (touch). Detect via CSS media query @media (pointer: coarse) and JS window.matchMedia().







