Почему дрожит background в передвигаемом блоке в chrome?

Реализовал увеличение части изображения для каталога товаров. В Firefox, IE11, EDGE работает все отлично, а в chrome дергается высчитываемый background ( передвигаемого блока )

Реализация блока, отображающего увеличиваемую область, следующая:
1. Блок с самим изображением
2. Блок, затемняющий изображение
3. Блок-лупа, которая реализует "просвет" в блоке затемнителе и показывает увеличиваемую область изображения.

В последнем блоке и возникает проблема, при его перемещении дергается background (по горизонтали).

Эффект можно посмотреть тут (разумеется проблему нужно смотреть в хроме)
(полный код в файле main.js в конце функции initGallery)

UPD: перенес часть кода в codepen для демонстрации, но там таких лагов нет, но появляются, если уменьшить страницу (в хроме)


Собственно как можно исправить эту проблему в google chrome? И в чем она заключается?

часть html
<div class="image-full">
    <img>
    <div class="image-zoom-zone"> </div>
    <div class="image-zoom-fade"> </div>
</div>


часть JS, отвечающего за перемещение блока-лупы
// увеличиваемое изображение и блок - лупа, отображающий увеличиваемую область
var imageFull = imageFullContainer.firstElementChild;
var imageZone = gallery.querySelector(".image-zoom-zone");

// вызывается при наведении на изображение и при передвижении мышки
function move(event) {
    // координаты в окне, ширина и высота изображения
    var imageCoords = imageFull.getBoundingClientRect();
    var imageHeight  = imageFull.offsetHeight;
    var imageWidth = imageFull.offsetWidth;

    // Координаты мышки, относительно левого верхнего угла ИЗОБРАЖЕНИЯ
    var mouseX = event.clientX - imageCoords.left;
    var mouseY = event.clientY - imageCoords.top;

    // определение максимальных положений блока-лупы
    // (так, чтобы блок не выходил за края изображения)
    var zone = {
      left: Math.max(Math.min(mouseX - imageZone.offsetWidth/2, imageWidth - imageZone.offsetWidth), 0),
      top: Math.max(Math.min(mouseY - imageZone.offsetHeight/2, imageHeight - imageZone.offsetHeight), 0),
    }

    // позиционирование в блоке-лупы фона, для реализации "просвета"
    // значения у позиции фона отрицательные, для компенсации смещения блока
    imageZone.style.backgroundSize = imageFull.offsetWidth + "px";
    imageZone.style.backgroundPositionX = -zone.left + "px";
    imageZone.style.backgroundPositionY = -zone.top + "px";

    // положение блока-лупы относительно левого верхнего угла изображения
    // (двигается за мышкой, не пересекая границы изображения)
    imageZone.style.left = zone.left  + "px";
    imageZone.style.top = zone.top  + "px";
}


Пробовал так же реализовать через background-attachment: fixed;
Но это создает больше проблем, чем пользы (позиционировать фон все равно нужно, чтобы он совпадал с изображением, но при этом при прокрутке он фиксировался на месте (а не совпадал с изображением)
  • Вопрос задан
  • 852 просмотра
Пригласить эксперта
Ответы на вопрос 1
Stalker_RED
@Stalker_RED
Вы перекрываете оригинальную картинку затемняющим слоем а затем рисуете еще один квадратик с той-же картинкой имитируя прозрачность. И позиция фона этого квадратика иногда не совпадает с оригиналом.

Вместо этого можно:
1. выбросить затемняющий слой вообще
2. использовать действительно прозрачный блок, вокруг которого затемнение делается за счет border.
proof of concept: https://jsfiddle.net/66rpmfxf/

Осталось сделать бордер пошире и переписать координаты в onmousemove
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы