• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

如何使用 GSAP 构建可拖动的图片库和自定义灯箱

之前的教程中,我们学习了如何使用slick.js构建响应式图片库。今天,让我们构建一个类似但更完整的东西:一个带有可拖动特色图像/主幻灯片的响应式图片库和一个位于其顶部的响应式灯箱库。为了使目标元素可拖动,我们将利用 GSAP 的Draggable插件。

听起来像是一个很好的运动? 

我们正在建造什么

这是我们要创建的组件:

See the Pen  How to Build a Draggable Image Gallery (+ Custom Lightbox) With GSAP by Envato Tuts+ (@tutsplus)  on CodePen.

请务必通过单击“打开灯箱” 按钮打开灯箱库。

1.包括所需的插件

如前所述,为了使特色图像成为可拖动元素,我们将使用GSAP,特别是它的 Draggable 插件。

您可以通过使用另一个插件甚至使用纯 javascript 事件来实现此功能

可选地,我们还将包括InertiaPlugin(以前称为 ThrowPropsPlugin),这是第二个 GSAP 插件,将在释放鼠标/触摸后应用基于动量的移动。值得注意的是,这是一个高级插件,您必须先注册成为 GSAP 会员才能决定使用它。在我们的例子中,我们将使用一个只能在本地和像codepen.io这样的域上运行的试用版(有关更多详细信息,请参阅演示的浏览器控制台)。

考虑到所有这些,我们将包含三个外部 JavaScript 文件。前两个是强制性的,而第三个是可选的。

如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第1张

2.定义 html 标记

为图库设置标记

我们将首先定义一个包装元素,该元素将包含:

  • 缩略图和特色图像列表。两个列表都将包含相同的Unsplash图像。这些将具有相同的尺寸并且足够大以实现可拖动效果。

  • 打开灯箱库的按钮。

默认情况下,将显示第一张主幻灯片。但是我们可以通过将is-active类附加到所需的幻灯片(列表)来配置该行为。

此外,所有精选图片都将保留其原始尺寸(1920 像素 x 1280 像素)。

这是我们画廊所需的结构:

<div class="gallery-wrapper">

  <ul class="thumb-list">

    <li class="is-active">

      <img width="1920" height="1280" src="sports-car1.jpg" alt="">

    </li>

    <li>

      <img width="1920" height="1280" src="sports-car2.jpg" alt="">

    </li>

    <li>

      <img width="1920" height="1280" src="sports-car3.jpg" alt="">

    </li>

    <li>

      <img width="1920" height="1280" src="sports-car4.jpg" alt="">

    </li>

  </ul>

  <ul class="featured-list">

    <li class="is-active">

      <div class="featured-img" style="background-image: url(sports-car1.jpg); width: 1920px; height: 1280px;"></div>

    </li>

    <li>

      <div class="featured-img" style="background-image: url(sports-car2.jpg); width: 1920px; height: 1280px;"></div>

    </li>

    <li>

      <div class="featured-img" style="background-image: url(sports-car3.jpg); width: 1920px; height: 1280px;"></div>

    </li>

    <li>

      <div class="featured-img" style="background-image: url(sports-car4.jpg); width: 1920px; height: 1280px;"></div>

    </li>

  </ul>

  <button type="button" class="open-lightbox">Open Lightbox</button>

</div>

为灯箱库设置标记

接下来,我们将定义一个灯箱组件,其中包括:

  • 包含上述 Unsplash 图像的列表。根据活动的主幻灯片,将出现相关的灯箱图像。

  • 用于在幻灯片之间切换的导航箭头。

  • 关闭按钮

这是我们的灯箱所需的结构:

<div class="lightbox">

  <header class="lightbox-header">

    <button type="button" class="close-lightbox" aria-label="Close lightbox">✕</button>

  </header>

  <div class="lightbox-dialog">

    <section class="lightbox-content">

      <ul class="lightbox-items">

        <li>

          <img src="sports-car1.jpg" alt="" width="1920" height="1280">

        </li>

        <li>

          <img src="sports-car2.jpg" alt="" width="1920" height="1280">

        </li>

        <li>

          <img src="sports-car3.jpg" alt="" width="1920" height="1280">

 

        </li>

        <li>

          <img src="sports-car4.jpg" alt="" width="1920" height="1280">

        </li>

      </ul>

      <button type="button" class="lightbox-control lightbox-control-next" aria-label="Next slide">

        <svg aria-hidden="true" xmlns="https://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 24 24">

          <path d="M5 3l3.057-3 11.943 12-11.943 12-3.057-3 9-9z" />

        </svg>

      </button>

      <button type="button" class="lightbox-control lightbox-control-prev" aria-label="Previous slide">

        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 24 24">

          <path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z" />

        </svg>

      </button>

    </section>

  </div>

</div>

3.指定主要样式

准备好标记后,我们将继续使用页面的主要样式。为简单起见,我将跳过介绍性/重置那些。另外,我不会优化或合并常见的 css 样式,因此您会更容易理解发生了什么。请务必通过单击演示的CSS选项卡来查看所有这些。

设置画廊布局 

图库的最大宽度为 950 像素。

在大屏幕 (>750px) 上,我们将有两列。缩略图将出现在左侧,而特色图像将出现在右侧,如下所示:

如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第2张

请注意,缩略图将覆盖画廊宽度的四分之一,而特色图像将覆盖四分之三。

在小屏幕(≤750px)上,缩略图将位于特色图像下方,如下所示:

如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第3张

请注意,每个缩略图将覆盖父级宽度的四分之一。

以下是相关的样式:

.gallery-wrapper {

  max-width: 950px;

  padding: 0 15px;

  margin: 0 auto;

  display: grid;

  grid-template-columns: 1fr 3fr;

  grid-gap: 15px;

}

 

.gallery-wrapper .thumb-list {

  display: grid;

  grid-gap: 15px;

}

 

@media (max-width: 750px) {

  .gallery-wrapper {

    grid-template-columns: 1fr;

  }

 

  .gallery-wrapper .thumb-list {

    grid-template-columns: repeat(4, 1fr);

    order: 1;

  }

}

精选幻灯片的可见性

默认情况下,除了活动幻灯片之外,所有精选幻灯片都将被隐藏。此外,一次只会出现一张特色幻灯片(活动的)。

以下是相关的样式:

.gallery-wrapper .featured-list li {

  opacity: 0;

  transition: opacity 0.25s;

}

.gallery-wrapper .featured-list li.is-active {

  opacity: 1;

}

定位特色图片

在大屏幕上,两个图库列将具有与网格项相同的高度。特色图像将是绝对定位的元素并在其容器中居中。要查看它们的所有部分,我们必须拖动它们。

在小屏幕上,由于列是堆叠的,特色图像仍然是绝对定位的,我们应该为右列指定一个固定的高度。

以下是相关的样式:

.gallery-wrapper .featured-list {

  position: relative;

  overflow: hidden;

}

 

.gallery-wrapper .featured-list .featured-img {

  background-size: cover;

  background-repeat: no-repeat;

  background-position: center;

  z-index: 1 !important;

  position: absolute;

  top: 50%;

  left: 50%;

  transform: translate(-50%, -50%);

}

 

@media (max-width: 750px) {

  .gallery-wrapper .featured-list {

    height: 340px;

  }

}

指示活动和悬停状态

每次我们将鼠标悬停在缩略图上时,它的::before伪元素都会出现。这将具有浅蓝色背景并位于缩略图的顶部。

另一方面,活动缩略图将收到红色边框颜色。

如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第4张

以下是相关的样式:

/*CUSTOM VARIABLES HERE*/

 

.gallery-wrapper .thumb-list li {

  position: relative;

  cursor: pointer;

  border: 4px solid var(--black);

}

 

.gallery-wrapper .thumb-list li:not(.is-active):hover::before {

  content: "";

  position: absolute;

  top: 0;

  left: 0;

  right: 0;

  bottom: 0;

  background: var(--hovered-thumb);

}

 

.gallery-wrapper .thumb-list li.is-active {

  border-color: var(--red);

}

设置灯箱样式 

默认情况下,灯箱将被隐藏,仅当有人单击相应的号召性用语按钮时才会出现。 


如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第5张

以下是有关灯箱样式的一些注意事项:

  • 灯箱将是具有水平居中内容的固定位置元素。

  • 导航和关闭按钮将是绝对定位的元素。

  • 画廊将垂直居中,一次只会出现一张图片。这将取决于活动的特色幻灯片。

  • 图像的最大高度将等于视口高度,并且它们的宽度将设置为auto. 

如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第6张

以下是这些样式的一部分:

/*CUSTOM VARIABLES HERE*/

 

.lightbox {

  position: fixed;

  top: 0;

  left: 0;

  right: 0;

  bottom: 0;

  display: flex;

  justify-content: center;

  opacity: 0;

  visibility: hidden;

  z-index: 2;

  transition: all 0.25s;

  background: var(--black);

}

 

.lightbox.is-visible {

  opacity: 1;

  visibility: visible;

}

 

.lightbox-header {

  position: absolute;

  top: 0;

  left: 0;

  right: 0;

  display: flex;

  justify-content: flex-end;

  padding: 5px 10px;

  z-index: 2;

  background: var(--lightbox-header);

}

 

.lightbox-dialog {

  display: flex;

  align-items: center;

}

 

.lightbox-items {

  display: grid;

}

 

.lightbox-items li {

  display: flex;

  grid-column: 1;

  grid-row: 1;

  opacity: 0;

  transition: opacity 0.25s;

}

 

.lightbox-items li.is-active {

  opacity: 1;

}

 

.lightbox-items img {

  width: auto;

  max-height: 100vh;

}

4.添加javaScript

现在让我们为我们的组件赋予生命!

同样,为简单起见,我不会优化/合并 JavaScript 代码。随意获取适用于您的项目的代码部分。

更改图库幻灯片

每次单击缩略图时,我们都会执行以下操作:

  • is-active从预先存在的活动缩略图和特色图像中删除类。

  • 查找当前活动缩略图的索引。

  • 将is-active类分配给活动缩略图和索引与此缩略图的索引匹配的特色图像。 

如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第7张

这是所需的代码:

const galleryWrapper = document.queryselector(".gallery-wrapper");

const thumbList = galleryWrapper.querySelector(".thumb-list");

const thumbItems = thumbList.querySelectorAll("li");

const featuredList = galleryWrapper.querySelector(".featured-list");

const isActiveClass = "is-active";

 

thumbItems.forEach((el) => {

  el.addeventListener("click", () => {

    thumbList.querySelector("li.is-active").classList.remove(isActiveClass);

    featuredList.querySelector("li.is-active").classList.remove(isActiveClass);

    let index = Array.from(thumbItems).indexOf(el);

    el.classList.add(isActiveClass);

    featuredList

      .querySelector(`li:nth-child(${++index})`)

      .classList.add(isActiveClass);

  });

});

添加键盘支持

更进一步,我们将通过提供对键盘导航的支持来增强以前的功能。进一步来说:

  • 每次按下向上( ↑ ) 或向下( ↓ )箭头键时,我们都会检索预先存在的活动缩略图。 

  • 如果按下向上箭头键,当前缩略图之前的缩略图将变为活动状态。如果没有任何此类缩略图,则最后一个缩略图将变为活动状态。

  • 如果按下向下箭头键,当前缩略图之后的缩略图将变为活动状态。如果没有任何此类缩略图,则第一个缩略图将变为活动状态。

这是所需的代码:

...

document.addEventListener("keyup", (e) => {

  if (e.keyCode === 38 || e.keyCode === 40) {

    const activeThumb = thumbList.querySelector("li.is-active");

    // up arrow

    if (e.keyCode === 38) {

      if (activeThumb.previousElementSibling) {

        activeThumb.previousElementSibling.click();

      } else {

        thumbList.lastElementChild.click();

      }

    } else {

      // down arrow

      if (activeThumb.nextElementSibling) {

        activeThumb.nextElementSibling.click();

      } else {

        thumbList.firstElementChild.click();

      }

    }

  }

});

作为增强功能,您可以  在移动布局上切换左/右箭头的上/下 箭头 

使特征图像可拖动

接下来,我们将使特色图像成为可拖动元素。如前所述,为此,我们将利用 GSAP 的 Draggable 插件。我们将通过它的create()方法实例化插件,并将以下两个参数传递给它:

  • 我们要拖动的元素。

  • 一个配置对象。在其中,我们将指定可拖动元素在效果期间应保持的边界。可选地,当我们加载了 InertiaPlugin 时,我们还将inertia在用户的鼠标/触摸释放后通过基于动量的属性请求。 

  下面是对应的代码:

const galleryWrapper = document.querySelector(".gallery-wrapper");

const featuredList = galleryWrapper.querySelector(".featured-list");

const featuredItems = featuredList.querySelectorAll("li"); 

Draggable.create(featuredImgs, {

  bounds: featuredList,

  inertia: true

});

当然,在这里,我们只介绍了插件功能的基本部分。您可以通过阅读文档和实现复杂的东西来更深入地了解。

打开灯箱

如前所述,只要我们单击“打开灯箱”按钮,灯箱就会出现。因此,单击后,我们将执行以下操作:

  • is-active从预先存在的活动灯箱图像中删除该类(如果有)。

  •  通过类从body元素中移除垂直滚动条。overflow-y-hidden

  • 查找当前活动的特色图像的索引。

  • 将is-active类分配给其索引与此特色图像的索引匹配的灯箱图像。 

  • is-visible通过课堂展示灯箱。

如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第8张

这是所需的代码

...

openLightbox.addEventListener("click", () => {

  if (lightboxItems.querySelector("li.is-active")) {

    lightboxItems.querySelector("li.is-active").classList.remove(isActiveClass);

  }

  body.classList.add(overflowYHiddenClass);

  const el = featuredList.querySelector("li.is-active");

  let index = Array.from(featuredItems).indexOf(el);

  lightboxItems

    .querySelector(`li:nth-child(n+${++index})`)

    .classList.add(isActiveClass);

  lightbox.classList.add(isVisibleClass);

});

关闭灯箱

关闭灯箱有两种不同的方式:

  • 首先,通过单击.close-lightbox位于灯箱标题内的元素。

  • 其次,通过Esc按键。

再次,这是所需的代码

...

document.addEventListener("click", (e) => {

  if (e.target === closeLightbox) {

    body.classList.remove(overflowYHiddenClass);

    lightbox.classList.remove(isVisibleClass);

  }

});

document.addEventListener("keyup", (e) => {

  // Esc

  if (document.querySelector(".lightbox.is-visible") && e.keyCode === 27) {

    body.classList.remove(overflowYHiddenClass);

    lightbox.classList.remove(isVisibleClass);

  }

});

更改灯箱幻灯片

每次单击导航箭头时,我们都会执行以下操作:

  • 获取当前活动的灯箱幻灯片的副本。

  • is-active从此幻灯片中删除课程。

  • 检查以查看单击了哪个按钮。如果这是下一个,我们将把这个is-active类添加到活动的幻灯片后面的幻灯片中。如果没有这样的幻灯片,则第一个将收到此课程。

  • 另一方面,如果那是前一个,我们将把类添加到is-active活动类之前的幻灯片中。如果没有这样的幻灯片,最后一个将收到这个类。


如何使用 GSAP 构建可拖动的图片库和自定义灯箱  第9张


这是所需的代码:

... 

for (const lightboxControl of lightboxControls) {

  lightboxControl.addEventListener("click", (e) => {

    const activeSlide = lightboxItems.querySelector("li.is-active");

    activeSlide.classList.remove(isActiveClass);

    if (e.currentTarget === lightboxNextControl) {

      activeSlide.nextElementSibling

        ? activeSlide.nextElementSibling.classList.add(isActiveClass)

        : lightboxItems.firstElementChild.classList.add(isActiveClass);

    } else {

      activeSlide.previousElementSibling

        ? activeSlide.previousElementSibling.classList.add(isActiveClass)

        : lightboxItems.lastElementChild.classList.add(isActiveClass);

    }

  });

}

添加键盘支持

就像我们对图片库所做的那样,让我们通过添加对键盘导航的支持来使我们的灯箱更加强大。进一步来说:

  • 如果灯箱可见,我们检查是否按下了左( ← ) 或右 ( → )箭头键。

  • 如果按下左箭头键,我们将强制单击上一个导航控件。

  • 同样,如果按下右箭头键,我们将强制单击下一个导航控件。

这是所需的代码:

...

 

document.addEventListener("keyup", (e) => {

  if (

    document.querySelector(".lightbox.is-visible") &&

    (e.keyCode === 37 || e.keyCode === 39)

  ) {

    // left arrow

    if (e.keyCode === 37) {

      lightboxPrevControl.click();

    } else {

      // next arrow

      lightboxNextControl.click();

    }

  }

});

结论

伙计们,另一个练习已经结束了!感谢您的关注。希望您喜欢我们今天构建的内容,它让您深入了解如何将一些自定义代码与 GSAP 等流行插件的强大功能相结合。 


文章目录
  • 我们正在建造什么
  • 1.包括所需的插件
  • 2.定义 html 标记
    • 为图库设置标记
    • 为灯箱库设置标记
  • 3.指定主要样式
    • 设置画廊布局
    • 精选幻灯片的可见性
    • 定位特色图片
    • 指示活动和悬停状态
    • 设置灯箱样式
  • 4.添加javaScript
    • 更改图库幻灯片
    • 添加键盘支持
    • 使特征图像可拖动
    • 打开灯箱
    • 关闭灯箱
    • 更改灯箱幻灯片
    • 添加键盘支持
  • 结论