JS image magnifier

Keywords: Javascript

Today, I'm going to practice a small demo to read pictures locally,

And then achieve the effect similar to the magnifying glass of Taobao,

Two more needs

1. The scale can be adjusted, and the default magnification is twice

2. The width and height of the picture are adaptive and not fixed

If you don't say much, see the effect first:

 

 

Principle: 1. The size of the enlarged area on the right is equal to the size of the translucent slider on the left multiplied by the zoom factor

2. The original size of the picture in the enlarged area on the right should be the same as

Same as the picture on the left, it cannot change with the width and height on the right

3. Calculate the slider position

Upper Code: almost every line has a comment

HTML:

<!--Magnifier-->
<div class="preview">
    <div class="preview-header">
        <!--Choose a local picture-->
        <div class="choose-image">
            <lable for="fileInput">Select pictures</lable>
            <input type="file" id="fileInput">
        </div>
        <!--Adjust zoom factor-->
        <div class="scale">
            <lable for="scaleNum">Set magnification</lable>
            <input type="number" id="scaleNum" value="2">
        </div>
    </div>
    <!--Preview Area-->
    <div class="preview-content">
        <!--Original graph-->
        <div class="origin">
            <img src="" alt="" id="origin-image">
            <!--slider-->
            <div class="scale-section"></div>
        </div>
        <!--Enlarged picture-->
        <div class="target">
            <img src="" alt="" id="target-image">
        </div>
    </div>
</div>

CSS:

/*Picture magnifier*/
/*head*/
.preview-header{
    display: flex;
    padding: 10px;
}
/*Preview Area*/
.preview-content{
    display: none;
    align-items: flex-start;
}
/*Original picture*/
.preview-content .origin{
    max-width: 350px;
    margin: 30px 0px 0px 10px;
    position: relative;
    box-shadow:3px 3px 10px 0 #111111; /*Shadow a picture */
    -webkit-box-shadow: 3px 3px 10px 0 #111111;  /*Compatibility handling*/
    -moz-box-shadow: 3px 3px 10px 0 #111111;
    overflow: hidden;
}
.preview-content .origin img{
    width: 100%;
}
/*slider*/
.origin .scale-section{
    display: none; /*Initial hiding*/
    position:absolute;
    top:0;
    left:0;
    width:175px;
    height:175px;
    background:#000;
    opacity: 0.3;
    cursor:move;  /*Change the shape of the mouse*/
}

/*The width and height of the enlarged area on the right are proportional to the slider*/
.preview-content .target{
    display: none;/*Initial hiding*/
    width: 350px;
    height: 350px;
    margin: 30px 0px 0px 30px;
    position: relative;
    box-shadow:3px 3px 10px 0 #111111; /*Shadow a picture */
    -webkit-box-shadow: 3px 3px 10px 0 #111111;  /*Compatibility handling*/
    -moz-box-shadow: 3px 3px 10px 0 #111111;
    overflow: hidden;
}
/*Enlarged picture*/
.target img{
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: top left;
}

JS:

// Obtain dom
    // Original picture
const originImage = document.getElementById('origin-image'),
    // Left picture area
        origin = document.getElementsByClassName('origin')[0],
    // Enlarged picture
        targetImage = document.getElementById('target-image'),
    // Enlarge picture area
        target = document.getElementsByClassName('target')[0],
    // Entire picture area
        previewContent = document.getElementsByClassName('preview-content')[0],
    // slider
        scaleSection = document.getElementsByClassName('scale-section')[0],
    // File selection box
        fileInput = document.getElementById('fileInput'),
    // Magnification box
        scaleNum = document.getElementById('scaleNum');
// Magnification factor
let scale = scaleNum.value;
// Width and height of left picture
let originWidth,originHeight;

// Registration event
// Select file
fileInput.addEventListener('change',chooseImage,false);
// Change multiple
scaleNum.addEventListener('change',scaleChange,false);
// Move the mouse in the left area
origin.addEventListener('mousemove',(e) => {
    // Event compatibility
    const event = e || window.event;
    // Calculate the position of the slider and the enlarged picture on the right
    calculatePosition(event.clientX, event.clientY);
    scaleSection.style.display = 'block';
    target.style.display = 'block';
}, false);
// Mouse out of left picture area
origin.addEventListener('mouseleave',() => {
    scaleSection.style.display = 'none';
    target.style.display = 'none';
}, false);

// Select pictures to zoom
function chooseImage(e) {
    // Use file Reader Obtain URL
    // Don't you understand? fileReader You can refer to the local picture preview I wrote before
    if (e.target.files[0].type.indexOf('image') === -1) {
        alert('Please select a picture');
        return
    }
    const reader = new FileReader();
    reader.onload = () => {
        // promise To get the width and height after the image is loaded
        const P1 = () => {
            return new Promise((resolve, reject) => {
                originImage.onload = () => {
                    resolve(originImage);
                };
                originImage.src = reader.result;
            })
        };
        const P2 = () => {
            return new Promise((resolve, reject) => {
                targetImage.onload = () => {
                    resolve(targetImage);
                };
                targetImage.src = reader.result;
            })
        };
        // Get the size of the original image on the left,
        // Initialize the picture size of the enlarged area
        Promise.all([P1(), P2()]).then((data) => {
            originWidth = data[0].width;
            originHeight = data[0].height;
           data[1].style.width = originWidth * scale + 'px';
           data[1].style.height = originHeight * scale + 'px';
        });
        previewContent.style.display = 'flex';
    };
    reader.readAsDataURL(e.target.files[0]);
}

function calculatePosition(x,y) {
    // Set boundaries
    const minTop = 0,
        minLeft = 0,
        maxTop = origin.offsetHeight - scaleSection.offsetHeight,
        maxLeft = origin.offsetWidth - scaleSection.offsetWidth;
    // Calculate the position of the slider
    const sectionX = x - origin.offsetLeft - scaleSection.offsetWidth/2;
    const sectionY = y - origin.offsetTop - scaleSection.offsetHeight/2;
    // True position of slider
    // Used to calculate the position of the enlarged picture on the right
    let realTop = sectionY, realLeft = sectionX;
    // Left and right boundary
    if (sectionX < minLeft) {
        scaleSection.style.left = minLeft + 'px';
        realLeft = minLeft;
    } else if (sectionX >= maxLeft) {
        scaleSection.style.left = maxLeft + 'px';
        realLeft = maxLeft;
    } else {
        scaleSection.style.left = sectionX + 'px';
    }
    // Upper and lower boundaries
    if (sectionY <= minTop) {
        scaleSection.style.top = minTop + 'px';
        realTop = minTop;
    } else if (sectionY >= maxTop) {
        scaleSection.style.top = maxTop + 'px';
        realTop = maxTop;
    } else {
        scaleSection.style.top = sectionY + 'px';
    }
    // Calculate the position of the enlarged picture on the right
    // As much as the slider moves, the picture on the right moves in the opposite direction scale Multiple
    targetImage.style.top = -realTop*scale + 'px';
    targetImage.style.left = -realLeft*scale + 'px';
}
// Scale change
function scaleChange(e) {
    scale = e.target.value;
    targetImage.style.width = originWidth * scale + 'px';
    targetImage.style.height = originHeight * scale + 'px';
    target.style.width = 175 * scale + 'px';
    target.style.height = 175 * scale + 'px';
}

In the same sentence, novices write more by themselves,

Otherwise, it will be easy to read and write,

Thanks for watching!!!

Posted by hitman6003 on Sun, 24 Nov 2019 12:58:46 -0800