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(); }, }, });