乐趣区

不到30行, 用any-touch实现一个drawer

any-touch 一个手势库
demo
预览
drawer 的基本逻辑

添加 2 个 div, 一个是当 drawer 隐藏的时候打开隐藏的触发开关, 一个是 drawer 本身.
对把手和 drawer 进行进行 fixed 定位到界面的右侧边缘.
调整 drawer 和把手的样式, 这里把手主要是要设置背景色为透明, 具体样式看下面代码.
用 any-touch 分别给把手和 drawer 添加 pan(拖拽) 手势.
当 drawer 隐藏时, 拖拽把手向右, 通过 pan 返回的 deltaX(每次触发拖拽的 x 偏移) 进行 drawer 的拖拽, 让其向右侧移动以显示.
向左拖拽 drawer, 让其隐藏, 当隐藏部分占 drawer 宽度超过一半的时候, 松开手, 那么抽屉自动隐藏到左侧, 反之, drawer 完全显示.

注: 本文仅用来讲解 drawer 的基本原理, 还有很多边界处理的细节大家可以后续自行补充作为练习.
代码
<!– 触发把手 –>
<div class=”com-drawer-handler” id=”j-com-drawer-handler”></div>

<!– 抽屉 –>
<div class=”com-drawer” id=”j-com-drawer”>
<img class=”avator” src=”https://s.cdpn.io/profiles/user/406915/80.jpg?1511329408″ width=”100%”>

<p align=”center”>
铁皮饭盒
</p>
<a class=”github” href=”https://github.com/383514580/any-touch”>github : any-touch</a>
<div>
<script src=”https://unpkg.com/any-touch/dist/AnyTouch.umd.js”></script>
.com-drawer-handler {
height: 100vh;
background: rgba(252, 252,252, 0);
width: 45px;
position: fixed;
z-index: 2;
top: 0;
left: 0;
}

.com-drawer {
padding: 30px;
height: 100vh;
min-width: 10vw;
position: fixed;
top: 0;
left: 0;
z-index: 3;
box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.1);
.avator {
touch-action: none;
display: block;
width: 60%;
border-radius: 100%;
margin: 15px auto;
}
.github {
padding: 5px 15px;
background: #000;
color: #fff;
text-decoration: none;
display: block;
text-align: center;
border-radius: 6px;
margin-top: 60px;
}
}

.animated {
transition: all 200ms;
}

// 抽屉部分
let offsetX = 0;
const elDrawer = document.getElementById(“j-com-drawer”);
const minX = 0 – elDrawer.offsetWidth;
const at = new AnyTouch(elDrawer);
at.on(“panstart”, ev => {
});
at.on(“panmove”, ({ deltaX}) => {
offsetX += deltaX;
console.log(offsetX, deltaX);
if (0 <= offsetX) {
offsetX = 0;
}
elDrawer.style.transform = `translateX(${offsetX}px)`;
});
at.on(“panend”, () => {
offsetX = minX / 2 < offsetX ? 0 : minX;
elDrawer.style.transform = `translateX(${offsetX}px)`;
elDrawer.classList.toggle(animated, true);
});
// 把手
const elHandler = document.getElementById(“j-com-drawer-handler”);
const atHandler = new AnyTouch(elHandler, { isPreventDefault: false});
atHandler.on(“panmove”, ({deltaX}) => {
offsetX+= deltaX;
offsetX = 0 < offsetX ? 0 : offsetX;
elDrawer.style.transform = `translateX(${offsetX}px)`;
console.log(ev.target,ev.currentTarget)
});
关于 vue 和 react 版本
这里是用纯 js 实现的版本, 如果用 vue 或者 react 代码量会更少, 有兴趣的同学可以自行实现或者需要的人多, 我会再写个 vue 版本的例子 (react 我也不会, 我得找同事帮写个 demo, 嘿). 太晚了, 写的仓促, 如果错误请指出, 我会立即修改.

退出移动版