Splide 缩放踩坑

204 阅读3分钟

今日这个话题是:如何对 Splide 使用 scale 进行缩放?

为了演示,我们首先建一个能够正常运行的 splide 案例👇

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Splide Example</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide@latest/dist/css/splide.min.css">
</head>
<body>
  <div id="container-outer">
    <div class="title">其他内容</div>
    <div class="splide" id="splide">
    <div class="splide__track">
      <ul class="splide__list">
        <li class="splide__slide"><img src="https://example.com/path/to/slide1.png" alt="Slide 1"></li>
        <li class="splide__slide"><img src="https://example.com/path/to/slide2.png" alt="Slide 2"></li>
      </ul>
    </div>
  </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@latest/dist/js/splide.min.js"></script>
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      new Splide('#splide', {
        type: 'loop',
        perPage: 1,
        autoplay: false,
      }).mount();
    });
  </script>
</body>
</html>

我们额外添加点 CSS 样式:

#splide {
  width: 500px;
}

.splide__slide img {
      width: 100%;
      height: auto;
    }

.title {
  width: 500px;
  background-color: red;
  height: 60px;
  text-align: center;
  line-height: 60px;
}

这个时候,我们得到下面的效果图👇

normal_splide.gif

我们能够对图片进行完整的滑动。

但是,如果我们需要更改容器的尺寸,将 id="container-outer" 的容器变为原来宽度的 1 / 2,即 250px 呢?

第一种方法:直接调整宽度

我们直接调整 class="title" 类容器和 id="splide" 容器的宽度大小为 250px。则可以完成我们的需求目标。

但是,缺点就是,我们需要调整 id="container-outer" 下面很多的相关的元素宽度尺寸。

第二种方法:设定 scale

我们直接在 id="container-outer" 容器上设定 scale1 / 2

#container-outer {
  transform: scale(0.5); // 等比例缩小为原来尺寸的一半
}

乍一看,还真适合我们的场景,但是我们仔细查看 splide 就发现问题了👇

scale_splide_error.gif

截图的款尺寸是一样的。

如上图,我们的 id="container-outer" 内容确实是相比较上一张缩小了一半。可是,我们点击查看下一张图像的时候,图像滚动的却只是移动了一半。

我们定位到 splide 中的 transform: translateX 的移动情况,有所出入。

移动了一半.png

那么,我们应该怎么去解决这个问题呢?

我们尝试了很多种方法,比如强制设定 splide 的宽度,添加 paddingmargin 的方法,依旧没有效果。

然后,我们到 splide 的仓库中查看是否存在这个问题,并是否有解决答案?

还真存在这么个 issue - # Any scaling on parent div causes incorrect translateX value #653。我们使用 scale 会造成上 translateX,我们上面提到的问题,是因为 Splide 使用 getBoundingClientRect 来计算。

splide_translateX.png

嗯~那么我们在缩放后,再进行宽度的复原不就可以了嘛?就是有些绕~

#container-outer > *:not(.splide) {
  transform: scale(0.5);
}

.splide {
  width: 250px !important; /* 这里的 250 = 500 / 2 */
  margin: 0 125px; /* 这里的 125 = (500 - (500 / 2)) / 2 */
}

这样,我们就能正确实现缩放后 splide 正常的轮播效果👇

scale_splide_normal.gif

当然,如果我们需要动态计算更改的尺,那么,我们就得搭配 javascript 来实现:

// 我们设定了一个 CSS 的变量名为 --scale-splide-width,并赋值 250px
document.documentElement.style.setProperty("--scale-splide-width", "250px");

接着,我们就可以在 CSS 调用了。

.splide {
  width: var(--scale-splide-width) !important; /* 调用变量 --scale-splide-width */
  margin: 0 125px;
}

实现的效果跟上图一样👆。

当然了,我们也可以利用 javascript 做进一步的计算,做更加定制化的需求。

比如,我们使用 react 开发👇

react-demo.png

图中,我们根据不同的场景 - 横屏使用和竖屏使用来进行不同的缩放计算,对 splide 进行兼容。而不是直接更改 Splide 来破坏我们封装好的带有 Splide 插件的组件。

感谢阅读🌹【完✅】