【问题标题】:iPhoneX-like show/hide menu/container by drag类似 iPhoneX 的拖拽显示/隐藏菜单/容器
【发布时间】:2018-08-19 14:06:02
【问题描述】:

我想实现在用户拖动.drag 元素时根据拖动值平滑折叠灰色.content-wrapper 块(内部带有蓝色方块)的能力。现在移动触摸拖动最好和最有效的方法是什么?

* {
  box-sizing: border-box;
  color: white;
}

.drag {
  width: 50px;
  height: 3px;
  border-radius: 3px;
  opacity: 0.3;
  margin: 0 auto;
  background: linear-gradient(to left, white, rgba(255, 255, 255, 0.8) 50%, white 100%);
  transition: opacity 0.4s;
}

.screen {
  padding-top: 40px;
  margin: 0 auto;
  border-radius: 5px;
  overflow: hidden;
  background: #2b2d5b;
  width: 320px;
  height: 568px;
}

.controls {
  background: linear-gradient(to bottom, #fd2929, #fd5c5c);
  height: 100px;
  
}

.drag-wrapper {
  display: block;
  padding: 20px;
}

.drag-wrapper:active .drag,
.drag-wrapper:hover .drag,
.drag-wrapper:focus .drag {
  opacity: 0.7;
}

.board {
  padding: 0 20px;
}

.content-wrapper {
  padding: 20px;
  height: 320px;
}

.content-wrapper {
  background: #444;
}

.content {
display: flex;
justify-content: center;
align-items: center;
font-family: Helvetica;
  background: linear-gradient(to bottom, #3adffd, #00abfb);
  height: 100%;
}
<div class="screen">
  <div class="content-wrapper">
    <div class="content">
    .content
    </div>
  </div>
  <a href="javascript:void(0)" class="drag-wrapper">
    <div class="drag"></div>
  </a>
  <div class="board">
    <div class="controls"></div>
  </div>
</div>

【问题讨论】:

    标签: javascript css drag-and-drop draggable hammer.js


    【解决方案1】:

    这是我对hammer.js 的这个案例的实现

    http://hammerjs.github.io

    board 的移动可能会基于e.velocityY 进行更复杂的计算,但是当pan 结束时我正在使用快速 CSS 转换,这对我的情况来说看起来不错

    $(document).ready(function() {
        let sliderManager = new Hammer.Manager(document.querySelector('.drag-wrapper'));
        let board = document.querySelector('.board');
        let threshold = 150;
        let boardTopInitial = board.style.top = board.offsetTop;
        let boardTopCollaped = 30;
      
        sliderManager.add(new Hammer.Pan({
          threshold: 0,
          pointers: 0
        }));
        sliderManager.on('pan', function(e) {
          e.preventDefault();
          board.classList.remove("transitable");
          board.classList.add("full-height");
          if (!board.classList.contains('pinned-top') && e.deltaY < 0) {
            board.style.top = boardTopInitial + e.deltaY + "px";
            if (e.isFinal) {
              board.classList.add("transitable");
              if (Math.abs(e.deltaY) > threshold) {
                board.style.top = boardTopCollaped + "px";
                board.classList.add("pinned-top");
              } else {
                board.setAttribute('style', '');
                board.classList.remove("full-height");
              }
            }
          } else if (board.classList.contains('pinned-top') && e.deltaY > 0) {
            board.style.top = boardTopCollaped + e.deltaY + "px";
            if (e.isFinal) {
              board.classList.add("transitable");
              if (Math.abs(e.deltaY) > threshold) {
                board.setAttribute('style', '');
                board.classList.remove("pinned-top");
                board.classList.remove("full-height");
              } else {
                board.style.top = boardTopCollaped + "px";
                board.classList.add("top");
              }
            }
          }
        })
      })
    * {
      box-sizing: border-box;
      color: white;
    }
    
    .drag {
      width: 50px;
      height: 3px;
      border-radius: 3px;
      opacity: 0.3;
      margin: 0 auto;
      background: linear-gradient(to left, white, rgba(255, 255, 255, 0.8) 50%, white 100%);
      transition: opacity 0.4s;
    }
    
    .pinned-top {
      top: 30px;
    }
    
    .full-height {
      box-shadow: none;
      min-height: 100vh;
    }
    
    .transitable {
      transition: top .2s ease-out;
    }
    
    .screen {
      position: relative;
      padding-top: 40px;
      margin: 0 auto;
      border-radius: 5px;
      overflow: hidden;
      background: #2b2d5b;
      width: 320px;
      height: 568px;
    }
    
    .controls {
      background: linear-gradient(to bottom, #fd2929, #fd5c5c);
      height: 100px;
    }
    
    .drag-wrapper {
      display: block;
      padding: 20px;
    }
    
    .drag-wrapper:active .drag,
    .drag-wrapper:hover .drag,
    .drag-wrapper:focus .drag {
      opacity: 0.7;
    }
    
    .board {
      padding: 0 20px;
      position: absolute;
      background: #2b2d5b;
      top: 360px;
      left: 0;
      right: 0;
    }
    
    .content-wrapper {
      padding: 20px;
      height: 320px;
    }
    
    .content-wrapper {
      background: #444;
    }
    
    .content {
      display: flex;
      justify-content: center;
      align-items: center;
      font-family: Helvetica;
      background: linear-gradient(to bottom, #3adffd, #00abfb);
      height: 100%;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://hammerjs.github.io/dist/hammer.min.js"></script>
    <div class="screen">
      <div class="content-wrapper">
        <div class="content">
          .content
        </div>
      </div>
      <div class="board">
        <a href="javascript:void(0)" class="drag-wrapper">
          <div class="drag"></div>
        </a>
        <div class="controls"></div>
      </div>
    </div>

    【讨论】:

    • 很好的解决方案,经过测试。想知道是否有可能防止board 被锁定在每个位置。这意味着我总是可以尝试向上/向下滑动它 - 现在看来我只能在向下滑动时向上滑动,在向上滑动时向下滑动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 2014-01-17
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多