1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | import util from '../../ons/util.js';
|
19 | import GestureDetector from '../../ons/gesture-detector.js';
|
20 |
|
21 | const widthToPx = (width) => {
|
22 | const [value, px] = [parseInt(width, 10), /px/.test(width)];
|
23 | return px ? value : Math.round(document.body.offsetWidth * value / 100);
|
24 | };
|
25 |
|
26 | export default class SwipeReveal {
|
27 |
|
28 | constructor(params) {
|
29 | 'element ignoreSwipe isInitialState onDragCallback swipeMax swipeMin swipeMid'
|
30 | .split(/\s+/).forEach(key => this[key] = params[key]);
|
31 |
|
32 | this.elementHandler = params.elementHandler || params.element;
|
33 | this.getThreshold = params.getThreshold || (() => .5);
|
34 | this.getSide = params.getSide || (() => 'left');
|
35 |
|
36 | this.handleGesture = this.handleGesture.bind(this);
|
37 |
|
38 | this._shouldFixScroll = util.globals.actualMobileOS === 'ios';
|
39 | }
|
40 |
|
41 | update(swipeable = this.element.hasAttribute('swipeable')) {
|
42 | if (!this.gestureDetector) {
|
43 | this.gestureDetector = new GestureDetector(this.elementHandler, { dragMinDistance: 1, passive: !this._shouldFixScroll });
|
44 | }
|
45 |
|
46 | const action = swipeable ? 'on' : 'off';
|
47 | this.gestureDetector[action]('drag dragstart dragend', this.handleGesture);
|
48 | }
|
49 |
|
50 | handleGesture(e) {
|
51 | if (e.gesture) {
|
52 | if (e.type === 'dragstart') {
|
53 | this.onDragStart(e);
|
54 | } else if (!this._ignoreDrag) {
|
55 | e.type === 'dragend' ? this.onDragEnd(e) : this.onDrag(e);
|
56 | }
|
57 | }
|
58 | }
|
59 |
|
60 | onDragStart(event) {
|
61 | const getDistance = () => this.getSide() === 'left' ? event.gesture.center.clientX : window.innerWidth - event.gesture.center.clientX;
|
62 | this._ignoreDrag = event.consumed || !util.isValidGesture(event) || this.ignoreSwipe(event, getDistance());
|
63 |
|
64 | if (!this._ignoreDrag) {
|
65 | event.consume && event.consume();
|
66 | event.consumed = true;
|
67 |
|
68 | this._width = widthToPx(this.element.style.width || '100%');
|
69 | this._startDistance = this._distance = (!(this.isInitialState instanceof Function) || this.isInitialState()) ? 0 : this._width;
|
70 |
|
71 | util.iosPreventScroll(this.gestureDetector);
|
72 | }
|
73 | }
|
74 |
|
75 | onDrag(event) {
|
76 | event.stopPropagation();
|
77 |
|
78 | const delta = this.getSide() === 'left' ? event.gesture.deltaX : -event.gesture.deltaX;
|
79 | const distance = Math.max(0, Math.min(this._width, this._startDistance + delta));
|
80 | if (distance !== this._distance) {
|
81 | this._distance = distance;
|
82 | this.swipeMid(this._distance, this._width);
|
83 | }
|
84 | }
|
85 |
|
86 | onDragEnd(event) {
|
87 | event.stopPropagation();
|
88 |
|
89 | const direction = event.gesture.interimDirection;
|
90 | const isSwipeMax = this.getSide() !== direction && this._distance > this._width * this.getThreshold();
|
91 | isSwipeMax ? this.swipeMax() : this.swipeMin();
|
92 | }
|
93 |
|
94 | dispose() {
|
95 | this.gestureDetector && this.gestureDetector.dispose();
|
96 | this.gestureDetector = this.element = this.elementHandler = null;
|
97 | }
|
98 | }
|