From 0190a360709cde899387b311dcf4bbaf508b00ba Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 2 Aug 2021 19:33:33 -0400 Subject: Add missing swipe click component --- src/components/swipe_click/swipe_click.js | 85 ++++++++++++++++++++++++++++++ src/components/swipe_click/swipe_click.vue | 14 +++++ 2 files changed, 99 insertions(+) create mode 100644 src/components/swipe_click/swipe_click.js create mode 100644 src/components/swipe_click/swipe_click.vue (limited to 'src/components/swipe_click') diff --git a/src/components/swipe_click/swipe_click.js b/src/components/swipe_click/swipe_click.js new file mode 100644 index 00000000..49b097ce --- /dev/null +++ b/src/components/swipe_click/swipe_click.js @@ -0,0 +1,85 @@ +import GestureService from '../../services/gesture_service/gesture_service' + +/** + * props: + * direction: a vector that indicates the direction of the intended swipe + * threshold: the minimum distance in pixels the swipe has moved on `direction' + * for swipe-finished() to have a non-zero sign + * perpendicularTolerance: see gesture_service + * + * Events: + * preview-requested(offsets) + * Emitted when the pointer has moved. + * offsets: the offsets from the start of the swipe to the current cursor position + * + * swipe-canceled() + * Emitted when the swipe has been canceled due to a pointercancel event. + * + * swipe-finished(sign: 0|-1|1) + * Emitted when the swipe has finished. + * sign: if the swipe does not meet the threshold, 0 + * if the swipe meets the threshold in the positive direction, 1 + * if the swipe meets the threshold in the negative direction, -1 + * + * swipeless-clicked() + * Emitted when there is a click without swipe. + * This and swipe-finished() cannot be emitted for the same pointerup event. + */ +const SwipeClick = { + props: { + direction: { + type: Array + }, + threshold: { + type: Number, + default: 30 + }, + perpendicularTolerance: { + type: Number, + default: 1.0 + } + }, + methods: { + handlePointerDown (event) { + this.$gesture.start(event) + }, + handlePointerMove (event) { + this.$gesture.move(event) + }, + handlePointerUp (event) { + this.$gesture.end(event) + }, + handlePointerCancel (event) { + this.$gesture.cancel(event) + }, + handleNativeClick (event) { + event.stopPropagation() + event.preventDefault() + }, + preview (offsets) { + this.$emit('preview-requested', offsets) + }, + end (sign) { + this.$emit('swipe-finished', sign) + }, + click () { + this.$emit('swipeless-clicked') + }, + cancel () { + this.$emit('swipe-canceled') + } + }, + created () { + this.$gesture = new GestureService.SwipeAndClickGesture({ + direction: this.direction, + threshold: this.threshold, + perpendicularTolerance: this.perpendicularTolerance, + swipePreviewCallback: this.preview, + swipeEndCallback: this.end, + swipeCancelCallback: this.cancel, + swipelessClickCallback: this.click + }); + } +} + +export default SwipeClick diff --git a/src/components/swipe_click/swipe_click.vue b/src/components/swipe_click/swipe_click.vue new file mode 100644 index 00000000..5372071d --- /dev/null +++ b/src/components/swipe_click/swipe_click.vue @@ -0,0 +1,14 @@ + + + -- cgit v1.2.3-70-g09d2 From f3269cdc106511bc589dc68e71619a0d9581cd67 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 2 Aug 2021 19:44:01 -0400 Subject: Make lint happy --- src/components/media_modal/media_modal.js | 4 ---- src/components/pinch_zoom/pinch_zoom.js | 6 ++++-- src/components/swipe_click/swipe_click.js | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/components/swipe_click') diff --git a/src/components/media_modal/media_modal.js b/src/components/media_modal/media_modal.js index f4c99f6a..3de9822b 100644 --- a/src/components/media_modal/media_modal.js +++ b/src/components/media_modal/media_modal.js @@ -20,10 +20,6 @@ library.add( faCircleNotch ) -const onlyXAxis = ([x, y]) => [x, 0] -const SCALING_RESET_MIN = 1.1 -const SCALING_ENABLE_MOVE_THRESHOLD = 1 - const MediaModal = { components: { StillImage, diff --git a/src/components/pinch_zoom/pinch_zoom.js b/src/components/pinch_zoom/pinch_zoom.js index 36bebbce..82670ddf 100644 --- a/src/components/pinch_zoom/pinch_zoom.js +++ b/src/components/pinch_zoom/pinch_zoom.js @@ -1,11 +1,13 @@ import PinchZoom from '@kazvmoe-infra/pinch-zoom-element' export default { - props: { - }, methods: { setTransform ({ scale, x, y }) { this.$el.setTransform({ scale, x, y }) } + }, + created () { + // Make lint happy + (() => PinchZoom)() } } diff --git a/src/components/swipe_click/swipe_click.js b/src/components/swipe_click/swipe_click.js index 49b097ce..ac77154a 100644 --- a/src/components/swipe_click/swipe_click.js +++ b/src/components/swipe_click/swipe_click.js @@ -78,7 +78,7 @@ const SwipeClick = { swipeEndCallback: this.end, swipeCancelCallback: this.cancel, swipelessClickCallback: this.click - }); + }) } } -- cgit v1.2.3-70-g09d2 From 9f3a983fef9dfedef8f44855e1f939ea944cd0ba Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 2 Aug 2021 20:32:02 -0400 Subject: Use native click for hiding overlay The pointerup strategy is unsuccessful, as some other overlays (Firefox's Inspect Element) will pass down pointerup events. --- src/components/swipe_click/swipe_click.js | 3 +-- src/services/gesture_service/gesture_service.js | 26 ++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) (limited to 'src/components/swipe_click') diff --git a/src/components/swipe_click/swipe_click.js b/src/components/swipe_click/swipe_click.js index ac77154a..b979f42a 100644 --- a/src/components/swipe_click/swipe_click.js +++ b/src/components/swipe_click/swipe_click.js @@ -53,8 +53,7 @@ const SwipeClick = { this.$gesture.cancel(event) }, handleNativeClick (event) { - event.stopPropagation() - event.preventDefault() + this.$gesture.click(event) }, preview (offsets) { this.$emit('preview-requested', offsets) diff --git a/src/services/gesture_service/gesture_service.js b/src/services/gesture_service/gesture_service.js index 238b7875..cd9e3ba2 100644 --- a/src/services/gesture_service/gesture_service.js +++ b/src/services/gesture_service/gesture_service.js @@ -4,6 +4,8 @@ const DIRECTION_RIGHT = [1, 0] const DIRECTION_UP = [0, -1] const DIRECTION_DOWN = [0, 1] +const BUTTON_LEFT = 0 + const deltaCoord = (oldCoord, newCoord) => [newCoord[0] - oldCoord[0], newCoord[1] - oldCoord[1]] const touchCoord = touch => [touch.screenX, touch.screenY] @@ -23,8 +25,8 @@ const project = (v1, v2) => { return [scalar * v2[0], scalar * v2[1]] } -// const debug = console.log -const debug = () => {} +const debug = console.log +// const debug = () => {} // direction: either use the constants above or an arbitrary 2d vector. // threshold: how many Px to move from touch origin before checking if the @@ -100,11 +102,17 @@ class SwipeAndClickGesture { this._pointerId = -1 this._swiping = false this._swiped = false + this._preventNextClick = false } start (event) { debug('start() called', event) + // Only handle left click + if (event.button !== BUTTON_LEFT) { + return + } + this._startPos = pointerEventCoord(event) this._pointerId = event.pointerId debug('start pos:', this._startPos) @@ -124,6 +132,7 @@ class SwipeAndClickGesture { } cancel (event) { + debug('cancel called') if (!this._swiping || this._pointerId !== event.pointerId) { return } @@ -146,6 +155,8 @@ class SwipeAndClickGesture { debug('end: is swipe event') + debug('button = ', event.button) + // movement too small const coord = pointerEventCoord(event) const delta = deltaCoord(this._startPos, coord) @@ -171,9 +182,18 @@ class SwipeAndClickGesture { return isPositive ? 1 : -1 })() + const swiped = this._swiped if (this._swiped) { this.swipeEndCallback(sign) - } else { + } + this._reset() + if (swiped) { + this._preventNextClick = true + } + } + + click (event) { + if (!this._preventNextClick) { this.swipelessClickCallback() } this._reset() -- cgit v1.2.3-70-g09d2 From 6980e4ddf1aa8dfd8c3bba0ea6cc7de90f531ba9 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 2 Aug 2021 21:19:04 -0400 Subject: Scale swipe threshold with viewport width --- src/components/media_modal/media_modal.js | 7 +++++-- src/components/swipe_click/swipe_click.js | 4 ++-- src/services/gesture_service/gesture_service.js | 11 +++++++---- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src/components/swipe_click') diff --git a/src/components/media_modal/media_modal.js b/src/components/media_modal/media_modal.js index 91413563..6a368508 100644 --- a/src/components/media_modal/media_modal.js +++ b/src/components/media_modal/media_modal.js @@ -33,7 +33,10 @@ const MediaModal = { return { loading: false, swipeDirection: GestureService.DIRECTION_LEFT, - swipeThreshold: 50, + swipeThreshold: () => { + const considerableMoveRatio = 1 / 4 + return window.innerWidth * considerableMoveRatio + }, pinchZoomMinScale: 1, pinchZoomScaleResetLimit: 1.2 } @@ -104,7 +107,7 @@ const MediaModal = { this.$refs.pinchZoom.setTransform({ scale: 1, x: 0, y: 0 }) if (sign > 0) { this.goNext() - } else { + } else if (sign < 0) { this.goPrev() } }, diff --git a/src/components/swipe_click/swipe_click.js b/src/components/swipe_click/swipe_click.js index b979f42a..238e6df8 100644 --- a/src/components/swipe_click/swipe_click.js +++ b/src/components/swipe_click/swipe_click.js @@ -31,8 +31,8 @@ const SwipeClick = { type: Array }, threshold: { - type: Number, - default: 30 + type: Function, + default: () => 30 }, perpendicularTolerance: { type: Number, diff --git a/src/services/gesture_service/gesture_service.js b/src/services/gesture_service/gesture_service.js index cd9e3ba2..97a26ba7 100644 --- a/src/services/gesture_service/gesture_service.js +++ b/src/services/gesture_service/gesture_service.js @@ -25,8 +25,8 @@ const project = (v1, v2) => { return [scalar * v2[0], scalar * v2[1]] } -const debug = console.log -// const debug = () => {} +// const debug = console.log +const debug = () => {} // direction: either use the constants above or an arbitrary 2d vector. // threshold: how many Px to move from touch origin before checking if the @@ -92,7 +92,7 @@ class SwipeAndClickGesture { this.swipeEndCallback = swipeEndCallback || nop this.swipeCancelCallback = swipeCancelCallback || nop this.swipelessClickCallback = swipelessClickCallback || nop - this.threshold = threshold + this.threshold = typeof threshold === 'function' ? threshold : () => threshold this.perpendicularTolerance = perpendicularTolerance this._reset() } @@ -162,7 +162,10 @@ class SwipeAndClickGesture { const delta = deltaCoord(this._startPos, coord) const sign = (() => { - if (vectorLength(delta) < this.threshold) { + debug( + 'threshold = ', this.threshold(), + 'vector len =', vectorLength(delta)) + if (vectorLength(delta) < this.threshold()) { return 0 } // movement is opposite from direction -- cgit v1.2.3-70-g09d2