今介绍一个在商城网站经常看到的功能,图片放大镜的效果:我们试试用最少的 JavaScript,尽量使用 CSS 以及最简...

今介绍一个在商城网站经常看到的功能,图片放大镜的效果:

我们试试用最少的 JavaScript,尽量使用 CSS 以及最简单的 HTML 结构去实现,那我们就开始啦。

HTML 的部份

id 名为 image。

阿里P7大牛,图片放大镜的效果(图1)

CSS 的部份

去到 CSS 的部份,新增 image 选择器,宽度和高度设定为 300px,背景颜色设定为黑色。

将需要显示的图片,通过 background-image 设定为背景图片,由于我们要做放大镜的效果,所以这张图片的大小需要大于容器的大小,例如放大镜会将图片放大 3 倍,那图片的大小就是 900px 乘以 900px 了。

再通过 background-size,将它设定回 300px 乘以 300px 的大小,而 background-repeat 设定为 no-repeat。

阿里P7大牛,图片放大镜的效果(图2)

再加入 body 选择器,使用 Flexbox 的方式将内容上下左右置中。

阿里P7大牛,图片放大镜的效果(图3)

JavaScript 的部份

好了,那么如何做到当游标移到图片上时,将图片放大呢?这里涉及到三个 JavaScript Event。在 JavaScript 的部份,加入三个事件:

第一个,是 mouseenter,会在游标进入图片时触发,事件处理函式命名为 enterHandler。

第二个,是 mousemove,会在游标在图片上移动时触发,事件处理函式命名为 moveHandler。

第三个,是 mouseleave,会在游标离开图片时触发,事件处理函式命名为 leaveHandler。

阿里P7大牛,图片放大镜的效果(图4)

好,那么先处理游标进入图片时放大,离开图片时缩小到原来大小的效果。这个就很简单,平时我们惯用的方法是进入图片时加个 class,离开图片时就移除那个 class。但我想再纯粹一点,今次就用另一个方式试试。

在 enterHandler 函式内,加入 e.target.setAttribute,将 zoomed 设定为 1,这样就即是在

上加入 zoomed=“1” 这个属性。

在 leaveHandler 函式内,加入 e.target.removeAttribute,将 zoomed 属性移除。

阿里P7大牛,图片放大镜的效果(图5)

实现放大缩小功能

回到 CSS 的部份,加入 image【zoomed】 选择器,代表当 image 有 zoomed 这个属性的时候,将 background-size 设定为 3 倍大小,宽度与高度是 900px。

阿里P7大牛,图片放大镜的效果(图6)

一下,现在移到图片上就放大,离开图片就回到原来的大小:

阿里P7大牛,图片放大镜的效果(图7)

再来处理游标移动的情况,回到 JavaScript 的部份,在 moveHandler 函式内定义两个变量,分别是 x 和 y。我想计算出游标移到图片上的 x 方向百份比和 y 方向百份比,位移的数字可以通过 offsetX 和 offsetY 获取,再除以容器的宽度和高度就可以了。

为了准确获取容器的大小,再定义一个变量 rect,赋值为 e.target.getBoundingClientRect, x 等于 e.offsetX 除以 rect.width,y 等于 e.offsetY 除以 rect.height,再通过 e.target.style.setProperty 分别将 x 和 y 设定为 CSS 的变量,这样就可以在 CSS 中获取到 x 和 y 的值。

阿里P7大牛,图片放大镜的效果(图8)

现在可以通过者工具,看到 CSS 变量的值:

阿里P7大牛,图片放大镜的效果(图9)

阿里P7大牛,图片放大镜的效果(图10)

有了这两个数据,再加多一行 CSS,就可以完成放大镜的效果。你猜到我会怎样做吗?如果有兴趣的话,不妨自己试一试,再回来继续看。

回到 CSS 的部份,在 image【zoomed】 的选择器内加入 background-position 控制背景图片的位置:

X 的值设定为 var(--x) 乘以 100%,外层套上 calc

Y 的值设定为 var(--y) 乘以 100%,外层套上 calc

阿里P7大牛,图片放大镜的效果(图11)

一下,放大镜效果就完成了:

阿里P7大牛,图片放大镜的效果(图12)

不过,我们还要照顾一下手机版的情况,在手机上,以上的 mouse 事件都不太适用。这个时候就需要监听 touch 事件,分别是 touchstart、touchmove 和 touchend。刚好可以与 mouse 那三个事件一一对应,先新增它们的事件。

阿里P7大牛,图片放大镜的效果(图13)

主要需要调整的是 moveHandler,因为 touch 事件的 物件并没有 offsetX 和 offsetY,所以我们需要自行计算。

定义两个变量,offsetX 和 offsetY,判断 e.type 是否为 touchstart、touchmove 或 touchend。

阿里P7大牛,图片放大镜的效果(图14)

先设定 else 用游标的情况,将 offsetX 与 offsetY 赋值为 Event 物件内的对应值就可以了。

阿里P7大牛,图片放大镜的效果(图15)

而 touch 的情况,首先 touch 是支援多点触碰的,假设我们用一只手指触碰荧幕,要获取第一个触碰点,可以通过 e.touches【0】 .pageX 减去 rect.left,这个就是 offsetX 的设定值。运用相同的原理,计算 offsetY 的值。

阿里P7大牛,图片放大镜的效果(图16)

将 x 的 e.offsetX 改为变量 offsetX,y 的 e.offsetY 改为变量 offsetY,在手机操作的情况下,还要加入 e.prDefault,这样才可以避免手指在图片上滑动的时候触发页面的卷动。

阿里P7大牛,图片放大镜的效果(图17)

最后,再来一点优化,当我手指开始点下去的时候,如果不移动的话,放大的就是上一次 x 和 y 的位置,而不是我直接点下去的位置。

mouse 事件没有这个问题的,因为游标要移到图片的哪一个点都好,都一定要有移动的动作,一定会触发到 mousemove,而更正这个情况就很简单,只需要在 enterHandler 和 leaveHandler 函式内都执行一次 moveHandler 就可以了,注意要将 e 这个参数传递进去。

阿里P7大牛,图片放大镜的效果(图18)

我们来看看这个案例的完成效果

阿里P7大牛,图片放大镜的效果(图19)

阿里P7大牛,图片放大镜的效果(图20)

以上,就是今集要介绍的全部内容。

阿里P7大牛,图片放大镜的效果(图21)

本文相关词条概念解析:

图片

图是宏观指由有形式的事物、图形、图像、图画﹑照片﹑拓片等构成的平面媒体的统称。图片可以反应生活百态、真实反映具有实效性的人或事,灾难、战争、贫困等。微观指是技术制图中的基础术语,指用点、线、符号、文字和数字等描绘事物几何特征、形态、位置及大小的一种形式。随着数字采集技术和信号处理理论的发展,越来越多的图片以数字形式存储,但总体上可以分为点阵图和矢量图两大类,我们常用BMP、JPG等格式都是点阵图形,而SWF、PSD等格式的图形属于矢量图形。

网友评论