Setting up Zoom viewing of 1C-Bitrix product images

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    565
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    980

Setting Up Zoom Viewing of Product Images in 1C-Bitrix

Buyer wants to examine serial number on label or fabric texture. Standard Bitrix product card component shows fixed-size image. Zoom added at template level without core changes.

Product Images in Catalog

Main product image stored in iblock property type F with code MORE_PHOTO (multiple) or in PREVIEW_PICTURE / DETAIL_PICTURE fields of b_iblock_element table — file IDs from b_file.

For zoom need original high-resolution image. Problem: standard Bitrix resize reduces images via \CFile::ResizeImageGet(). Original stays in b_file with full path.

Get both paths:

$detailPictureId = $arResult['DETAIL_PICTURE']['ID'];

// Original (for zoom)
$originalPath = \CFile::GetPath($detailPictureId);

// Preview (400x400)
$previewInfo = \CFile::ResizeImageGet($detailPictureId, ['width' => 400, 'height' => 400], BX_RESIZE_IMAGE_PROPORTIONAL, true);
$previewPath = $previewInfo['src'];

Zoom via CSS Transform

Simplest zoom without libraries — CSS cursor: zoom-in + transform: scale on click. Works for basic needs:

.product-image-zoom {
    overflow: hidden;
    cursor: zoom-in;
    position: relative;
}

.product-image-zoom img {
    transition: transform 0.3s ease;
    transform-origin: var(--zoom-x, 50%) var(--zoom-y, 50%);
}

.product-image-zoom.zoomed img {
    transform: scale(2.5);
    cursor: zoom-out;
}
const container = document.querySelector('.product-image-zoom');
const img = container.querySelector('img');

container.addEventListener('mousemove', function (e) {
    if (!container.classList.contains('zoomed')) return;
    const rect = container.getBoundingClientRect();
    const x = ((e.clientX - rect.left) / rect.width * 100).toFixed(1) + '%';
    const y = ((e.clientY - rect.top) / rect.height * 100).toFixed(1) + '%';
    container.style.setProperty('--zoom-x', x);
    container.style.setProperty('--zoom-y', y);
});

container.addEventListener('click', function () {
    container.classList.toggle('zoomed');
    if (container.classList.contains('zoomed')) {
        img.src = img.dataset.originalSrc;
    }
});

In component template:

<div class="product-image-zoom">
    <img src="<?= $previewPath ?>"
         data-original-src="<?= $originalPath ?>"
         alt="<?= htmlspecialchars($arResult['NAME']) ?>">
</div>

Lens Zoom (Magnifying Glass Effect)

Professional solution — "lens": on hover over thumbnail, magnified area appears nearby. Drift library — 3KB no dependencies:

import Drift from 'drift-zoom';

new Drift(document.querySelector('.product-image-zoom img'), {
    paneContainer: document.querySelector('.zoom-pane'),
    inlinePane: false,
    zoomFactor: 3,
    hoverBoundingBox: true,
});

For Drift, image needs data-zoom attribute with high-resolution image URL:

<img src="<?= $previewPath ?>"
     data-zoom="<?= $originalPath ?>"
     alt="Product">
<div class="zoom-pane"></div>

Original Image Requirements

Zoom works well only if original image has sufficient resolution. With 3x scaling, 400×400 image gives 133×133px original lens — blurry. Recommended minimum for zoomFactor: 3 — original 1600×1600px.

If originals arrive in low resolution, disable zoom conditionally:

$fileInfo = \CFile::GetFileArray($detailPictureId);
$showZoom = ($fileInfo['WIDTH'] >= 1200 && $fileInfo['HEIGHT'] >= 1200);

Gallery with Zoom

For cards with multiple images (MORE_PHOTO) zoom applies to active image. On slide switch reinitialize zoom instance with new URL:

function switchImage(url, originalUrl) {
    mainImg.src = url;
    mainImg.dataset.zoom = originalUrl;
    if (window.driftInstance) {
        window.driftInstance.destroy();
    }
    window.driftInstance = new Drift(mainImg, driftOptions);
}

Initialize zoom after image load or wrap in DOMContentLoaded. On touchscreen devices hover doesn't work — need separate tap-to-zoom logic or fullscreen via Fancybox with data-fancybox="gallery" on each gallery element.