zoukankan      html  css  js  c++  java
  • JS 图片放大镜

    今天练习一个小demo, 从本地读取图片,

    然后实现类似淘宝放大镜的效果,

    再加两个需求

    1 .可以调节缩放比例,默认放大两倍

    2 . 图片宽高自适应, 不固定宽高

    话不多说先看效果:

    原理:1, 右侧放大区域的大小等于左侧半透明滑块大小乘以缩放倍数

       2, 右侧放大区域图片的原始尺寸要和

          左侧图片一样,不能随右侧的宽高变化

       3, 计算滑块位置

    上代码: 基本每行都有注释

    HTML:

    <!--放大镜-->
    <div class="preview">
        <div class="preview-header">
            <!--选择本地图片-->
            <div class="choose-image">
                <lable for="fileInput">选择图片</lable>
                <input type="file" id="fileInput">
            </div>
            <!--调整缩放倍数-->
            <div class="scale">
                <lable for="scaleNum">设置放大倍数</lable>
                <input type="number" id="scaleNum" value="2">
            </div>
        </div>
        <!--预览区域-->
        <div class="preview-content">
            <!--原图-->
            <div class="origin">
                <img src="" alt="" id="origin-image">
                <!--滑块-->
                <div class="scale-section"></div>
            </div>
            <!--放大后的图片-->
            <div class="target">
                <img src="" alt="" id="target-image">
            </div>
        </div>
    </div>

    CSS:

    /*图片放大镜*/
    /*头部*/
    .preview-header{
        display: flex;
        padding: 10px;
    }
    /*预览区域*/
    .preview-content{
        display: none;
        align-items: flex-start;
    }
    /*原始图片*/
    .preview-content .origin{
        max- 350px;
        margin: 30px 0px 0px 10px;
        position: relative;
        box-shadow:3px 3px 10px 0 #111111; /*给图片施加阴影效果 */
        -webkit-box-shadow: 3px 3px 10px 0 #111111;  /*兼容性处理*/
        -moz-box-shadow: 3px 3px 10px 0 #111111;
        overflow: hidden;
    }
    .preview-content .origin img{
         100%;
    }
    /*滑块*/
    .origin .scale-section{
        display: none; /*初始隐藏*/
        position:absolute;
        top:0;
        left:0;
        175px;
        height:175px;
        background:#000;
        opacity: 0.3;
        cursor:move;  /*改变鼠标的形状*/
    }
    
    /*右侧放大区域的宽高是和滑块成比例的*/
    .preview-content .target{
        display: none;/*初始隐藏*/
         350px;
        height: 350px;
        margin: 30px 0px 0px 30px;
        position: relative;
        box-shadow:3px 3px 10px 0 #111111; /*给图片施加阴影效果 */
        -webkit-box-shadow: 3px 3px 10px 0 #111111;  /*兼容性处理*/
        -moz-box-shadow: 3px 3px 10px 0 #111111;
        overflow: hidden;
    }
    /*放大后的图片*/
    .target img{
        position: absolute;
        top: 0;
        left: 0;
        transform-origin: top left;
    }

    JS:

    // 获取dom
        // 原始图片
    const originImage = document.getElementById('origin-image'),
        // 左侧图片区域
            origin = document.getElementsByClassName('origin')[0],
        // 放大后的图片
            targetImage = document.getElementById('target-image'),
        // 放大图片区域
            target = document.getElementsByClassName('target')[0],
        // 整个图片区域
            previewContent = document.getElementsByClassName('preview-content')[0],
        // 滑块
            scaleSection = document.getElementsByClassName('scale-section')[0],
        // 文件选择框
            fileInput = document.getElementById('fileInput'),
        // 放大倍数框
            scaleNum = document.getElementById('scaleNum');
    // 放大的倍数
    let scale = scaleNum.value;
    // 左侧图片的宽高
    let originWidth,originHeight;
    
    // 注册事件
    // 选择文件
    fileInput.addEventListener('change',chooseImage,false);
    // 改变倍数
    scaleNum.addEventListener('change',scaleChange,false);
    // 鼠标在左侧区域移动移动
    origin.addEventListener('mousemove',(e) => {
        // 事件兼容
        const event = e || window.event;
        // 计算滑块以及右边放大图片的位置
        calculatePosition(event.clientX, event.clientY);
        scaleSection.style.display = 'block';
        target.style.display = 'block';
    }, false);
    // 鼠标离开左侧图片区域
    origin.addEventListener('mouseleave',() => {
        scaleSection.style.display = 'none';
        target.style.display = 'none';
    }, false);
    
    // 选择要缩放的图片
    function chooseImage(e) {
        // 使用file Reader获取URL
        // 不懂fileReader的可以参考我之前写的本地图片预览
        if (e.target.files[0].type.indexOf('image') === -1) {
            alert('请选择图片');
            return
        }
        const reader = new FileReader();
        reader.onload = () => {
            // promise是为了等图片加载完毕取宽高
            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;
                })
            };
            // 获取左侧原图的大小,
            // 初始化放大区域的图片大小
            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) {
        // 设置边界
        const minTop = 0,
            minLeft = 0,
            maxTop = origin.offsetHeight - scaleSection.offsetHeight,
            maxLeft = origin.offsetWidth - scaleSection.offsetWidth;
        // 计算滑块的位置
        const sectionX = x - origin.offsetLeft - scaleSection.offsetWidth/2;
        const sectionY = y - origin.offsetTop - scaleSection.offsetHeight/2;
        // 滑块的真实位置
        // 用于计算右侧放大图片的位置
        let realTop = sectionY, realLeft = sectionX;
        // 左右边界
        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';
        }
        // 上下边界
        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';
        }
        // 计算右侧放大图片的位置
        // 滑块移动多少, 右侧图片就向反方向移动scale的倍数
        targetImage.style.top = -realTop*scale + 'px';
        targetImage.style.left = -realLeft*scale + 'px';
    }
    // 缩放比例改变
    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';
    }

    还是那句话,新手自己多动手写写,

    不然容易一看就会,一写就懵逼,

    感谢观看!!!

  • 相关阅读:
    php+ajax文件上传
    安装ruby及sass
    大佬
    ES6--let,解构赋值,promise && ES7--async
    miniapp基础
    8月笔记
    webpack 打包html文件
    webpack压缩打包不成功
    nvm安装成功后,但命令不可用(command not found)
    jq库extend的区别
  • 原文地址:https://www.cnblogs.com/LHLVS/p/10752979.html
Copyright © 2011-2022 走看看