Lucas Caires
Lucas Caires

Reputation: 1

Resize Height IMG on Wheelzoom.js

I'm trying to make a zoomable image on a modal and I'm using wheelzoom.js

It's almost perfect, but I need to resize the image Height that is auto, by default, when the orientation of the img is Horizontal. And resize the width when its vertical!

Also, the zoom must work with pinch move.

Here's my project on a freehost

My demo.html:

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Wheelzoom</title>
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        .containerzoom {
            border: 1px dashed;
            /* Borda visual para identificar o contêiner */
            height: 98dvh;
            /* Usando unidade 'dvh' para melhor responsividade em dispositivos móveis */
            max-width: 100vw;
            /* Garante que o contêiner não ultrapasse a largura da viewport */
            display: flex;
            justify-content: center;
            /* Centraliza a imagem horizontalmente */
            align-items: center;
            /* Centraliza a imagem verticalmente */
            position: relative;
            /* Necessário para posicionar elementos dentro */
            overflow: hidden;
            /* Garante que o conteúdo que ultrapassa seja cortado */
            top: 10px;
            /* Desloca o contêiner para baixo */
        }

        .containerzoom img {
            border: 2px solid;
            /* Borda para a imagem se necessário */
            max-width: 100%;
            /* Limita a largura máxima da imagem */
            max-height: 100%;
            /* Limita a altura máxima da imagem */
            width: auto;
            /* Mantém a proporção correta */
            height: auto;
            /* Mantém a proporção correta */
            object-fit: contain;
            /* Ajusta a imagem dentro da div, mantendo a proporção */
            transition: transform 0.3s ease;

            /* Indica que a imagem pode ser ampliada */
        }

        /* .containerzoom img:active {
            cursor: move;
        } */

        .zoom-button {
            position: absolute;
            top: 40px;
            background: rgba(255, 255, 255, 0.7);
            border: 1px solid #ccc;
            border-radius: 5px;
            padding: 10px;
            cursor: pointer;
            font-size: 16px;
            margin-left: auto;
        }

        .zoom-in {
            left: 10px;
        }

        .zoom-out {
            left: 90px;
        }
    </style>
</head>

<body>
    <div class="containerzoom">
        <img class='zoom zoomedimage'
            src='https://img.freepik.com/free-photo/panoramic-shot-erg-chebbi-dunes-sahara-desert-merzouga-morocco_181624-16129.jpg?t=st=1727474703~exp=1727478303~hmac=e729edeeaed62fafb9627aa20e68dd4d79a4fdc2c7daeda09c619101c99e9e63&w=1380'
            alt='Daisy!' />
        <!-- <img class='zoom zoomedimage' src='http://localhost/apis/gallery-box/img/image%20(112).jpeg' alt='Daisy!' /> -->

    </div>

    <button class="zoom-button zoom-in">Zoom In</button>
    <button class="zoom-button zoom-out">Zoom Out</button>



    <script src="wheelzoom.js"></script>
    <script>
        const img = document.querySelector('img.zoom');
        wheelzoom(img);

        const zoomInButton = document.querySelector('.zoom-in');
        const zoomOutButton = document.querySelector('.zoom-out');

        // Função para atualizar os estilos dos botões
        function updateZoomButtons() {
            const currentBgSize = img.style.backgroundSize.split(' ')[0] || '100%'; // Pega a largura atual ou padrão
            const width = parseFloat(currentBgSize); // Converte para número

            // Tamanho padrão
            const defaultSize = img.clientWidth;

            // Atualiza a opacidade e o cursor do botão de zoom out
            if (width <= defaultSize) {
                zoomOutButton.style.opacity = 0.5;
                zoomOutButton.style.cursor = 'default';
                zoomOutButton.disabled = true; // Desabilita o botão
            } else {
                zoomOutButton.style.opacity = 1;
                zoomOutButton.style.cursor = 'pointer';
                zoomOutButton.disabled = false; // Habilita o botão
            }

            // Usa o valor de width atual para verificar se o zoom máximo foi atingido
            if (width >= defaultSize * 2.4) { // Defina o fator de zoom máximo desejado
                console.log(`Desabilitando o botão Zoom In: width = ${width}, defaultSize = ${defaultSize}`);
                zoomInButton.style.opacity = 0.5;
                zoomInButton.style.cursor = 'default'; // Cursor padrão
                zoomInButton.disabled = true; // Desabilita o botão
            } else {
                zoomInButton.style.opacity = 1;
                zoomInButton.style.cursor = 'pointer'; // Cursor pointer
                zoomInButton.disabled = false; // Habilita o botão
            }

            // Log do tamanho atual da imagem
            console.log(`Tamanho atual da imagem: ${width}px`);
        }

        zoomInButton.addEventListener('click', () => {
            const event = new WheelEvent('wheel', { deltaY: -50, bubbles: true, cancelable: true });
            img.dispatchEvent(event);
            updateZoomButtons();
        });

        zoomOutButton.addEventListener('click', () => {
            const currentBgSize = img.style.backgroundSize.split(' ')[0] || '100%';
            const width = parseFloat(currentBgSize);

            if (width > img.clientWidth) {
                const event = new WheelEvent('wheel', { deltaY: 50, bubbles: true, cancelable: true });
                img.dispatchEvent(event);
                updateZoomButtons();
            }
        });

        updateZoomButtons(); // Chama inicialmente para configurar os botões
    </script>
</body>

</html>

And my Wheelzoom.js:

window.wheelzoom = (function () {
    var defaults = {
        zoom: 0.20,
        maxZoom: 5,
        initialZoom: 1,
        initialX: 0.5,
        initialY: 0.5,
    };

    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 transparentSpaceFiller;

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

        function updateBgStyle() {
            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 = e.deltaY ? e.deltaY : -e.wheelDelta;
            e.preventDefault();

            var rect = img.getBoundingClientRect();
            var offsetX = e.pageX - rect.left - window.pageXOffset;
            var offsetY = e.pageY - rect.top - window.pageYOffset;

            var bgCursorX = offsetX - bgPosX;
            var bgCursorY = offsetY - bgPosY;

            var bgRatioX = bgCursorX / bgWidth;
            var bgRatioY = bgCursorY / bgHeight;

            if (deltaY < 0) {
                bgWidth += bgWidth * settings.zoom;
                bgHeight += bgHeight * settings.zoom;
                img.style.cursor = 'move';
            } else {
                bgWidth -= bgWidth * settings.zoom;
                bgHeight -= bgHeight * settings.zoom;
                img.style.cursor = 'default';
            }

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

            bgPosX = offsetX - (bgWidth * bgRatioX);
            bgPosY = offsetY - (bgHeight * bgRatioY);

            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;
            updateBgStyle();
        }

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

        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 === transparentSpaceFiller) return;

            var computedStyle = window.getComputedStyle(img, null);
            width = parseInt(computedStyle.width, 10);
            height = parseInt(computedStyle.height, 10);
            bgWidth = width * initial;
            bgHeight = height * initial;
            bgPosX = -(bgWidth - width) * settings.initialX;
            bgPosY = -(bgHeight - height) * settings.initialY;

            setSrcToBackground(img);

            img.style.backgroundSize = bgWidth + 'px ' + bgHeight + 'px';
            img.style.backgroundPosition = bgPosX + 'px ' + bgPosY + 'px';
            img.addEventListener('wheelzoom.reset', reset);
            img.addEventListener('wheel', onwheel, { passive: false });
            img.addEventListener('mousedown', draggable);
        }

        function touchStart(e) {
            e.preventDefault();
            previousEvent = e.touches[0];
            document.addEventListener('touchmove', touchMove);
            document.addEventListener('touchend', touchEnd);
        }

        function touchMove(e) {
            e.preventDefault();
            bgPosX += (e.touches[0].pageX - previousEvent.pageX);
            bgPosY += (e.touches[0].pageY - previousEvent.pageY);
            previousEvent = e.touches[0];
            updateBgStyle();
        }

        function touchEnd() {
            document.removeEventListener('touchmove', touchMove);
            document.removeEventListener('touchend', touchEnd);
        }

        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.removeEventListener('touchstart', touchStart);
            img.removeEventListener('touchmove', touchMove);
            img.removeEventListener('touchend', touchEnd);

            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);
        img.addEventListener('touchstart', touchStart, { passive: false });
    };

    if (typeof window.btoa !== 'function') {
        return function (elements) {
            return elements;
        };
    } else {
        return function (elements, options) {
            if (elements && elements.length) {
                Array.prototype.forEach.call(elements, function (node) {
                    main(node, options);
                });
            } else if (elements && elements.nodeName) {
                main(elements, options);
            }
            return elements;
        };
    }
}());

Upvotes: 0

Views: 50

Answers (0)

Related Questions