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

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

本文内容概要:

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 条评论
登录 后参与评论

相关文章

来自专栏游戏开发那些事

【python游戏编程之旅】第四篇---pygame中加载位图与常用的数学函数。

本系列博客介绍以python+pygame库进行小游戏的开发。有写的不对之处还望各位海涵。

772
来自专栏吾爱乐享

白盒测试的测试方法及基本路径测试法

1013
来自专栏前端架构

css样式重置的一些方法

在当今网页设计/开发实践中,使用CSS来为语义化的(X)HTML标记添加样式风格是重要的关键。在设计师们的梦想中都存在着这样的一个完美世界:所有的浏览器都能够理...

441
来自专栏数据小魔方

条件格式制作条形数据组图

今天跟大家分享用条件格式制作条形数据组图! ▽▼▽ 记得之前有一期跟大家分享过条件格式图表的制作方法,今天所要讲的案例,方法是一样的,只是通过多个条形图叠加及排...

3396
来自专栏女程序员的日常

ATmega8仿真——键盘扫描的学习

1.按键的使用特点   按键的应用主要是在按键闭合时改变电路的电平,但是一般情况下按键的开关都是机械弹性触点开关,即利用触点的接触和分离来实现电路的通断,所以在...

2621
来自专栏TechBox

一篇文章详解iOS之AutoResizing、AutoLayout、sizeClass来龙去脉前言三大适配技术

1916
来自专栏Coco的专栏

谈谈一些有趣的CSS题目(九)-- 巧妙的实现 CSS 斜线

1183
来自专栏自动化测试实战

《selenium2 python 自动化测试实战》(15)——调用js控制滚动条等操作

3479
来自专栏斑斓

编程实践 | Scala亮瞎Java的眼(一)

这是我在11月15日成都OpenParty分享的一个题目,确有标题党的嫌疑。Scala自然不是无所不能,Java也没有这么差劲,我只希望给Java程序员提供另外...

3175
来自专栏点滴积累

geotrellis使用(二十二)实时获取点状目标对应的栅格数据值

目录 前言 实现方法 总结 一、前言        其实这个功能之前已经实现,今天将其采用1.0版的方式进行了重构与完善,现将该内容进行总结。        其...

3525

扫描关注云+社区