CSS
使用纯 CSS 利用 resize 实现强大的图片切换预览功能。类似于这样:
2021-08-19-23-41-51-152915.gif

思路

首先,要实现这样一个效果如果不要求可以拖拽,其实有非常多的办法。

  1. 将两张图片叠加在一起
  2. 改变上层图片的宽度,或者使用 mask, 改变 mask 的透明度区间变化

两种方式都简单示意一下。
假设结构如下,分别使用 background 展示两张图片:

  1. <div class="g-outer">
  2. <div class="g-inner"></div>
  3. </div>

方法一,改变上层图片的宽度的方式:

  1. .g-outer {
  2. width: 650px;
  3. height: 340px;
  4. background-image: url(image1.png);
  5. overflow: hidden;
  6. }
  7. .g-inner {
  8. height: 340px;
  9. background: url(image2.png);
  10. animation: widthchange 3s infinite alternate linear;
  11. }
  12. @keyframes widthchange {
  13. 0% {
  14. width: 650px;
  15. }
  16. 100% {
  17. width: 0px;
  18. }
  19. }

效果如下:
2021-08-19-23-41-54-626298.gif
当然,使用 mask 遮罩的方式也非常轻松的可以实现类似的效果:

  1. .g-outer {
  2. background-image: url(https://images.cnblogs.com/cnblogs_com/coco1s/881614/o_21081614180122.png);
  3. }
  4. .g-inner {
  5. background: url(https://images.cnblogs.com/cnblogs_com/coco1s/881614/o_21081614175811.png);
  6. mask: linear-gradient(90deg, #fff 0%, #fff 50%, transparent 50%, transparent 100%);
  7. mask-size: 200% 100%;
  8. animation: maskChange 2s infinite alternate linear;
  9. }
  10. @keyframes maskChange {
  11. 0% {
  12. mask-position: -100% 0;
  13. }
  14. 100% {
  15. mask-position: 0 0;
  16. }
  17. }

也可以得到同样的效果:
2021-08-19-23-41-56-470296.gif
完整代码

  1. <div class="g-outer">
  2. <div class="g-inner width-change"></div>
  3. </div>
  4. <div class="g-outer">
  5. <div class="g-inner mask-change"></div>
  6. </div>
  1. html, body {
  2. background: #fff;
  3. height: 100%;
  4. width: 100%;
  5. display: flex;
  6. flex-direction: row;
  7. }
  8. .g-outer {
  9. width: 650px;
  10. height: 340px;
  11. margin: auto;
  12. background-image: url(https://images.cnblogs.com/cnblogs_com/coco1s/881614/o_21081614180122.png);
  13. overflow: hidden;
  14. }
  15. .g-inner {
  16. height: 340px;
  17. background: url(https://images.cnblogs.com/cnblogs_com/coco1s/881614/o_21081614175811.png);
  18. }
  19. .width-change {
  20. animation: widthchange 2s infinite alternate linear;
  21. }
  22. .mask-change {
  23. mask: linear-gradient(90deg, #fff 0%, #fff 50%, transparent 50%, transparent 100%);
  24. mask-size: 200% 100%;
  25. animation: maskChange 2s infinite alternate linear;
  26. }
  27. @keyframes widthchange {
  28. 0% {
  29. width: 650px;
  30. }
  31. 100% {
  32. width: 0px;
  33. }
  34. }
  35. @keyframes maskChange {
  36. 0% {
  37. mask-position: -100% 0;
  38. }
  39. 100% {
  40. mask-position: 0 0;
  41. }
  42. }

使用 resize 实现拖拽功能

下一步则是最核心,最关键的一步,巧妙的使用 CSS resize 属性,实现拖拽控制元素的宽度。

什么是 resize ?

resize:该属性允许控制一个元素的大小
语法如下:

  1. {
  2. /* Keyword values */
  3. resize: none;
  4. resize: both;
  5. resize: horizontal;
  6. resize: vertical;
  7. resize: block;
  8. resize: inline;
  9. }

看一个最简单的 DEMO:

  1. <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aut qui labore rerum placeat similique hic consequatur tempore doloribus aliquid alias, nobis voluptates. Perferendis, voluptate placeat esse soluta deleniti id!</p>
  1. p {
  2. width: 200px;
  3. height: 200px;
  4. resize: horizontal;
  5. overflow: scroll;
  6. }

这里设置一个长宽为 200px 的 <p> 为横向可拖拽改变宽度。效果如下:
2021-08-19-23-41-56-651309.gif
简单总结一些小技巧:

  • resize 的生效,需要配合 overflow: scroll。当然,准确的说法是,overflow 不是 visible,或者可以直接作用于替换元素譬如图像、<video><iframe><textarea>
  • 可以通过 resizehorizontalverticalboth 来设置横向拖动、纵向拖动、横向纵向皆可拖动
  • 可以配合容器的 max-widthmin-widthmax-heightmin-height 限制可拖拽改变的一个范围

    将 resize 运用于图片拖拽切换

    接下来将 resize 运用于图片拖拽切换。
    首先,还是上述的代码,将 resize 作用于子元素试试:
    1. <div class="g-outer">
    2. <div class="g-inner width-change"></div>
    3. </div>
    ```css .g-outer { width: 650px; height: 340px; background-image: url(image1.png); overflow: hidden; }

.g-inner { height: 340px; background: url(image2.png); resize: horizontal; overflow: scroll; max-width: 640px; min-width: 10px; }

  1. 可以看到,`g-inner` 设置了 `resize: horizontal`,将允许被横向拖动,实际的效果如下:<br />![2021-08-19-23-41-57-233295.gif](https://cdn.nlark.com/yuque/0/2021/gif/396745/1629389562199-5b7cb31e-fa81-46fb-881f-11eb2749139e.gif#clientId=u6fb74b5e-cd68-4&from=ui&id=vmlC5&originHeight=350&originWidth=661&originalType=binary&ratio=1&size=985283&status=done&style=none&taskId=u81d5629c-698c-4f7e-bb94-54d5022a30e)<br />嗯,非常接近了,因为需要配合 `overflow: scroll`,所以出现了恼人的滚动条,非常的不美观,得想办法干掉滚动条。
  2. <a name="U1jl0"></a>
  3. ### 借助多一层嵌套及绝对定位实现隐藏滚动条
  4. 隐藏滚动条的方式有很多,这里我们介绍其中一种巧妙的方式,对结构进行一下改造,再叠加多一层 div
  5. ```html
  6. <div class="g-outer">
  7. <div class="g-inner">
  8. <div class="g-resize"></div>
  9. </div>
  10. </div>

将控制拖拽这个功能交给 g-resize,它负责改变元素的宽度,而 g-inner 改为绝对定位,当 g-resize 的宽度增大时,其父元素 g-inner 也会随之增大,最后设置 g-resizeopacity 为 0 即可隐藏滚动条。
核心代码如下:

  1. .g-outer {
  2. position: relative;
  3. width: 650px;
  4. height: 340px;
  5. background-image: url(image1.png);
  6. overflow: hidden;
  7. }
  8. .g-inner {
  9. position: absolute;
  10. top: 0;
  11. left: 0;
  12. min-width: 0;
  13. max-width: 650px;
  14. height: 340px;
  15. background-image: url(image2.png);
  16. }
  17. .g-resize {
  18. position: relative;
  19. resize: horizontal;
  20. overflow: scroll;
  21. width: 0;
  22. height: 340px;
  23. max-width: 650px;
  24. min-width: 15px;
  25. animation: opacityChange 3s infinite alternate linear;
  26. }
  27. @keyframes opacityChange {
  28. 0% {
  29. opacity: 0;
  30. }
  31. 100% {
  32. opacity: 1;
  33. }
  34. }

这里,为了方便示意,将 opacity 设置了一个渐隐渐现的动画效果,方便示意:
2021-08-19-23-41-58-082297.gif

借助伪元素,显示拖拽条

最后一步,由于完全隐藏了滚动条,用户也就不知道可以拖拽了,所以我们还需要绘制一个更为好看的拖拽条,这里延续上述的布局,给 .g-inner 再添加一个伪元素,绝对定位在元素最后即可:

  1. .g-inner:before {
  2. content: "↔";
  3. position: absolute;
  4. background: rgba(0, 0, 0, 0.5);
  5. top: 0;
  6. right: 0;
  7. height: 100%;
  8. line-height: 340px;
  9. }

最终完美达成效果:
2021-08-19-23-41-59-791317.gif