2020年12月2日星期三

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 > <div ></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









原文转载:http://www.shaoqun.com/a/494639.html

心怡:https://www.ikjzd.com/w/1327

凹凸曼:https://www.ikjzd.com/w/1392

易麦:https://www.ikjzd.com/w/2048


最近看到一篇讲放大镜的文章,实践后感觉效果非常好,这里分享给大家。效果如下:其实现核心:CSS函数,如:calc()——动态计算;var()——使用自定义变量CSS伪元素:::before/after——方便控制,而且独立于文档流之外,易于渲染JSAPI:offsetX/offsetY:相对父节点区域左上角定位  其实我们具体要实现的就是:在鼠标移入时显示出来一个小圆圈(跟着鼠标走),这个小圆圈到
环球b2b:环球b2b
extra:extra
亚马逊旺季机遇与挑战并存,4大销售技巧助卖家巧妙化解难题:亚马逊旺季机遇与挑战并存,4大销售技巧助卖家巧妙化解难题
台湾国父纪念馆_台北国父纪念馆旅游景点介绍:台湾国父纪念馆_台北国父纪念馆旅游景点介绍
选品指南:11个方法教你找到高利润的利基产品:选品指南:11个方法教你找到高利润的利基产品

没有评论:

发表评论