利用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多边形裁剪值的设置。

相关推荐
儒雅的烤地瓜1 小时前
小程序 | Vue小程序开发框架:MPvue与UniApp深度解析
前端·vue.js·uni-app·nodejs·cli·mpvue
小鸡脚来咯2 小时前
正则表达式考点
java·开发语言·前端
ujainu2 小时前
Electron 主进程与渲染进程通信详解:HarmonyOS PC基于 `ipcRenderer.send` 与 `ipcMain.on` 的双向数据传输
javascript·electron·harmonyos
Cg136269159742 小时前
JS-对象-
开发语言·javascript·ecmascript
IT_陈寒2 小时前
SpringBoot开发效率提升50%的5个隐藏技巧,官方文档都没告诉你!
前端·人工智能·后端
鹏北海2 小时前
TypeScript 装饰器完全指南
前端·typescript
zhaoyin19942 小时前
Vue面试题笔记
javascript·vue.js·笔记
533_2 小时前
[element-ui] el-tree 获取指定节点的父节点
前端·vue.js·elementui
坚持学习前端日记2 小时前
Agent AI 前端技术架构设计文档
前端·javascript·人工智能·python