好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解CSS3+JS完美实现放大镜模式

大概一年多之前写过一篇 文章 : 仿放大镜效果的几种方式原理解析 , 当时 觉得 自己技 术 可以了、飘了,于是就起了这样牛气哄哄的标题,其实也只算是介绍了css里的transform和animation两种动画方式 —— 当然,实现的效果也是巨 简单 的那种&helli p; 惭愧。

虽然后来随着技术的增长又逐渐实现了canvas方式的放大镜以及用纯JS实现了另一种[ 淘宝 式]的模型,但是仍然不尽人意:因为实现起来太复杂了,而且需依赖大部分JS逻辑,移动和显示的效果均依赖JS,通过JS计算偏移量再渲染样式。

但是CSS3自定义变量的出现让我看到了[希望之光]!

先看效果:

其实现核心:

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

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

为什么要 用O ffset API?
其实根据上面的描述,我们需要实时获取鼠标的左偏移量和上偏移量,而这两个偏移量是相对父节点的。通过左偏移量和上偏移量结合 calc() 即可计算放大镜显示内容相对父节点的显示位置。
不难找到在鼠标事件对象中,js为我们提供了如下API:

screenX/screenY :相对屏幕区域左上角定位,若发生滚动行为,则相对该区域定位 pageX/pageY :相对网页区域左上角定位 clientX/clientY :相对浏览器可视区域左上角定位 offsetX/offsetY :相对父节点区域左上角定位,若无父节点则相对 <ht ML > 或 <body> 定位

但相较而言唯一符合要求的就只有offset[相对于父元素]了。

<div class=" br uce">
    <div class=" ;m agnifier"></div>
</div>

let magnifier=document.querySelector(".magnifier");
magnifier.addEventListener("mou SEM ove",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{
    m arg in -t op: 50px;
}
.magnifier{
    --x:0;
    --y:0;
    overflow: hidden;
    pos IT ion: relative;
    width: var(--box-w);
    h ei ght: var(--box-h);
    background: url(" img /nan.png") no-re PE at  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(- -s ize);
    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.set PR operty("--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{
    mar gin -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自定义变量:我仍然认为只能在[同级同属]范围内才能修改并显示成功。

到此这篇关于详解CSS3+JS完美实现放大镜模式的文章就介绍到这了,更多相关CSS3+JS放大镜内容请搜索以前的文章或继续浏览下面的相关文章,希望大家以后多多支持!

总结

以上是 为你收集整理的 详解CSS3+JS完美实现放大镜模式 全部内容,希望文章能够帮你解决 详解CSS3+JS完美实现放大镜模式 所遇到的问题。

如果觉得 网站内容还不错, 推荐好友。

查看更多关于详解CSS3+JS完美实现放大镜模式的详细内容...

  阅读:17次