diff options
| author | Henry Jameson <me@hjkos.com> | 2019-03-30 12:31:50 +0200 |
|---|---|---|
| committer | Henry Jameson <me@hjkos.com> | 2019-03-30 12:31:50 +0200 |
| commit | 9f4a9bff464e43e1c01d621e8c55db6105d327de (patch) | |
| tree | 3124790d8a00ef148acb199efeac59594879f875 /src/services/gesture_service | |
| parent | e89a62200532a4d61de35d73299c33555aad8bed (diff) | |
| parent | 0117f6af9f8ae600e613402590de4c9364806967 (diff) | |
Merge remote-tracking branch 'upstream/develop' into minimal-scopes-mode
* upstream/develop: (173 commits)
Fix: Change condition
fix typo
update store according to retweeted status
#433 - update sort by for conversation
display replies_count right after reply icon
expose replies_count from mastodon api
Apparently, MastoAPI gives status in ancestors if you try opening a repeat...
make side drawer use gesture service and fix its animations
review/remove error hiding
errata
review
#433 - sort conversation for retweets and clean up
Revert "Merge branch 'revert-987b5162' into 'develop'"
Revert "Merge branch 'mastoapi/friends-tl' into 'develop'"
Add await to login action'
Remove console log
Fix warnings in user profile routing
Add tests for gesture service, fix bug with perpendicular directions
#255 - clean up autocomplete form
#255 - clean up user settings page with self-closing html tags
...
Diffstat (limited to 'src/services/gesture_service')
| -rw-r--r-- | src/services/gesture_service/gesture_service.js | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/services/gesture_service/gesture_service.js b/src/services/gesture_service/gesture_service.js new file mode 100644 index 00000000..88a328f3 --- /dev/null +++ b/src/services/gesture_service/gesture_service.js @@ -0,0 +1,74 @@ + +const DIRECTION_LEFT = [-1, 0] +const DIRECTION_RIGHT = [1, 0] +const DIRECTION_UP = [0, -1] +const DIRECTION_DOWN = [0, 1] + +const deltaCoord = (oldCoord, newCoord) => [newCoord[0] - oldCoord[0], newCoord[1] - oldCoord[1]] + +const touchEventCoord = e => ([e.touches[0].screenX, e.touches[0].screenY]) + +const vectorLength = v => Math.sqrt(v[0] * v[0] + v[1] * v[1]) + +const perpendicular = v => [v[1], -v[0]] + +const dotProduct = (v1, v2) => v1[0] * v2[0] + v1[1] * v2[1] + +const project = (v1, v2) => { + const scalar = (dotProduct(v1, v2) / dotProduct(v2, v2)) + return [scalar * v2[0], scalar * v2[1]] +} + +// direction: either use the constants above or an arbitrary 2d vector. +// threshold: how many Px to move from touch origin before checking if the +// callback should be called. +// divergentTolerance: a scalar for much of divergent direction we tolerate when +// above threshold. for example, with 1.0 we only call the callback if +// divergent component of delta is < 1.0 * direction component of delta. +const swipeGesture = (direction, onSwipe, threshold = 30, perpendicularTolerance = 1.0) => { + return { + direction, + onSwipe, + threshold, + perpendicularTolerance, + _startPos: [0, 0], + _swiping: false + } +} + +const beginSwipe = (event, gesture) => { + gesture._startPos = touchEventCoord(event) + gesture._swiping = true +} + +const updateSwipe = (event, gesture) => { + if (!gesture._swiping) return + // movement too small + const delta = deltaCoord(gesture._startPos, touchEventCoord(event)) + if (vectorLength(delta) < gesture.threshold) return + // movement is opposite from direction + if (dotProduct(delta, gesture.direction) < 0) return + // movement perpendicular to direction is too much + const towardsDir = project(delta, gesture.direction) + const perpendicularDir = perpendicular(gesture.direction) + const towardsPerpendicular = project(delta, perpendicularDir) + if ( + vectorLength(towardsDir) * gesture.perpendicularTolerance < + vectorLength(towardsPerpendicular) + ) return + + gesture.onSwipe() + gesture._swiping = false +} + +const GestureService = { + DIRECTION_LEFT, + DIRECTION_RIGHT, + DIRECTION_UP, + DIRECTION_DOWN, + swipeGesture, + beginSwipe, + updateSwipe +} + +export default GestureService |
