CSS3+JS完美实现放大镜模式
最近看到一篇讲放大镜的文章,实践后感觉效果非常好,这里分享给大家。
效果如下:
其实现核心:
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完美实现放大镜模式的更多相关文章
- Backbone.js的技巧和模式
Backbone.js的技巧和模式 Backbone.js的技巧和模式 本文由白牙根据Phillip Whisenhunt的<Backbone.js Tips And Patterns> ...
- js判断手机 横屏模式
js判断手机 横屏模式 方法名称:orientation 实例: if(window.orientation!=0){ var obj=document.getElementById('orienta ...
- JS设计模式——5.单体模式
JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html 单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...
- JS 文本输入框放大镜效果
JS 文本输入框放大镜效果 今天下午研究了下 "文本输入框放大镜效果" 当然KISSY官网也有这种组件 请看kissy demo 其实这种效果 对于很多童鞋来说 应该并不陌生!我今 ...
- Js完美验证15/18身份证,Js验证身份证,支持15/18位
Js完美验证15/18身份证,Js验证身份证,支持15/18位 >>>>>>>>>>>>>>>>> ...
- 原生js实现的放大镜效果
这是我用原生js写的放大镜效果,与各种各样的框架技术相比,我喜欢使用原生的js,在这里,想和大家一起谈谈原生和框架技术的理解与个人喜好. <!DOCTYPE HTML><html&g ...
- 原生JS实现图片放大镜插件
前 言 我们大家经常逛各种电商类的网站,商品的细节就需要用到放大镜,这个大家一定不陌生,今天我们就做一个图片放大镜的插件,来看看图片是如何被放大的…… 先看一下我们要是实现的最终效果是怎么样的 ...
- ext.js的mvc开发模式详解
ext.js的mvc开发模式详解和环境配置 在JS的开发过程中,大规模的JS脚本难以组织和维护,这一直是困扰前端开发人员的头等问题.Extjs为了解决这种问题,在Extjs 4.x版本中引入了MVC开 ...
- 纯css3实现的创意图片放大镜
今天要给大家分享的的一款用纯css3实现的图片放大镜特效.页面打开五个小图显示于页面.当鼠标经过图片时,当前图片以灰色背景图的形式展示.效果非常不错. 在线预览 源码下载 实现的代码: html代 ...
随机推荐
- Helm 带你飞
文章目录 目录 文章目录 在没使用 Helm之前,向 K8S部署应用,我们要依次部署 deployment. svc 等,步骤较繁琐.况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复 ...
- Webpack的学习总结(1)
入门 Webpack,看这篇就够了 入门 Webpack,看这篇就够了 写在前面的话 一个基础的webpack配置文件 什么是WebPack,为什么要使用它? WebPack和Grunt以及Gulp相 ...
- 【剑指offer】00 开撸剑指offer
此篇为刷题链接集合,我会将剑指offer中的每一题单独做一篇随笔,然后将链接加在本篇随笔中. //将用JavaScript解题 剑指offer:https://www.nowcoder.com/ta/ ...
- 前中后序递归遍历树的体会 with Python
前序:跟->左->右 中序:左->根->右 后序:左>右->根 采用递归遍历时,编译器/解释器负责将递归函数调用过程压入栈并保护现场,在不同位置处理根节点即可实现不 ...
- 5分钟教你在Linux下安装VMware
如果我们只有一台笔记本,又想要搭建一个小集群,怎么办?虚拟机帮你实现梦想,市面上较为常用的虚拟机软件有VMware.VirtualBox.Xen.KVM.hyper-v等,本文主要介绍如何在Linux ...
- Docker教程:使用Docker容器运行Nginx并实现反向代理
一.前言 我们知道,为了安全考虑,我们一般会设置反向代理,用来屏蔽应用程序真实的IP和端口号.在Linux系统上最常用的反向代理就是Nginx.本篇文章中,我们会通过Docker容器分别运行一个Ngi ...
- jq再次封装自己的ajax & js 回调函数 & js方法注释&js 全局屏蔽点击事件及a标签
1.封装成一个独立JS var commonUrl = 'http://xx.xxx.com/'; function http({ url, type = "post", data ...
- 从0开始快速入门学Java----基本篇
由于是0基础入门java,所以花了比较多的时间学习了基本语法知识,阶段性梳理下知识: 1. Java的介绍+JDK安装及环境变量配置+第一个程序HelloWorld的编写 这部分开始遇到的问题比较多, ...
- 在wildfly 21中搭建cluster集群
目录 简介 下载软件和相关组件 配置domain 创建应用程序 部署应用程序 集群配置 总结 简介 wildfly是一个非常强大的工具,我们可以轻松的使用wildfly部署应用程序,更为强大的是,wi ...
- 自动化运维工具-Ansible之3-playbook
自动化运维工具-Ansible之3-playbook 目录 自动化运维工具-Ansible之3-playbook PlayBook初识 YAML语法 PlayBook部署httpd PlayBook实 ...