Created
June 18, 2020 16:53
-
-
Save mfcodeworks/eba18fa9a04e4bba8ce2d046f61a8806 to your computer and use it in GitHub Desktop.
Drag HTML Elements
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { | |
fromEvent, | |
interval, | |
merge | |
} = rxjs | |
const { | |
takeUntil, | |
repeat, | |
throttle, | |
switchMap, | |
map, | |
tap | |
} = rxjs.operators | |
// Get target | |
const el = document.querySelector('.draggable'); | |
// Get events | |
const down$ = merge( | |
fromEvent(el, 'mousedown'), | |
fromEvent(el, 'touchstart') | |
); | |
const move$ = merge( | |
fromEvent(document, 'mousemove'), | |
fromEvent(document, 'touchmove') | |
); | |
const up$ = merge( | |
fromEvent(el, 'mouseup'), | |
fromEvent(el, 'touchend') | |
); | |
// Process dragging | |
const drag$ = down$.pipe( | |
// Add offset to touch events | |
map(ev => ev instanceof MouseEvent | |
? ev : Object.assign(ev, { | |
offsetX: Math.floor(ev.touches[0].clientX) - ev.target.offsetLeft, | |
offsetY: Math.floor(ev.touches[0].clientY) - ev.target.offsetTop | |
}) | |
), | |
switchMap(start => move$.pipe( | |
// Slow to 59 events per second (60~ fps) | |
throttle(() => interval(17)), | |
// Prevent further handling of events | |
tap(move => move.preventDefault()), | |
// Map to new posiiton | |
map(move => { | |
return move instanceof MouseEvent ? ({ | |
left: move.clientX - start.offsetX, | |
top: move.clientY - start.offsetY | |
}) : ({ | |
left: move.targetTouches[0].clientX - start.offsetX, | |
top: move.targetTouches[0].clientY - start.offsetX | |
}) | |
}) | |
)), | |
// Apply new posiiton | |
tap(e => { | |
el.style.top = `${e.top}px`; | |
el.style.left = `${e.left}px`; | |
}), | |
// Track dragging until user lets go | |
takeUntil(up$), | |
// Repeat even after initial drag | |
repeat() | |
) | |
// Handle dragging | |
drag$.subscribe() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment