这次要实现的是在一个容器内有两张通过绝对定位叠在一起的图片,通过鼠标在上层图片上的移动,完成随鼠标裁剪上层图片使下层的图片能够展示出来。
先看一下浏览器中图片初始的样子,如下图:

接下来是鼠标进入的样子,如图:

这就是随鼠标在上层图上移动裁剪,展示出下层的图片,这就是基本的效果。下面直接上代码:
首先是页面布局html文件:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<!-- 容器:包裹两张重叠的图片 -->
<div class="container">
<img alt="" src="./images/app_white1.png" srcset=""> <!-- 第一张图:作为底层背景 -->
<img alt="" src="./images/app_white2.png" srcset=""> <!-- 第二张图:通过clip-path裁剪,实现交互效果 -->
</div>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>
然后是样式文件:
ruby
.container {
width: 80%; /* 容器宽度占页面80% */
height: 800px; /* 容器高度 */
margin: 1em auto;
overflow: hidden;
border-radius: 10px;
position: relative;
}
.container img {
width: 100%;
height: 100%;
inset: 0; /* 等价于top/right/bottom/left:0,让图片完全覆盖容器 */
position: absolute; /* 两张图片绝对定位,重叠显示 */
}
.container img:nth-child(2) {
/* clip-path:裁剪图片,只显示多边形区域内的部分;polygon是多边形,参数是多个坐标点(x y) */
clip-path: polygon(
0 var(--p1y, 100%), /* 第一个点:x=0,y=--p1y变量值(默认100%) */
var(--p2x, 100%) var(--p2y, 100%), /* 第二个点:x=--p2x(默认100%),y=--p2y(默认100%) */
100% 0, /* 第三个点:x=100%,y=0 */
100% 100%, /* 第四个点:x=100%,y=100% */
0 100% /* 第五个点:x=0,y=100% */
);
}
最后是核心的js文件:
javascript
// 1. 获取容器元素
const container = document.querySelector('.container')
// 2. 获取容器内第二张图片
const img2 = container.querySelector('img:nth-child(2)')
// 3. 监听鼠标进入容器事件
// 注意:如果对于鼠标刚进入没特别设置的话这个事件可以不写也不影响效果
container.onmouseenter = () => {
// 修改img2的--p2y变量为0%(裁剪区域变化)
img2.style.setProperty('--p2y', '0%')
}
// 4. 监听鼠标离开容器事件
// 注意:如果需求是鼠标离开图片保持当前裁剪效果,onmouseleave不用写就可以实现
container.onmouseleave = () => {
// 重置--p2y为0%
img2.style.setProperty('--p2y', '0%')
// 重置--p1y为0%
img2.style.setProperty('--p1y', '0%')
// 重置--p2x为50%
img2.style.setProperty('--p2x', '50%')
}
// 5. 获取容器的位置和尺寸信息(距离视口的位置、宽高)
const containerRect = container.getBoundingClientRect()
// 6. 监听鼠标在容器内移动事件
container.onmousemove = e => {
// 计算鼠标在容器内的X轴百分比((鼠标X - 容器左边界) / 容器宽度 * 100)
const xPercent = ((e.clientX - containerRect.left) / containerRect.width) * 100
// 计算鼠标在容器内的Y轴百分比
const yPercent = ((e.clientY - containerRect.top) / containerRect.height) * 100
// 动态修改--p1y为鼠标Y百分比的2倍(放大裁剪效果)
img2.style.setProperty('--p1y', `${yPercent * 2}%`)
// 动态修改--p2x为鼠标X百分比的2倍
img2.style.setProperty('--p2x', `${xPercent * 2}%`)
}
以上就是亲自手敲的原代码,没有任何插件就是原生js实现的裁剪效果。重点是知道css中clip-path属性的polygon多边形裁剪值的设置。