1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import create from 'dd-store';
var MIN_DISTANCE = 10;
var THRESHOLD = 0.3;
function getDirection(x, y) {
if (x > y && x > MIN_DISTANCE) {
return 'horizontal';
}
if (y > x && y > MIN_DISTANCE) {
return 'vertical';
}
return '';
}
let ARRAY = [];
/**
* num: 当前的移动大小
* min: 往左移的最大位置
* max: 往右移的最大位置
*/
function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
create.Component({
mixins: [],
data: {
wrapperStyle: ''
},
props: {},
didMount() {
ARRAY.push(this);
this.offset = 0;
},
didUpdate() { },
didUnmount() {
//组件卸载的时候需要清空ARRAY,否则每次didMount都累加
this.destroyed();
},
methods: {
close: function () {
this.dragging = false;
this.swipeMove(0);
},
destroyed: function () {
ARRAY = ARRAY.filter((item) => { return item !== this; });
},
resetTouchStatus: function () {
this.direction = '';
this.deltaX = 0;
this.deltaY = 0;
this.offsetX = 0;
this.offsetY = 0;
},
touchStart: function (event) {
this.resetTouchStatus();
var touch = event.touches[0];
this.startX = touch.clientX;
this.startY = touch.clientY;
},
touchMove: function (event) {
var touch = event.touches[0];
this.deltaX = touch.clientX - this.startX;
this.deltaY = touch.clientY - this.startY;
this.offsetX = Math.abs(this.deltaX);
this.offsetY = Math.abs(this.deltaY);
this.direction = this.direction || getDirection(this.offsetX, this.offsetY);
},
startDrag: function (event) {
this.startOffset = this.offset;
this.touchStart(event);
},
onDrag: function (event) {
this.touchMove(event);
if (this.direction !== 'horizontal') {
return;
}
//设置页面禁止竖向滚动
this.props.onSetBodyDisableScroll(true);
//滑动的时候不要过度时间,否则不跟手势的感觉
this.dragging = true;
// 其他组件归位
ARRAY.filter((item) => { return item !== this }).forEach(function (item) { return item.close(); });
this.swipeMove(this.startOffset + this.deltaX);
},
swipeMove: function (offset) {
this.offset = range(offset, -this.props.rightWidth, this.props.leftWidth);
var transform = "translate3d(" + this.offset + "px, 0, 0)";
var transition = this.dragging
? 'none'
: 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
this.setData({
wrapperStyle: "\n -webkit-transform: " + transform + ";\n -webkit-transition: " + transition + ";\n transform: " + transform + ";\n transition: " + transition + ";\n "
});
},
endDrag: function () {
this.dragging = false;
// 结束的时候判断是否需要帮忙拉到底或者归位,否则到中间就不动了,体验很不好
this.swipeLeaveTransition();
},
onClick: function (event) {
ARRAY.forEach(function (item) { return item.close(); });
},
swipeLeaveTransition: function () {
const { leftWidth, rightWidth } = this.props;
var offset = this.offset;
if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
this.open('right');
}
else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
this.open('left');
}
else {
this.swipeMove(0);
}
//恢复页面竖向滚动
setTimeout(() => {
this.props.onSetBodyDisableScroll(false);
})
},
open: function (position) {
const { leftWidth, rightWidth } = this.props;
var offset = position === 'left' ? leftWidth : -rightWidth;
this.swipeMove(offset);
//向父组件暴露关闭方法
this.$store.closeActiveSwipe = () => {
this.close();
}
this.update();
},
},
});