floating panel - 带有锚点功能和可拖拽顶栏的浮动面板

在现代的前端应用中,浮动面板是一个非常常见的UI组件,它能够为用户提供额外的信息和操作空间,同时又不会占据页面的主要内容区域。本文将详细记录如何实现一个带有锚点功能和可拖拽顶栏的浮动面板。

设计思路

这个浮动面板将由三个主要部分组成:父元素(floating-panel)、标头(floating-panel-header)和内容(floating-panel-content)。我们将通过设置父元素的偏移值来实现浮动效果,并通过监听touchmove事件来实现拖拽功能。

1. 父元素设计

父元素floating-panel将作为整个浮动面板的容器。常态下,我们将为它设置一个初始的偏移值,使其位于页面的底部。

2. 标头设计

标头floating-panel-header将作为用户交互的主要区域。它将包含一个可拖拽的顶栏,用户可以通过拖动这个顶栏来改变浮动面板的高度。我们将为这个顶栏添加touchmove事件监听器,以便在用户拖动时动态改变父元素的偏移值。

根据设计,我们的锚点可以大概设计为三个:底部、页面一半高度、页面顶部,分别对应不同的父元素偏移值

为了实现锚点功能,可以利用touchmovetouchend事件,根据 touchmoveclientY属性判断父元素最终的偏移值;

 touchmovetouchend都需要动态改变父元素的偏移,最终通过touchend来固定,以满足拖动的动画效果。

3. 内容设计

内容floating-panel-content将展示实际的信息和操作界面。它将根据父元素的偏移值动态调整自身的高度和显示内容。

实现步骤

1. HTML结构

首先,我们需要构建浮动面板的基本HTML结构。以下是一个简单的示例:

<div className="floating-panel" id="floating-panel" style={{ transform: `translateY(${window.innerHeight - 160}px)` }}>
  <div className="floating-panel-header" id="floating-panel-header">
    <div className="floating-panel-header-bar"></div>
  </div>
  <div className="floating-panel-content" id="floating-panel-content">
    <div className="content" id="content">
      <Content..... />
    </div>
  </div>
</div>

2. CSS样式

接下来,我们需要为浮动面板添加一些基本的CSS样式。以下是一个示例:

.floating-panel {
    background-color: rgba(30, 30, 30, 1);
    border-radius: 10px;
    height: 100%;
    &-header {
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: grab;
      height: 20px;
      &-bar {
        height: 4px;
        width: 30px;
        border-radius: 10px;
        background-color: rgba(79, 79, 79, 1);
      }
    }
    &-content {
      padding: 10px;
      overflow-y: auto;
      max-height: 400px; /* 根据需要调整 */
    }
  }

3. JavaScript逻辑

最后,我们需要添加一些JavaScript逻辑来实现拖拽功能和锚点功能。

const initTouch = () => {
    const ele = document.getElementById('floating-panel-header');
    const panel = document.getElementById('floating-panel');
    const contentEle = document.getElementById('content'); // 内容元素
    let transformY = window.innerHeight - 160,
      contentHeight = window.innerHeight - 225;

    ele?.addEventListener('touchmove', (e) => {
      e.preventDefault();
      const { clientY } = e.touches[0];
      if (clientY < 180) {
        transformY = 0;
        contentHeight = window.innerHeight - 225;
      } else if (clientY >= 180 && clientY < window.innerHeight / 2 + 150) {
        transformY = window.innerHeight / 2 - 100;
        contentHeight = window.innerHeight - 545;
      } else {
        transformY = window.innerHeight - 160;
        contentHeight = window.innerHeight - 225;
      }
      panel.style.transform = `translateY(${clientY - 50}px)`;
    });
    ele?.addEventListener('touchend', () => {
      panel.style.transform = `translateY(${transformY}px)`;
      contentEle.style.height = `${contentHeight}px`;
    });
  };

注意事项

  • 在实现拖拽功能时,我们禁用了父元素的过渡效果,以确保拖拽过程中的高度变化是即时的。在拖拽结束后,我们恢复了过渡效果,以便父元素能够平滑地回到其最终位置。
  • 请注意,这个示例中的拖拽功能仅适用于移动端操作。如果你需要支持web设备,可以考虑使用mousedownmousemovemouseup事件来实现类似的逻辑。

通过以上步骤,我们成功实现了一个带有锚点功能和可拖拽顶栏的浮动面板。这个浮动面板可以根据用户的操作动态调整其高度,并且能够快速定位到指定的锚点位置。

posted @ 2025-01-05 18:51  Yang9710  阅读(348)  评论(0)    收藏  举报