如何用原生实现一个滑动消除卡片的组件
今天看到chrome github 实现的一个通过左右滑动清除子卡片的的组件。感觉有点意思,学习一下
源地址在这里
https://github.com/GoogleChrome/ui-element-samples/tree/gh-pages/swipeable-cards
需求分析
这个组件的功能很单一
- 接受一组元素,使之可以通过鼠标或是触控左右滑动元素
- 当左右滑动到达一定程度以后则删除该列表元素
这个组件的一个难点在于如何让元素跟随鼠标或是触控左右滑动。
关于这一点,我们可以将整个过程分为
开始滑动->滑动中->滑动结束
同时为了滑动过程的流畅,我们不在滑动中触发响应的位移动画,
我们可以单独抽出一个 update 函数负责函数动画的绘制,
而只要 requestAnimationFrame 函数循环调用在每一帧中检查是否有需要位移,有则更新利用 update 响应的位移位置到 css 动画中
开始滑动
这一阶段我们需要捕获 mousedown 跟 touchstart 事件,通过事件的target确定被拖动的元素
并记录 target 元素相关数据,比如说我们最后需要判断位移是否“过了”该触发删除的点所以需要一个开始位移的位置,
另一方面就是拖放过程中的位移记录
还有就是设置一下 css 动画相关的样式,触发位移动画的一些设置
滑动中
这一阶段对应的是 mousemove 与touchmove 事件
这个阶段最简单,只需要不断更新位移的位置就好了,滑动的效果由 update 自己通过 requsetnimationFrame 不断去调用检查就好
滑动结束
这一阶段对应的是 mouseup 与touchend 事件
这个时候需要做的事情会多一点点,需要稍微计算一下我们在开始滑动的时候保存的位置,判断当前位置是否已经过了这个某个点,可以删除元素还是令其归位
复位与惯性
为了是左右滑动卡片过程中更加平滑,需要为滑动卡片结束后的两个状态,做处理。
惯性
当需要移除子元素的时候,增加一个惯性的继续移动的动画效果。
为了实现一个惯性的效果
首先,我们知道了当前位移了 screenX,这个是时候通过 screenX 的正负判断出位移的方向。
然后 google 的做法是增加一个 target 元素的宽的目标位移距离,然后
在更新动画的时候,我们根据 targetX 以每次 (screenX-targetX)/4 的变化趋势增加 screenX 达到一个平缓增加的过程
复位
当未到边界的时候,增加一个归位的动画效果,这里实际上跟惯性是同样的,只不过他位移 targetX 应当是 0
如何计算透明度
在滑动过程中,为了表现出一种简便的过程,我们可以增加一个滑动元素的透明度的改变更加直观的显示出,当前处于什么什么状态。
问题在于我们的滑动动画是不是一个线性的过程,因为我们为了动画效果平滑,应用了贝塞尔曲线。
因此,我们需要对透明度的变化做出类似的平滑变化,而不是一个线性的变化。
这里的做法是,将 (位移的距离/元素的宽)^3 通过这样一个简单的三次方程来拟合贝塞尔曲线,
代码注释
|
|
|
|