html css 实现纵享丝滑🎗️滑动查看——反差对比图

4,489 阅读2分钟

效果

先来看看效果:(如封面👆)

继上一篇左右滑动查看反差图,今天出一篇上下滑动查看两张图的效果。

当然,上一篇的input做法也可以实现上下效果,这一篇不同做法(也是第二种做法)来实现这种上下布局的效果。

准备工作

准备两张反差或变身图

Kapture 2023-03-31 at 16.34.01.gif

原理

根据鼠标事件mousedownmousemovemouseup来改变其中一张图的css clip 属性、以及滑动横条的高度。

如题,本文用html和jq写,思路搞好,无论是vue写法还是react写法,都大差不差,仅此而已。

css clip 语法

  • clip: auto | rect(number number number number)
    • auto: 默认值 (对象无裁切)
    • rect(number number number number) (上, 右,下,左) 左上角(0, 0)坐标计算的四个偏移数值,其中任一数值可用 auto 替换,即此边不剪切。

贴代码

html

<div class="container">
    <div id="root">
        // 底图 不用动高
        <img class="changed-img" src="./images/after.png" />
        
        // 需改高
        <div id="clip">
            <img class="origin-img" src="./images/before.png" />
        </div>
        
        // 滑动横条
        <div id="bar">
             <div class="bar-line">
                <div class="handle-root">
                  <div class="handle-line"></div>
                  <div class="handle-button">
                    <div></div>
                    <div></div>
                  </div>
                  <div class="handle-line"></div>
                </div>
             </div>
        </div>
        
    </div>
</div>

js

<script>
  let allow = false;
   
  // 滑动
  const move = (clientY) => {
    $("#bar").css("transform", `translate3d(0px, ${clientY - 100}px, 0px)`);
    $("#clip").css("clip", `rect(auto, auto, ${clientY - 100}px, auto)`);
    $("#root").css("cursor", `ns-resize`);
  };
  
  // 停止
  const stop = () => {
    allow = false;
    $("#root").css("cursor", "unset");
  };
  
  // 鼠标事件
  $("#root").on({
    mousedown: function(e) {
      allow = true;
      move(e.clientY);
    },
    mousemove: function(e) {
      if (allow) {
        move(e.clientY);
      }
    },
    mouseup: function(e) {
      stop();
    },
  });

  $(document).on("mouseup", () => {
    stop();
  });
</script>

css

// 最外层容器
#root {
    width: 600px;
    height: 24rem;
    position: relative;
    overflow: hidden;
    user-select: none;
    margin: 100px auto;
}

// 不用动的底图
#root .changed-img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: 100%;
    box-sizing: border-box;
    object-fit: cover;
    object-position: center center;
}

// 需要根据鼠标事件改高度的图
#root #clip {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
    will-change: clip;
    user-select: none;
    clip: rect(auto, auto, 206px, auto);
}

#root #clip .origin-img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: 100%;
    box-sizing: border-box;
    object-fit: cover;
    object-position: center center;
}

// 用css写一个滑动横条

#bar {
    position: absolute;
    top: 0px;
    width: 100%;
    height: 100%;
    pointer-events: none;
    transform: translate3d(0px, 206px, 0px);
}
#bar .bar-line {
    position: absolute;
    width: 100%;
    transform: translateY(-50%);
    pointer-events: all;
    height: 56px;
}
.bar-line .handle-root {
    display: flex;
    flex-direction: row;
    place-items: center;
    height: 100%;
    cursor: ns-resize;
    pointer-events: none;
    color: rgb(255, 255, 255);
}
.bar-line .handle-line {
    flex-grow: 1;
    height: 2px;
    width: 100%;
    background-color: currentcolor;
    pointer-events: auto;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 0px 7px;
}
.bar-line .handle-button {
    display: grid;
    grid-auto-flow: column;
    gap: 8px;
    place-content: center;
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border-style: solid;
    border-width: 2px;
    pointer-events: auto;
    backdrop-filter: blur(7px);
    box-shadow: rgba(0, 0, 0, 0.35) 0px 0px 7px;
    transform: rotate(90deg);
}
.bar-line .handle-button div {
    width: 0px;
    height: 0px;
    border-top: 8px solid transparent;
    border-right: 10px solid;
    border-bottom: 8px solid transparent;
}
.bar-line .handle-button div:nth-child(2) {
    transform: rotate(180deg);
}

结语

  • 最好的学习是贡献和输出。

本文正在参加「金石计划」