使用原生JS实现图片放大镜效果

更新日期: 2019-09-06阅读: 2.4k标签: 效果

前提先了解数学算法:
求遮罩层mask宽度,大图、大图显示区、小图、遮罩层
1、小图是大图等比缩放的
2、遮罩层是大图显示区缩放的
小图/大图 = 遮罩层/大图显示区
遮罩层 = 大图显示区*(小图/大图);
    ------------------------------------------------
大图活动区 = 大图-大图显示区
小图活动区 = 小图-遮罩层

遮罩层偏移量/小图活动区 = 大图偏移量/大图活动区

大图偏移量 = 大图活动区*(遮罩层偏移量/小图活动区)
大图偏移量 = (大图-大图显示区)*(遮罩层偏移量/(小图-遮罩层))


放大镜 == 100*100橘色方块 简称:方块1

左窗口 == 200*200蓝色方块 简称:方块2

右窗口 == 200*200紫色方块 简称:方块3

原图 == 400*400青色方块 简称:方块4

用一个表达式就是:方块1的left值(或top值)/方块4的left值(或top值)=(-1)*方块2的宽度/方块四的宽度。这里我们需要注意的是方块1的定位父级是方块2,方块4的定位父级是方块3。另外小图的长宽与左窗口的长宽保持一致。我们等比例地根据方块1的top值和left值去修改方块4的top值和left值,并且方块超出部分不可见,就可以实现放大镜效果。
 

分解动作:
1、布局
2、计算遮罩层宽高度
3、为small绑定移入移出事件处理
4、为small绑定鼠标移入事件处理
      4.1、计算mask的偏移量 (e.clientX-zoom.offsetLeft-zoom.clientLeft-mask.offsetWidth/2)
      4.2、规定mask的最大最小偏移量
      4.3、计算大图偏移量(参照公式)

 

注意事项:
1、鼠标移入和鼠标移动事件应该加给small
 2、offsetX/offsetY 值不准确,应该使用clientX/clientY代替

 

效果图:


 

源码:

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
		<style>
			/*整个div中只放置小显示区域即可,大显示区域隐藏,这样直接对zoom设置属性就行了*/
			
			.zoom {
				width: 200px;
				height: 200px;
				margin-left: 100px;
				margin-top: 100px;
				/*margin-top: 1000px;  测试有滚动条情况下反应*/
				position: relative;
				border: solid 1px #000;
			}
			
			.big_area {
				/*大显示区域宽高可直接改变*/
				width: 200px;
				height: 200px;
				position: absolute;
				left: -10000px;
				top: -1px;
				border: solid 1px #000;
				overflow: hidden;
			}
			
			.big_area img {
				position: absolute;
				left: 0;
				top: 0;
			}
			/*遮罩层*/
			
			.mask {
				position: absolute;
				left: -10000px;
				top: 0;
				width: 100px;
				height: 100px;
				background: #000;
				opacity: 0.65;
				filter: alpha(opacity=65);
			}
		</style>
	</head>

	<body>
		<div>
			<div>
				<img src="images/zoom.jpg" width="200" height="200" />
				<span></span>
			</div>
			<div>
				<img src="images/zoom.jpg" width="620" height="620">
			</div>
		</div>

		<script>
			// 获取相应节点元素
			var zoom = document.querySelector('.zoom');
			var simg = document.querySelector('.small_area img');
			var bimg = document.querySelector('.big_area img');
			var big = document.querySelector('.big_area');
			var small = document.querySelector('.small_area');
			var mask = document.querySelector('.mask');

			// 设置遮罩层宽高  小图宽 除以 大图宽 乘以 大显示区域边框
			mask.style.width = (simg.offsetWidth / bimg.offsetWidth) * big.clientWidth + "px";
			mask.style.height = (simg.offsetHeight / bimg.offsetHeight) * big.clientHeight + "px";

			// 定义遮罩层最大边距,也就是最大移动距离
			var maxW = simg.clientWidth - mask.offsetWidth;
			var maxH = simg.clientHeight - mask.offsetHeight;

			// 鼠标移入小显示区域发生事件:1.遮罩层显示 2.大显示区域显示
			small.onmouseenter = function() {
				mask.style.left = 0;
				big.style.left = 210 + "px";
			}
			// 鼠标移入小显示区域发生事件:1.遮罩层消失 2.大显示区域消失
			small.onmouseleave = function() {
				mask.style.left = -10000 + "px";
				big.style.left = -10000 + "px";
			}
			// 鼠标在小显示区域移动
			small.onmousemove = function(e) {
				// 解决兼容问题
				e = e || window.event;
				// 定义两个变量 让鼠标位置一直处于遮罩层位置中间
				var nLeft = e.pageX - zoom.offsetLeft - zoom.clientLeft - mask.offsetWidth / 2;
				var nTop = e.pageY - zoom.offsetTop - zoom.clientTop - mask.offsetHeight / 2;

				// 设置遮罩层永远显示在小显示区域内部 也就是判断nLeft、nTop值
				nLeft = Math.min(maxW, Math.max(0, nLeft));
				nTop = Math.min(maxH, Math.max(0, nTop));

				// 遮罩层位置
				mask.style.left = nLeft + "px";
				mask.style.top = nTop + "px";

				// 设置大图片移动位置 跟随遮罩层百分比移动(语法带入)
				bimg.style.left = -(bimg.offsetWidth - big.clientWidth) * (nLeft / (simg.clientWidth - mask.offsetWidth)) + "px";
				bimg.style.top = -(bimg.offsetHeight - big.clientHeight) * (nTop / (simg.clientHeight - mask.offsetHeight)) + "px";

			}
		</script>
	</body>
</html>


链接: https://fly63.com/article/detial/5242

使用 JavaScript 实现分屏视觉效果

今天这篇文章就来讲讲使用JavaScript来实现这种分屏的视觉UI效果。现在在网站上这种分屏视觉效果应用的也非常广泛,比如 Corsair website。

CSS3的过渡效果,使用transition实现鼠标移入/移出效果

在css中使用伪类虽然实现了样式的改变,但由于没有过渡效果会显得很生硬。以前如果要实现过渡,就需要借助第三方的js框架来实现。现在只需要使用CSS3的过渡(transition)功能,就可以从一组样式平滑的切换到另一组样式。

js如何实现新手引导效果?

js最近有个小伙伴问到了怎么实现新手引导的效果,然后便去网上找了下实现方案。可以通过css的border来实现。

css3 斜切角/斜边的实现方式

设计图含有斜切角的效果时,我们一般想到的方法是切出四个角为背景,然后用border连起来,这样就能显示出该效果了,那么直接使用css呢?下面就整理css做斜边的效果。

JavaScript 实现打字机效果,跑马灯效果

这篇文章在不使用任何插件的情况,以最简洁的原生javascript来实现打字机效果和跑马灯效果。打字效果即把一段话一个字一个字的显示出来。

CSS遮罩效果(模糊效果,阴影效果,毛玻璃效果)

一般遮罩加上透明度opacity就是阴影效果。阴影效果和一般遮罩一样,唯一不同的是设置.mask遮罩的背景色用rgba()表示,当然hsla()也是可以的。模糊效果(毛玻璃效果) 通过 filter来实现

纯css实现气泡效果

主要运用的是1.border 组成的直角三角形。2,before 和 after 伪元素 。3,z-index属性;将元素的长宽设置为0,并且将border的3条边设置为透明的,就会出现border颜色的直角三角形

css文字选中效果

文字选中效果,这个可能很少有人注意过。在默认状态先一般选中的文本颜色是白字蓝底的,不过可以通过CSS进行设置。::selection定义元素上的伪选择器,以便在选定元素时设置其中文本的样式。

text-fill-color:仿苹果官网介绍效果 CSS设置文字渐变效果 文字背景图遮罩

发布iPhone XR的时候 各种心动 去官网看了一遍又一遍。闲着无聊发现 里面的介绍很用大篇幅的有背景文字来介绍。Like this:看着挺酷炫的还不错 就看了下实现方式。还挺简单的。

Vue 中多个元素、组件的过渡,及列表过渡

多元素之间如何实现过渡动画效果呢?这么写行不行呢?肯定是不行的,因为 Vue 在两个元素进行切换的时候,会尽量复用dom,就是因为这个原因,导致现在动画效果不会出现。如果不让 Vue 复用dom的话,应该怎么做呢?只需要给这两个div不同的key值就行了

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!