diff --git a/README.md b/README.md index 0978889..47744c1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A simple publish/subscribe pattern - Plain old vanilla JS -- Just 0.6kb gzipped +- Just 1kb gzipped ## Installation @@ -58,7 +58,7 @@ const event = new Event() publishClick({ event }) event.subscribe('global.click', ({ target }) => { - console.log('Somebody clicked', target) + console.log('Somebody clicked on', target) }) ``` @@ -76,6 +76,20 @@ event.subscribe('global.escape', () => { }) ``` +#### Swipe + +```js +import Event, { publishSwipe } from 'core-events' + +const event = new Event() + +publishSwipe({ event, sensitivity: { x: 10, y: 50 } }) + +event.subscribe('global.swipe', ({ direction, target }) => { + console.log(`Somebody swiped ${direction} on`, target) +}) +``` + ## Browser support Core Events is packaged with Babel, and diff --git a/src/index.js b/src/index.js index d2ac97e..8a9e83a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import { publishClick, publishEscape } from './publish' +import { publishClick, publishEscape, publishSwipe } from './publish' const _ = new WeakMap() @@ -46,6 +46,6 @@ class Event { } } -export { publishClick, publishEscape } +export { publishClick, publishEscape, publishSwipe } export default Event diff --git a/src/publish.js b/src/publish.js index fbe99b8..1782bb0 100644 --- a/src/publish.js +++ b/src/publish.js @@ -1,3 +1,5 @@ +import { supportsPassive } from './support' + const publishClick = ({ event, name = 'global.click' }) => { window.addEventListener('click', ({ target }) => { event.publish(name, { target }) @@ -12,4 +14,55 @@ const publishEscape = ({ event, name = 'global.escape' }) => { }) } -export { publishClick, publishEscape } +const publishSwipe = ({ + event, + name = 'global.swipe', + sensitivity = { x: 10, y: 10 } +}) => { + let swipeStarted = false + let swipeTarget = null + let swipeStartX = null + let swipeStartY = null + + const swipeStart = e => { + swipeStarted = true + swipeTarget = e.target + swipeStartX = e.screenX + swipeStartY = e.screenY + } + + const swipeEnd = e => { + if (swipeStarted) { + if (Math.abs(e.screenX - swipeStartX) >= sensitivity.x) { + e.screenX < swipeStartX + ? event.publish(name, { direction: 'left', target: swipeTarget }) + : event.publish(name, { direction: 'right', target: swipeTarget }) + } + + if (Math.abs(e.screenY - swipeStartY) >= sensitivity.y) { + e.screenY < swipeStartY + ? event.publish(name, { direction: 'up', target: swipeTarget }) + : event.publish(name, { direction: 'down', target: swipeTarget }) + } + + swipeStarted = false + swipeTarget = null + swipeStartX = null + swipeStartY = null + } + } + + window.addEventListener('touchstart', e => { + swipeStart(e.changedTouches[ 0 ]) + }, supportsPassive ? { passive: true } : false) + + window.addEventListener('touchend', e => { + swipeEnd(e.changedTouches[ 0 ]) + }, supportsPassive ? { passive: true } : false) + + window.addEventListener('mousedown', e => swipeStart(e)) + + window.addEventListener('mouseup', e => swipeEnd(e)) +} + +export { publishClick, publishEscape, publishSwipe } diff --git a/src/support.js b/src/support.js new file mode 100644 index 0000000..aeb7866 --- /dev/null +++ b/src/support.js @@ -0,0 +1,25 @@ +let testedPassiveSupport = false +let passive = false + +const testPassiveSupport = () => { + try { + const opts = Object.defineProperty({}, 'passive', { + get: () => { + passive = true + } + }) + + window.addEventListener('test', null, opts) + } catch (e) {} +} + +const supportsPassive = () => { + if (!testedPassiveSupport) { + testPassiveSupport() + testedPassiveSupport = true + } + + return passive +} + +export { supportsPassive }