利用css+js实现一个图片随鼠标滑动裁剪的功能

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

先看一下浏览器中图片初始的样子,如下图:

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

这就是随鼠标在上层图上移动裁剪,展示出下层的图片,这就是基本的效果。下面直接上代码:

首先是页面布局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多边形裁剪值的设置。

相关推荐
kyriewen115 小时前
你点的“刷新”是假刷新?前端路由的瞒天过海术
开发语言·前端·javascript·ecmascript·html5
Timer@6 小时前
LangChain 教程 04|Agent 详解:让 AI 学会“自己干活“
javascript·人工智能·langchain
阿珊和她的猫6 小时前
TypeScript中的never类型: 深入理解never类型的使用场景和特点
javascript·typescript·状态模式
skywalk81637 小时前
Kotti Next的tinyfrontend前端模仿Kotti 首页布局还是不太好看,感觉比Kotti差一点
前端
RopenYuan8 小时前
FastAPI -API Router的应用
前端·网络·python
走粥9 小时前
clsx和twMerge解决CSS类名冲突问题
前端·css
Purgatory0019 小时前
layui select重新渲染
前端·layui
weixin1997010801610 小时前
《中国供应商商品详情页前端性能优化实战》
前端·性能优化
九皇叔叔10 小时前
003-SpringSecurity-Demo 统一响应类
java·javascript·spring·springsecurity