让剁手党洞察物体细节,“放大镜”当之无愧

经常浏览淘宝、京东等一些商城网站,都会看到各种各样的页面交互效果,放大镜交互效果在商城网站中算是比较常见的。作为程序员的我们也会经常去考虑放大镜效果的实现方式,同时在平时的一些电商类平台开发中也会遇到类似的需求,于是今天给大家介绍放大镜的实现方法。

本文内容概要:

1.基本介绍

2.涉及到的主要知识

3.结构样式搭建

4.功能分析实现

5.小结

1、基本介绍

商城网站放大镜效果图:

从效果图中可以看出,无非就是操作两张内容相同,但大小不同的图片。通过控制比例来实现放大的效果。但是需要注意的是,两张照片的宽高比必须是成比例的。

原理结构图

大家可以先根据原理图给出的信息先思考一波,然后咱们接着继续。

2、涉及到的主要知识

offsetLeft: 获取当前对象与父元素的左距离

offsetTop: 获取当前对象与父元素的上距离

offsetWidth: 获取元素(含边框)的自身宽度

offsetHight: 获取元素(含边框)自身高度

scrollLeft: 获取元素的左滚距离

scrollTop: 获取元素的上滚距离

event.clientX: 元素的X坐标

event.clientY: 元素的Y坐标

onmouseover: 当鼠标指针位于元素上方时,会发生mouseover事件

onmouseout: 当鼠标指针从元素上移开时,发生mouseout事件

onmousemove: 当鼠标指针在指定的元素中移动时,就会发生mousemove事件

3、结构样式搭建

a).实现控制区.box,与显示区左右布局;

b).在控制区中,拖动块move使用position定位于box之上;

具体代码:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML5学堂 - H5course</title>
    <meta name="viewport" content="width=device-width,user-scalable=no">
    <link rel="stylesheet" href="../css/reset.css">
    <style>
        .wrap {
            width: 850px;
            height: 400px;
            margin: 100px auto;
        }
        .box, .box-cop{
            float: left;
            width: 200px;
            height: 200px;
            border: 1px solid #39f;
        }
        .box {
            position: relative;
            margin-right: 45px;
        }
        .box-cop {
            overflow: hidden;
        }
        .wrap .box-cop {
            display: none;
        }
        .box .box-mov {
            display: none;
        }
        .box-mov {
            /*move块样式*/
            position: absolute;
            left: 0;
            top: 0;
            width: 50px;
            height: 50px;
            cursor: move;
            background: #000;
            opacity: 0.5;
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="box" id="pic">
            <img src="../images/mj.png" alt="" title="">
            <div class="box-mov" id="mov"></div>
        </div>
        <div class="box-cop" id="pic-big">
            <img src="../images/mj2.png" alt="" title="">
        </div>
    </div>
<body>
</html>

显示效果:

4、功能分析与实现

实现分析

1.首先,我们需一个显示框,显示框中需要一个img元素来显示原图对象;另外还需要一个容器作为显示框,用于存放大图对象。当鼠标移动到原图上时,通过对大图进行位置控制来显示对应的部位。

2. 当鼠标移动到box上方时,move块将显示,同时在放大区中显示大图的对应位置,所以我们在这里需要使用mousemove事件监听,当我们鼠标移入box时,就需要获取当前鼠标的相对坐标位置。

document.onmousemove = function (e) {
    e.preventDefault();
    newX = e.clientX; // 获取当前鼠标X轴位置
    newY = e.clientY; // 获取当前鼠标Y轴位置
}

3.通过获取到的鼠标坐标位置,减去box左/上距视口的距离,再减去move块所展现出来的宽高的1/2,则得到获取到当前的move块位置。

var nowX = newX - pic.offsetLeft - (mov.offsetWidth / 2);
//获取移动时move块距父级左侧距离
var nowY = newY - pic.offsetTop - (mov.offsetWidth / 2);
//获取移动时move块距父级的顶部距离

4.临界值判断,当move的移动距离超出了box的范围时,需要限制其最大移动值与最小移动值。

//设置move块的X轴最大移动距离
var maxX = pic.offsetWidth - mov.offsetWidth;
//设置move块的Y轴最大移动距离
var maxY = pic.offsetHeight - mov.offsetHeight;

5.根据move块相对于box的占比与放大区相对于大图的占比进行比例计算,得到显示图片的显示位置。

bec.scrollLeft = nowX * 图片占比; // 大图横向显示位置
bec.scrollTop = nowY * 图片占比;  // 大图纵向显示位置

6.根据实际需求,当鼠标移入时,使用mouseove触发,放大区显示,移出时,使用mouseout,move块与放大区消失。

pic.onmouseout = function () {
    bec.style.display = 'none'; // 移出效果
    mov.style.display = 'none';
}

具体代码:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML5学堂 - H5course</title>
    <meta name="viewport" content="width=device-width,user-scalable=no">
    <link rel="stylesheet" href="../css/reset.css">
    <style>
        .wrap {
            width: 850px;
            height: 400px;
            margin: 100px auto;
        }
        .box, .box-cop{
            float: left;
            width: 200px;
            height: 200px;
            border: 1px solid #39f;
        }
        .box {
            position: relative;
            margin-right: 45px;
        }
        .box-cop {
            overflow: hidden;
        }
        .wrap .box-cop {
            display: none;
        }
        .box .box-mov {
            display: none;
        }
        .box-mov {
            /*move块样式*/
            position: absolute;
            left: 0;
            top: 0;
            width: 50px;
            height: 50px;
            cursor: move;
            background: #000;
            opacity: 0.5;
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="box" id="pic">
            <img src="../images/mj.png" alt="" title="">
            <div class="box-mov" id="mov"></div>
        </div>
        <div class="box-cop" id="pic-big">
            <img src="../images/mj2.png" alt="" title="">
        </div>
    </div>
    <script>
        var pic = document.getElementById('pic'),
             bec = document.getElementById('pic-big'),
            mov = document.getElementById('mov');


        var newX = 0,
            newY = 0,
            nowDisX = 0,
            nowDisY = 0;


        pic.onmouseover = function (e) {
            bec.style.display = 'block'; //移入效果
            mov.style.display = 'block';
 
            nowDisX = mov.offsetLeft; //当前move块距父级右侧距离
            nowDisY = mov.offsetTop;    //当前move块距父级顶部距离
            e.preventDefault();
            document.onmousemove = function (e) {
                e.preventDefault();
                newX = e.clientX; // 获取当前鼠标X轴位置
                newY = e.clientY; // 获取当前鼠标Y轴位置
 
                var nowX = newX - pic.offsetLeft - (mov.offsetWidth / 2);
                 //获取移动时move块距父级左侧距离
                var nowY = newY - pic.offsetTop - (mov.offsetWidth / 2);
                //获取移动时move块距父级顶部距离
                var maxX = pic.offsetWidth - mov.offsetWidth;
                //设置move块的X轴最大移动距离
                var maxY = pic.offsetHeight - mov.offsetHeight;
                //设置move块的Y轴最大移动距离


                if (nowX <= 0) {
                    nowX = 0; //X轴最小值判断
                };
                if (nowX >= maxX) {
                    nowX = maxX;//X轴最大值判断
                };
                if (nowY <= 0) {
                    nowY = 0; //Y轴最小值判断
                };
                if (nowY >= maxY) {
                    nowY = maxY;//Y轴最大值判断
                };


                bec.scrollLeft = nowX * 4; // 大图横向显示显示位置
                bec.scrollTop = nowY * 4;    // 大图纵向显示位置
                mov.style.left = nowX + 'px'; //当前的move块X轴位置
                mov.style.top = nowY + 'px'; //当前的move块Y轴位置
            }
        }
        pic.onmouseout = function () {
            bec.style.display = 'none'; // 移出效果
            mov.style.display = 'none';
        }
    </script>
</body>
</html>

实现效果:

5、小结:

因为在日常项目开发中,对拖拽功能的需求还是比较常见的,这几期从自定义滚动条到放大镜的效果都是基于拖拽原理上实现的,小匠在后面的分享中会继续为大家带来更加实用与有趣的功能效果,希望能够为大家在实际开发中带来一点帮助。

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-12-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端知识分享

第140天:前端开发中浏览器兼容性问题总结(一)

我们在开发的时候会明确项目要兼容哪些浏览器的最低版本,我之前的项目要求兼容IE8.0以上的版本,Chrome 48以上,FireFox 44以上。有了这些最基本...

1023
来自专栏菩提树下的杨过

温故而知新:HttpApplication,HttpModule,HttpContext及Asp.Net页生命周期

IIS在接到一个新的http请求后,最终会调用asp.net_isapi.dll的ISAPI扩展(特指IIS6.0环境,iis7.0的应用程序池默认为集成方式,...

1735
来自专栏進无尽的文章

UI篇-自定义控件之基类UIControl

UIControl的主要角色是定义一套接口和基础实现,为iOS的人机交互制定了一系列的标准, 为了当确定的事件发生的时候(比如点击了按钮)准备好动作消息(Ac...

832
来自专栏PhpZendo

使用 Laravel 5.5+ 更好的来实现 404 响应

Laravel 5.5.10 封装了两个有用的路由器方法,可以帮助我们为用户提供更好的 404 页面。现在,当抛出 404 异常时,Laravel 会显示一个漂...

712
来自专栏GreenLeaves

JavaScript之充实文档的内容

1、我们在平时的开发中会碰到一些缩略语如:XML,HTML,API等专业术语;为了能使用户,更好的了解术语的意思,我们通常会给<abbr></abbr>标签加一...

1866
来自专栏我和未来有约会

Silverlight 3.0 中的 WriteableBitmap

Silverlight 3.0 中的 WriteableBitmap 尽管矢量图形非常的强大但是在有些情况下还是需要用到位图,因为他们在运行时能得到更高的执行效...

1858
来自专栏前端开发

[记]使用jQuery Jcrop 图像裁剪无法更换图片的坑

1333
来自专栏一个爱瞎折腾的程序猿

HTML5学习笔记

参考资料:http://www.runoob.com/html/html-tutorial.html

722
来自专栏web开发

移动端图片放大滑动查看-插件photoswipe的使用

最近在开发项目的时候,遇到一个需求,需要移动端实现放大查看图片的功能,然后我就在网上搜索了一下资料,看到了photoswipe这个插件,后来试了试,确实挺好用的...

2815
来自专栏河湾欢儿的专栏

(第一版)知识点

752

扫码关注云+社区