实现前端中隔线滑动对比预览效果

废话不多说,直接上效果图:

源码:中隔线滑动案例

你可以先别往下看,自己想想怎么实现~~ 本文的实现只是作者的方式,你当然可以使用自己的方式。

实现思路

  • 将输入内容做成中隔线的样子,拖动后触发数值变化
  • 根据数值变化,设置横向百分比的遮罩

定义中隔线

html 复制代码
<div class="compare">
  <!-- range 元素默认 0 - 100 -->
  <input type="range" id="range">
</div>

然后我们给输入框添加事件:

js 复制代码
// html 中标记有 id 的元素,可以在 js 里直接使用同名 dom
range.oninput = () => {
  document.body.style.setProperty('--pos', range.value + '%');
}

这样我们就能通过用户的拖拽往 css 里写入变量了。但是还有个问题,这个 range 他不是中隔线的样子,需要定义 css 样式:

css 复制代码
input[type="range"] {
  z-index: 1;  // 为了置顶
  appearance: none;
  background: transparent;
  cursor: pointer;
}

其中 appearance:none 是为了不显示拖动条,不设置的话就这样:

这样设置完后,效果如下:

为什么是个红点呢?因为我的电脑主题色是红色的,如果你是火狐,或者windows,就是一个白色的圆点,这个就是原生的 input 拖拽 bar 的颜色。我们需要把这个点变成一条线:

css 复制代码
input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  width: 4px;
  height: 390px;
  background-color: hotpink;
}

-webkit-slider-thumb 是 webkit 内核浏览器特有的样式,对于 firefox 需要另外写兼容:

css 复制代码
input[type="range"]::-moz-range-thumb {
  appearance: none;
  width: 4px;
  height: 390px;
  background-color: hotpink;
}

这样他就变成了一条自定义颜色的中隔线。

定义遮罩

我们先把两张图片放置一下:

html 复制代码
<div class="compare">
  <section class="before">
    <img src="https://images.unsplash.com/photo-1454496522488-7a8e488e8606?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=2952&amp;q=80" />
  </section>
  <section class="after">
    <img src="https://images.unsplash.com/photo-1611605645802-c21be743c321?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2940&q=80" />
  </section>
  <!-- range 元素默认 0 - 100 -->
  <input type="range" id="range">
</div>

现在长这样:

我们现在加上遮罩属性:

css 复制代码
.before {
  mask: linear-gradient(to right, #000 0, var(--pos, 50%), #0000 0);
}

.after {
  mask: linear-gradient(to right, #0000 0, var(--pos, 50%), #000 0);
}

mask 实战可以参考 使用 mask 实现视频弹幕人物遮罩过滤

本案例中,mask 属性接受一个线性渐变,配置为从左到右,#000 0 表示在 0% 处是黑色的,#0000 0 表示在 0% 处是黑色的,但是是透明的。var(--pos, 50%) 表示读取 css 变量,如果读取不到,默认是 50%,他是一个渐变停止点。

举个例子,比如 .before { mask: linear-gradient(to right, #000 0, 20%, #0000 0) } 表示前 20% 的区域有内容:

图片与 mask 生成的渐变的 transparent 的重叠部分,将会变得透明;而与 mask 渐变有颜色(这里是黑色)的地方交集就会原样显示

现在的效果图长这样:

我们还需要把他们叠在一起布局。

mask 兼容性:

设置网格布局

添加样式:

css 复制代码
.compare {
  display: grid;
}

.compare > * {
  grid-area: 1 / 1;
}

可以看到他们重叠在一起了:

解释一下 grid-area,它用于指定网格项目在网格容器中的位置和跨度。这个属性是 grid-row-start、grid-column-start、grid-row-end 和 grid-column-end 的简写形式,因此它可以同时设置项目的起始行、起始列、结束行和结束列。

例如,如果要将一个项目放置在网格容器的第一行第一列,并跨越两行两列,可以这样写:

css 复制代码
.item {  
  grid-area: 1 / 1 / 3 / 3;  
}

本文的案例中,就是强制所有元素都在第一行第一列,因为就没有分行分列。


至此,核心实现就完成啦~

源码:中隔线滑动案例

相关推荐
Justinc.26 分钟前
CSS3新增边框属性(五)
前端·css·css3
fruge33 分钟前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
As977_1 小时前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu10830189111 小时前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
我要洋人死4 小时前
导航栏及下拉菜单的实现
前端·css·css3
小白白一枚11115 小时前
css实现div被图片撑开
前端·css
@蒙面大虾15 小时前
CSS综合练习——懒羊羊网页设计
前端·css
顾菁寒16 小时前
WEB第二次作业
前端·css·html
前端Hardy20 小时前
HTML&CSS:爱上班的猫咪
前端·javascript·css·vue.js·html
聚宝盆_1 天前
【css flex 多行均分有间隙布局】
前端·css