最近看到一篇讲放大镜的文章,实践后感觉效果非常好,这里分享给大家。

效果如下:

其实现核心:

CSS函数,如:calc() —— 动态计算;var() —— 使用自定义变量
CSS伪元素:::before/after —— 方便控制,而且独立于文档流之外,易于渲染
JS API:offsetX/offsetY:相对父节点区域左上角定位

  

其实我们具体要实现的就是:在鼠标移入时显示出来一个小圆圈(跟着鼠标走),这个小圆圈到哪,哪里的图片区域就放大相应的倍数并且显示在圆圈内。

为什么要用offset API?
其实根据上面的描述,我们需要实时获取鼠标的左偏移量和上偏移量,而这两个偏移量是相对父节点的。通过左偏移量和上偏移量结合calc()即可计算放大镜显示内容相对父节点的显示位置。
不难找到在鼠标事件对象中,js为我们提供了如下API: screenX/screenY:相对屏幕区域左上角定位,若发生滚动行为,则相对该区域定位
pageX/pageY:相对网页区域左上角定位
clientX/clientY:相对浏览器可视区域左上角定位
offsetX/offsetY:相对父节点区域左上角定位,若无父节点则相对<html>或<body>定位
但相较而言唯一符合要求的就只有offset“相对于父元素”了。

代码如下:

<div class="bruce">
<div class="magnifier"></div>
</div>
let magnifier=document.querySelector(".magnifier");
magnifier.addEventListener("mousemove",e=>{
//控制“镜子”小圆圈的移动
});

放大镜显示内容其实就是将原图像放大N倍,通过上述偏移量按照比例截取一定区域显示内容。

先定义相关的css变量。我们设定放大倍率为2.5倍,那么被放大图像的宽高也是原来宽高的2.5倍。声明两个变量,分为为 --x 和 --y :

:root{
--ratio: 2.5;
--box-w: 600px;
--box-h: 400px;
--outbox-w: calc(var(--box-w) * var(--ratio));
--outbox-h: calc(var(--box-h) * var(--ratio));
}
.bruce{
margin-top: 50px;
}
.magnifier{
--x:0;
--y:0;
overflow: hidden;
position: relative;
width: var(--box-w);
height: var(--box-h);
background: url("img/nan.png") no-repeat center/100% 100%;
cursor: grabbing;
}

图片以背景图的形式展示,方便控制大小。

很显然在这个场景下无需插入子节点作为放大镜的容器了,使用::before即可!

放大镜在使用时宽高为100px,不使用时宽高为0。通过绝对定位布局放大镜随鼠标移动的位置,即声明left和top,再通过声明 transform:translate(-50%,-50%) 将放大镜补位,使放大镜中心与鼠标光标位置一致。由于声明left和top定位放大镜的位置,还可以声明 will-change 改善left和top因改变而引发的性能问题!
而且用CSS解决这些问题的另一个好处就是:借助于伪元素/伪类,我们可以将一些比较细节的东西用CSS解决,而不是寄托于“繁重”的JavaScript。比如:鼠标移入样式hover:

.magnifier::before{
--size: 0;
position: absolute;
left: var(--x);
top: var(--y);
border-radius: 100%;
width: var(--size);
height: var(--size);
box-shadow: 1px 1px 3px rgba(0,0,0,.5);
content: "";
will-change: left,top;
transform: translate(-50%,-50%);
}
.magnifier:hover::before{
--size: 100px;
}

接下来使用background实现(展示)放大镜内容。依据放大倍率为2.5倍,那么可声明size: --outbox-w --outbox-h,通过 position-x 和 position-y 移动背景即可,最终可连写成 background:#333 url(背景图片) no-repeat var(--scale-x) var(--scale-y)/var(--outbox-w) var(--outbox-h) 。
其中 --scale-x 和 --scale-y 对应 position-x 和 position-y (即background-position),用于随着鼠标移动而改变背景位置。

--scale-x: calc(var(--size) / var(--ratio) - var(--ratio) * var(--x));
--scale-y: calc(var(--size) / var(--ratio) - var(--ratio) * var(--y));

那么上面mousemove函数中改变镜子的“位置坐标”就可以这么写了:

e.target.style.setProperty("--x",`${e.offsetX}px`);
e.target.style.setProperty("--y",`${e.offsetY}px`);

so eazy~

最终的CSS内容如下:

:root{
--ratio: 2.5;
--box-w: 600px;
--box-h: 400px;
--outbox-w: calc(var(--box-w) * var(--ratio));
--outbox-h: calc(var(--box-h) * var(--ratio));
}
.bruce{
margin-top: 50px;
}
.magnifier{
--x:0;
--y:0;
overflow: hidden;
position: relative;
width: var(--box-w);
height: var(--box-h);
background: url("img/nan.png") no-repeat center/100% 100%;
cursor: grabbing;
}
.magnifier::before{
--size: 0;
--scale-x: calc(var(--size) / var(--ratio) - var(--ratio) * var(--x));
--scale-y: calc(var(--size) / var(--ratio) - var(--ratio) * var(--y));
position: absolute;
left: var(--x);
top: var(--y);
border-radius: 100%;
width: var(--size);
height: var(--size);
background: #333 url("img/nan.png") no-repeat var(--scale-x) var(--scale-y)/var(--outbox-w) var(--outbox-h);
box-shadow: 1px 1px 3px rgba(0,0,0,.5);
content: "";
will-change: left,top;
transform: translate(-50%,-50%);
}
.magnifier:hover::before{
--size: 100px;
}

若是::before中想要用一张本身就是2倍大小的图片,则background中将--outbox-w--outbox-h替换为原本的--box-w--box-h 再做适当的微调即可。


注意看你放大镜中的内容,它表明不只是简单的图片的放大,所以才有了 var(--size) / var(--ratio) 这一段代码;
关于css中修改css3自定义变量:我仍然认为只能在“同级同属”范围内才能修改并显示成功。

转载于:https://blog.csdn.net/qq_43624878/article/details/110197749

CSS3+JS完美实现放大镜模式的更多相关文章

  1. Backbone.js的技巧和模式

    Backbone.js的技巧和模式 Backbone.js的技巧和模式   本文由白牙根据Phillip Whisenhunt的<Backbone.js Tips And Patterns> ...

  2. js判断手机 横屏模式

    js判断手机 横屏模式 方法名称:orientation 实例: if(window.orientation!=0){ var obj=document.getElementById('orienta ...

  3. JS设计模式——5.单体模式

    JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html   单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...

  4. JS 文本输入框放大镜效果

    JS 文本输入框放大镜效果 今天下午研究了下 "文本输入框放大镜效果" 当然KISSY官网也有这种组件 请看kissy demo 其实这种效果 对于很多童鞋来说 应该并不陌生!我今 ...

  5. Js完美验证15/18身份证,Js验证身份证,支持15/18位

    Js完美验证15/18身份证,Js验证身份证,支持15/18位 >>>>>>>>>>>>>>>>> ...

  6. 原生js实现的放大镜效果

    这是我用原生js写的放大镜效果,与各种各样的框架技术相比,我喜欢使用原生的js,在这里,想和大家一起谈谈原生和框架技术的理解与个人喜好. <!DOCTYPE HTML><html&g ...

  7. 原生JS实现图片放大镜插件

      前  言 我们大家经常逛各种电商类的网站,商品的细节就需要用到放大镜,这个大家一定不陌生,今天我们就做一个图片放大镜的插件,来看看图片是如何被放大的…… 先看一下我们要是实现的最终效果是怎么样的  ...

  8. ext.js的mvc开发模式详解

    ext.js的mvc开发模式详解和环境配置 在JS的开发过程中,大规模的JS脚本难以组织和维护,这一直是困扰前端开发人员的头等问题.Extjs为了解决这种问题,在Extjs 4.x版本中引入了MVC开 ...

  9. 纯css3实现的创意图片放大镜

    今天要给大家分享的的一款用纯css3实现的图片放大镜特效.页面打开五个小图显示于页面.当鼠标经过图片时,当前图片以灰色背景图的形式展示.效果非常不错. 在线预览   源码下载 实现的代码: html代 ...

随机推荐

  1. 【漏洞复现】Struts2-045分析(CVE-2017-5638)

    如果需要大佬写好的脚本,可以直接去github上面搜 struts2 - 045 一个还比较出名的漏洞,因为涉及到利用Gopher协议反弹shell,所以写篇文章来简单学习下这个漏洞. Struts2 ...

  2. PHP连接数据库的方式

    1,旧的方式 - mysql(面向过程) 1 <?php 2 //定义连接参数 3 $host = 'localhost'; 4 $user = 'root'; 5 $password = '' ...

  3. Centos7 根目录存储空间扩展方法

    Centos7 根目录存储空间扩展方法   一.首先通过 df -hl 命令查看磁盘占用情况,其中根目录已经被占满,此时需要对其进行扩容   二.针对虚拟机环境的centos7系统根存储空间扩容,可利 ...

  4. PDO实用

    $sql="select * from test4 "; $b = $pdo->query($sql); // 返回的是个新对象 $c =$b->fetchAll(); ...

  5. 80%的学校还在给新生上C语言,它们OUT了吗?

    大家好,最近有小伙伴在后台问我,大一新生学校在教C语言,是不是已经过时了?第一门语言应该学什么比较好?大学期间什么课程对于毕业之后的从业帮助比较大呢? 今天这篇文章就和大家简单聊聊这个问题. 关于我 ...

  6. 高效扩展工具让 VS Code 如虎添翼

    Codelf 变量命名神器 Star:10688 https://github.com/unbug/codelf 新建项目,变量,类,方法,接口都需要命名,一个好的命名可以一眼看出这个地方的功能,Co ...

  7. CentOS 7 最小化安装及优化

    CentOS 7 最小化安装及优化 目录 CentOS 7 最小化安装及优化 一.下载镜像文件 官方网站 国内镜像源 一.VMware 配置虚拟网络 二.VMware 新建虚拟机 三.CentOS 7 ...

  8. 24位PCM采样数据转成16位算法,已实现PCM转WAV在线工具源码支持24bits、16bits、8bits

    目录 算法来源 js版24位PCM转8位.16位代码 js版8位.16位PCM转成24位 附:浏览器控制台下载数据文件代码 相关实现 最近收到几个24位的PCM录音源文件,Recoder库原有的PCM ...

  9. .Net Core — 依赖注入

    在.NET Core 中 依赖注入Dependency-Injection)作为基础知识,在.Net Core中无处不在:这么重要的知识接下来就了解和在.Net Core中使用. 一.依赖注入 说到依 ...

  10. Choreographer全解析

    前言 今天继续屏幕刷新机制的知识讲解,上文说到vsync的处理,每一帧UI的绘制前期处理都在Choreographer中实现,那么今天就来看看这个神奇的舞蹈编舞师是怎么将UI变化反应到屏幕上的. 代码 ...