HTML放大镜的一种实现及原理讲解(js)

0.效果预览

预览.png

上下方的宽度和高度指的是图片内可移动滑块的长宽,下文以‘放大镜’来称呼该滑块。

基本功能

  • 移动放大镜来选择需要放大的区域。
  • 可以根据需求调整放大镜尺寸和倍数,默认放大镜尺寸为50px*50px,放大倍数为2倍。
  • 上下滑动鼠标滚轮来放大(缩小)放大镜尺寸。
  • 下方实时显示放大镜当前尺寸和放大倍数。

eg: 调整放大镜大小来显示一行英文


image.png

1.原理讲解

HTML部分

<body>
    <div id="parent">
        <div id="setting">
            <span id="set">Setting</span> <span>宽:</span><input type="text" id="mgfW"><span>高:</span><input type="text" id="mgfH"><span>倍数:</span><input type="text" id="times">
            <input type="button" value="确认" id="sure">
        </div>
        <div id="curPic">
            <div id="mgf"></div>
            <img src="./0.jpg" />
        </div>
        <p id="inF">当前宽度:<span id ="curW"></span> 当前高度:<span id="curH"></span> 当前倍数:<span id="curT"></span></p>
        <div id="boxEnlarge">
            <img src="./0.jpg" />
        </div>
    </div>
</body>

CSS部分

#parent{
    position: relative;
    margin: 50px auto;
}
#setting{
    position: absolute;
    width: 400px;
    top:20px;
    left: 50px;
    text-align: center;
    font-family: SimSun;
}
#inF{
    position: absolute;
    left: 50px;
    width: 400px;
    top: 440px;
    text-align: center;
    font-family: Simsun;
}
#curW, #curH, #curT{
    color: blue;
}
#set{
    font-weight: bold; 
    font-style: italic;
}
#sure{
    font-family: Simsun;
    color:red;
}
#mgfH, #mgfW, #times{
    width: 50px;
}
#curPic{
    position: absolute;
    top: 50px;
    left: 50px;
}
#curPic:hover{
    cursor: move;
}
#curPic img{
    width: 400px;
    height: 400px;
}
#mgf{
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    background-color: rgba(255, 230, 93, 0.3);
}
#boxEnlarge{
    display: none;
    position: absolute;
    top: 50px;
    left: 550px;
    overflow: hidden;
}

准备一张图片(最好是大图),默认显示区和放大区域两部分放入该图片,默认区域和内部的图片大小事先是设置好了的,放大区域和内部的图片大小之后根据放大倍数设置 。

JS部分

①控制放大区域和放大镜的显示与隐藏
var parent = document.getElementById('parent');
var curpic = document.getElementById('curPic');
var mgf = document.getElementById("mgf");
var boxEnlarge = document.getElementById("boxEnlarge");
/*鼠标移至图片范围时,显示‘放大镜’和放大区域*/
curpic.onmouseover = function(){
    var mgf = document.getElementById("mgf");
    mgf.style.display = "block";
    boxEnlarge.style.display = "block";
}
/*鼠标移出图片范围时,隐藏‘放大镜’和放大区域*/
curpic.onmouseout = function(){
    var mgf = document.getElementById("mgf");
    mgf.style.display = "none";
    boxEnlarge.style.display = "none";
}
②放大镜的倍数和尺寸设置
/*默认‘放大镜’尺寸和放大倍数*/
var times = 2;
var mgfW = 50;
var mgfH = 50;
var curT = document.getElementById('curT');
var curW = document.getElementById('curW');
var curH = document.getElementById('curH');
curT.innerText = 2+'倍';
curW.innerText = 50+'px';
curH.innerText = 50+'px;'
mgf.style.width = mgfW + 'px';
mgf.style.height = mgfH + 'px';
/*自定义‘放大镜’尺寸和放大倍数*/
var button = document.getElementById('sure');
button.onclick = function (){//点击确认按钮触发事件
    times = document.getElementById('times').value;
    mgfH = document.getElementById('mgfH').value;
    mgfW = document.getElementById('mgfW').value;
    if(mgfH > curpic.offsetHeight){
        mgfH = curpic.offsetHeight;
    }
    if(mgfW > curpic.offsetWidth){
        mgfW = curpic.offsetWidth;
    }
    mgf.style.width = mgfW + 'px';
    mgf.style.height = mgfH + 'px';
    curH.innerText = mgfH + 'px';
    curW.innerText = mgfW + 'px';
    curT.innerText = times + '倍';
}
③放大镜随鼠标移动
/*‘放大镜’随鼠标移动*/
curpic.onmousemove = function(){
    Move();
}
function Move(e){
    /*根据‘放大镜’和放大倍数设置放大区域大小*/
    boxEnlarge.style.width = mgf.offsetWidth*times + 'px';
    boxEnlarge.style.height = mgf.offsetHeight*times + 'px';
    
    /*鼠标移至‘放大镜’中心*/
    e = e || event;
    var mgfx = e.clientX - curpic.offsetLeft - parent.offsetLeft - mgf.offsetWidth/2;
    var mgfy = e.clientY - curpic.offsetTop - parent.offsetTop - mgf.offsetHeight/2;
    if(mgfx<0){
        mgfx = 0;
    }
    if(mgfx >= curpic.offsetWidth-mgf.offsetWidth){
        mgfx = curpic.offsetWidth-mgf.offsetWidth;
    }
    if(mgfy<0){
        mgfy = 0;
    }
    if(mgfy >= curpic.offsetHeight-mgf.offsetHeight){
        mgfy = curpic.offsetHeight-mgf.offsetHeight;
    }
    mgf.style.left = mgfx + 'px';
    mgf.style.top = mgfy + 'px';
    
    /*设置放大的图片尺寸并根据‘放大镜’的移动调整显示区域*/
    var pic = boxEnlarge.children[0];
    pic.style.width = curpic.offsetWidth*times + 'px';
    pic.style.height = curpic.offsetHeight*times + 'px';
    pic.style.marginLeft = ((-1)*mgf.offsetLeft*times)+'px';
    pic.style.marginTop = ((-1)*mgf.offsetTop*times)+'px';
}
④鼠标滚动放大(缩小)放大镜
//未设置兼容性
curpic.onmousewheel = function(e){
    if(e.wheelDelta>0){
        if(mgf.offsetWidth*1.5 > curpic.offsetWidth){
            mgf.style.width = curpic.offsetWidth + 'px';
            return;
        }
        if(mgf.offsetHeight*1.5 > curpic.offsetHeight){
            mgf.style.height = curpic.offsetHeight + 'px';
            return;
        }
        mgf.style.width=mgf.offsetWidth*1.5 +'px';
        mgf.style.height=mgf.offsetHeight*1.5 +'px';
    }
    if(e.wheelDelta<0){
        mgf.style.width= parseInt(mgf.offsetWidth/1.5) +'px';
        mgf.style.height=parseInt(mgf.offsetHeight/1.5) +'px';
    }
    curH.innerText = mgf.offsetHeight + 'px';
    curW.innerText = mgf.offsetWidth + 'px';
    Move();
}

2.完整代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>放大镜</title>
<style>
#parent{
    position: relative;
    margin: 50px auto;
}
#setting{
    position: absolute;
    width: 400px;
    top:20px;
    left: 50px;
    text-align: center;
    font-family: SimSun;
}
#inF{
    position: absolute;
    left: 50px;
    width: 400px;
    top: 440px;
    text-align: center;
    font-family: Simsun;
}
#curW, #curH, #curT{
    color: blue;
}
#set{
    font-weight: bold; 
    font-style: italic;
}
#sure{
    font-family: Simsun;
    color:red;
}
#mgfH, #mgfW, #times{
    width: 50px;
}
#curPic{
    position: absolute;
    top: 50px;
    left: 50px;
}
#curPic:hover{
    cursor: move;
}
#curPic img{
    width: 400px;
    height: 400px;
}
#mgf{
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    background-color: rgba(255, 230, 93, 0.3);
}
#boxEnlarge{
    display: none;
    position: absolute;
    top: 50px;
    left: 550px;
    overflow: hidden;
}
</style>
<script>
    window.onload = function(){
    var parent = document.getElementById('parent');
    var curpic = document.getElementById('curPic');
    var mgf = document.getElementById("mgf");
    var boxEnlarge = document.getElementById("boxEnlarge");
    curpic.onmouseover = function(){
        var mgf = document.getElementById("mgf");
        mgf.style.display = "block";
        boxEnlarge.style.display = "block";
    }
    curpic.onmouseout = function(){
        var mgf = document.getElementById("mgf");
        mgf.style.display = "none";
        boxEnlarge.style.display = "none";
    }
    var times = 2;
    var mgfW = 50;
    var mgfH = 50;
    var curT = document.getElementById('curT');
    var curW = document.getElementById('curW');
    var curH = document.getElementById('curH');
    curT.innerText = 2+'倍';
    curW.innerText = 50+'px';
    curH.innerText = 50+'px;'
    mgf.style.width = mgfW + 'px';
    mgf.style.height = mgfH + 'px';
    var button = document.getElementById('sure');
    button.onclick = function (){
        times = document.getElementById('times').value;
        mgfH = document.getElementById('mgfH').value;
        mgfW = document.getElementById('mgfW').value;
        if(mgfH > curpic.offsetHeight){
            mgfH = curpic.offsetHeight;
        }
        if(mgfW > curpic.offsetWidth){
            mgfW = curpic.offsetWidth;
        }
        mgf.style.width = mgfW + 'px';
        mgf.style.height = mgfH + 'px';
        curH.innerText = mgfH + 'px';
        curW.innerText = mgfW + 'px';
        curT.innerText = times + '倍';
    }
    curpic.onmousewheel = function(e){
        if(e.wheelDelta>0){
            if(mgf.offsetWidth*1.5 > curpic.offsetWidth){
                mgf.style.width = curpic.offsetWidth + 'px';
                return;
            }
            if(mgf.offsetHeight*1.5 > curpic.offsetHeight){
                mgf.style.height = curpic.offsetHeight + 'px';
                return;
            }
            mgf.style.width=mgf.offsetWidth*1.5 +'px';
            mgf.style.height=mgf.offsetHeight*1.5 +'px';
        }
        if(e.wheelDelta<0){
            mgf.style.width= parseInt(mgf.offsetWidth/1.5) +'px';
            mgf.style.height=parseInt(mgf.offsetHeight/1.5) +'px';
        }
        curH.innerText = mgf.offsetHeight + 'px';
        curW.innerText = mgf.offsetWidth + 'px';
        Move();
    }
    curpic.onmousemove = function(){
        Move();
    }
    function Move(e){
        boxEnlarge.style.width = mgf.offsetWidth*times + 'px';
        boxEnlarge.style.height = mgf.offsetHeight*times + 'px';
        e = e || event;
        var mgfx = e.clientX - curpic.offsetLeft - parent.offsetLeft - mgf.offsetWidth/2;
        var mgfy = e.clientY - curpic.offsetTop - parent.offsetTop - mgf.offsetHeight/2;
        if(mgfx<0){
            mgfx = 0;
        }
        if(mgfx >= curpic.offsetWidth-mgf.offsetWidth){
            mgfx = curpic.offsetWidth-mgf.offsetWidth;
        }
        if(mgfy<0){
            mgfy = 0;
        }
        if(mgfy >= curpic.offsetHeight-mgf.offsetHeight){
            mgfy = curpic.offsetHeight-mgf.offsetHeight;
        }
        mgf.style.left = mgfx + 'px';
        mgf.style.top = mgfy + 'px';
        var pic = boxEnlarge.children[0];
        pic.style.width = curpic.offsetWidth*times + 'px';
        pic.style.height = curpic.offsetHeight*times + 'px';
        pic.style.marginLeft = ((-1)*mgf.offsetLeft*times)+'px';
        pic.style.marginTop = ((-1)*mgf.offsetTop*times)+'px';
    }
}
</script>
</head>
<body>
    <div id="parent">
        <div id="setting">
            <span id="set">Setting</span> <span>宽:</span><input type="text" id="mgfW"><span>高:</span><input type="text" id="mgfH"><span>倍数:</span><input type="text" id="times">
            <input type="button" value="确认" id="sure">
        </div>
        <div id="curPic">
            <div id="mgf"></div>
            <img src="./0.jpg" />
        </div>
        <p id="inF">当前宽度:<span id ="curW"></span> 当前高度:<span id="curH"></span> 当前倍数:<span id="curT"></span></p>
        <div id="boxEnlarge">
            <img src="./0.jpg" />
        </div>
    </div>
</body>
</html>

如有错误,欢迎指正~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • 使用sketch最重要的一点是设计好控件的规范。 为做好设计规范需要对色彩进行编号,比如:color_a”_1,c...
    youyeath阅读 26,145评论 2 237
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,467评论 1 45
  • 从花开繁花落尽,从烈日炎炎到白雪皑皑。我经历了夏秋冬三个季节。睡觉,上课,练,做饭。我只剩这些,也发现我学了好多古...
    陌黎小妹阅读 184评论 0 0
  • 01 我和肥肥谈了三年恋爱,上个月去领证了。 我本以为领证的时候,应该是有很隆重的仪式感,但其实并没有。 我们拿着...
    漫漫Chen阅读 3,632评论 4 40
  • 看完很多人写的留日生活,感觉很感慨。 有的人大学四年,没有向父母要一分钱。有的人迷茫不想继续在日本呆下去。有的人爱...
    758塔響阅读 214评论 0 1