11
Июн
2021

Изменить размер изображения со смещением элементов

Нужно по колесику мыши менять размер изображения, при этом элементы на данном изображении должны оставаться как бы на своих местах. Скрипт для zoom'а изображения нашел на просторах интернета, но вот добавить функционал для элементов не могу.

Пример. Исходный размер изображения с элементами Исходный размер изображения

После прокрутки колесика мыши на один пункт вперед, изображение приближается в место курсора, а элементы уже не на своих местах находятся. Новый размер изображения

Не могу никак смещение правильно рассчитать. Ожидаемый результат: Правый зеленый прямоугольник должен располагаться на месте, где находится красный. Левый прямоугольник скроется, так как не будет видно левой части изображения Правильное изображение

Код HTML

 <style>
    .wrapper-img{
        position: relative;
        width: 550px;
        height: 600px;
    }

    .wrapper-img div{
        position: absolute;
        width: 30px;
        height: 20px;
        background-color: green;
    }

    .wrapper-img img{
        width: 500px;
        height: 500px;
    }

    div.item1{
        top: 50px;
        left: 220px;
    }

    div.item2{
        top: 128px;
        left: 1px;

    }

</style>
<div class="wrapper-img">
  <img src="test-2.png" alt="">
  <div class="item1"></div>
  <div class="item2"></div>
</div>

Скрипт

window.wheelzoom = (function(){
            var deltaY = 0;
            var defaults = {
                zoom: 0.30,
                maxZoom: false,
                initialZoom: 1,
            };

            var main = function(img, options){
                if (!img || !img.nodeName || img.nodeName !== 'IMG') { return; }

                var settings = {};
                var width;
                var height;
                var bgWidth;
                var bgHeight;
                var bgPosX;
                var bgPosY;
                var previousEvent;
                var cachedDataUrl;
                var DragMarginTop;

                function setSrcToBackground(img) {
                    img.style.backgroundRepeat = 'no-repeat';
                    img.style.backgroundImage = 'url("'+img.src+'")';
                    cachedDataUrl = 'data:image/svg+xml;base64,'+window.btoa('<svg xmlns="http://www.w3.org/2000/svg" width="'+img.naturalWidth+'" height="'+img.naturalHeight+'"></svg>'); //'data:image/svg+xml;base64,'+window.btoa('<svg xmlns="http://www.w3.org/2000/svg" width="'+img.naturalWidth+'" height="'+img.naturalHeight+'"></svg>');
                    img.src = cachedDataUrl;
                }

                function updateBgStyle() {
                    // let deltaY = 0;
                    // if (e.deltaY) { // FireFox 17+ (IE9+, Chrome 31+?)
                    //     deltaZ = e.deltaY;
                    // } else if (e.wheelDelta) {
                    //     deltaY = -e.wheelDelta;
                    // }
                    // deltaY = -e.wheelDelta;
                if (bgPosX > 0) {
                        bgPosX = 0;
                    } else if (bgPosX < width - bgWidth) {
                        bgPosX = width - bgWidth;
                    }

                    if (bgPosY > 0) {
                        bgPosY = 0;
                    } else if (bgPosY < height - bgHeight) {
                        bgPosY = height - bgHeight;
                    }

                    img.style.backgroundSize = bgWidth+'px '+bgHeight+'px';
                    img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px';
                }

                function reset() {
                    bgWidth = width;
                    bgHeight = height;
                    bgPosX = bgPosY = 0;
                
                    updateBgStyle();
                }

                function onwheel(e) {
                    // var deltaY = 0;
                    
                    e.preventDefault();

                    if (e.deltaY) { // FireFox 17+ (IE9+, Chrome 31+?)
                        deltaY = e.deltaY;
                    } else if (e.wheelDelta) {
                        deltaY = -e.wheelDelta;
                    }


                    // As far as I know, there is no good cross-browser way to get the cursor position relative to the event target.
                    // We have to calculate the target element's position relative to the document, and subtrack that from the
                    // cursor's position relative to the document.
                    var rect = img.getBoundingClientRect();
                    
                    var offsetX = e.pageX - rect.left - window.pageXOffset;
                    var offsetY = e.pageY - rect.top - window.pageYOffset;

                    // Record the offset between the bg edge and cursor:
                    var bgCursorX = offsetX - bgPosX;
                    var bgCursorY = offsetY - bgPosY;

                    // Use the previous offset to get the percent offset between the bg edge and cursor:
                    var bgRatioX = bgCursorX/bgWidth;
                    var bgRatioY = bgCursorY/bgHeight;

                    // Update the bg size:
                    if (deltaY < 0) {
                        if(bgWidth > img.naturalWidth) return;
                        bgWidth += bgWidth*settings.zoom;
                        bgHeight += bgHeight*settings.zoom;
                    } else {
                        bgWidth -= bgWidth*settings.zoom;
                        bgHeight -= bgHeight*settings.zoom;
                    }

                    // console.log("bgPosY ", bgPosY);

                    if (settings.maxZoom) {
                        bgWidth = Math.min(width*settings.maxZoom, bgWidth);
                        bgHeight = Math.min(height*settings.maxZoom, bgHeight);
                    }

                    // Take the percent offset and apply it to the new size:
                    bgPosX = offsetX - (bgWidth * bgRatioX);
                    bgPosY = offsetY - (bgHeight * bgRatioY);
                    console.log("bgPosX ", bgPosX, " bgPosY ", bgPosY);
                    // Prevent zooming out beyond the starting size
                    if (bgWidth <= width || bgHeight <= height) {
                        reset();
                    } else {
                        updateBgStyle();
                    }
                }

                function drag(e) {
                    e.preventDefault();
                    bgPosX += (e.pageX - previousEvent.pageX);
                    bgPosY += (e.pageY - previousEvent.pageY);
                    previousEvent = e;
                    // console.log("bgPosX ", bgPosX, " bgPosY ", bgPosY, " zoom ", settings.zoom, " zoom ", settings.maxZoom);
                    updateBgStyle();
                }

                function removeDrag() {
                    document.removeEventListener('mouseup', removeDrag);
                    document.removeEventListener('mousemove', drag);
                }

                // Make the background draggable
                function draggable(e) {
                    e.preventDefault();
                    previousEvent = e;
                    document.addEventListener('mousemove', drag);
                    document.addEventListener('mouseup', removeDrag);
                }

                function load() {
                    var initial = Math.max(settings.initialZoom, 1);

                    if (img.src === cachedDataUrl) return;
                    
                    var computedStyle = window.getComputedStyle(img, null);

                    width = parseInt(computedStyle.width, 10);
                    height = parseInt(computedStyle.height, 10);
                    // width = document.querySelector("#viewport").offsetWidth;
                    // height = document.querySelector("#viewport").offsetHeight;
                    bgWidth = width * initial;
                    bgHeight = height * initial;
                    bgPosX = -(bgWidth - width)/2;
                    bgPosY = -(bgHeight - height)/2;
                    // dragMarginTop = $('[name')

                    setSrcToBackground(img);

                    img.style.backgroundSize = bgWidth+'px '+bgHeight+'px';
                    // img.style.backgroundSize = '600px';
                    img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px';
                    console.log("margin-top ", $("[name=12]").css("margin-top"));
                    img.addEventListener('wheelzoom.reset', reset);

                    img.addEventListener('wheel', onwheel);
                    img.addEventListener('mousedown', draggable);
                }

                var destroy = function (originalProperties) {
                    img.removeEventListener('wheelzoom.destroy', destroy);
                    img.removeEventListener('wheelzoom.reset', reset);
                    img.removeEventListener('load', load);
                    img.removeEventListener('mouseup', removeDrag);
                    img.removeEventListener('mousemove', drag);
                    img.removeEventListener('mousedown', draggable);
                    img.removeEventListener('wheel', onwheel);

                    img.style.backgroundImage = originalProperties.backgroundImage;
                    img.style.backgroundRepeat = originalProperties.backgroundRepeat;
                    img.src = originalProperties.src;
                }.bind(null, {
                    backgroundImage: img.style.backgroundImage,
                    backgroundRepeat: img.style.backgroundRepeat,
                    src: img.src
                });

                img.addEventListener('wheelzoom.destroy', destroy);

                options = options || {};

                Object.keys(defaults).forEach(function(key){
                    settings[key] = options[key] !== undefined ? options[key] : defaults[key];
                });

                if (img.complete) {
                    load();
                }

                img.addEventListener('load', load);
            };

            // Do nothing in IE9 or below
            if (typeof window.btoa !== 'function') {
                return function(elements) {
                    return elements;
                };
            } else {
                return function(elements, options) {
                    if (elements && elements.length) {
                        Array.prototype.forEach.call(elements, main, options);
                    } else if (elements && elements.nodeName) {
                        main(elements, options);
                    }
                    return elements;
                };
            }
        }());



        wheelzoom(document.querySelectorAll('.wrapper-img img'));
    });

Источник: https://ru.stackoverflow.com/questions/1294043/%D0%98%D0%B7%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80-%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D1%81%D0%BE-%D1%81%D0%BC%D0%B5%D1%89%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC-%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2

Тебе может это понравится...

Добавить комментарий