Skip to content

Instantly share code, notes, and snippets.

@mrehayden1
Last active August 18, 2018 09:57
Show Gist options
  • Save mrehayden1/e8da2fa2b0465950f2b71d86aefca3cd to your computer and use it in GitHub Desktop.
Save mrehayden1/e8da2fa2b0465950f2b71d86aefca3cd to your computer and use it in GitHub Desktop.
Mostjs Drag and Drop for touch devices.
import { Stream } from 'most';
import * as most from 'most';
type Maybe<T> = null | T
type Position = [number, number]
export function dragPositionStream(
touchStart$: Stream<TouchEvent>,
touchMove$: Stream<TouchEvent>,
touchEnd$: Stream<TouchEvent>
): Stream<Maybe<Position>>
{
return touchStart$
.map((e: TouchEvent) => {
const { pageX: touchX, pageY: touchY } = e.targetTouches[0];
const target = e.currentTarget as Element;
const { left: targetX, top: targetY } = target.getBoundingClientRect();
const offsetX = touchX - targetX;
const offsetY = touchY - targetY;
return touchMove$
.map((e: TouchEvent) => {
const { pageX: touchX, pageY: touchY } = e.targetTouches[0];
return [touchX - offsetX, touchY - offsetY] as Maybe<Position>
});
})
.merge(touchEnd$.constant(most.just(null)))
.switchLatest()
.startWith(null);
}
export function dropElementStream(
touchEnd$: Stream<TouchEvent>
): Stream<HTMLElement>
{
return touchEnd$
.map((e: TouchEvent) => {
const { pageX, pageY } = e.changedTouches[0];
// Hide the dragged element so we can see what it was dropped on.
const dragTarget = e.currentTarget as HTMLElement;
const savedVisibility: Maybe<string> = dragTarget.style.visibility;
dragTarget.style.visibility = 'hidden';
const dropElement = document.elementFromPoint(pageX, pageY) as HTMLElement;
dragTarget.style.visibility = savedVisibility;
return dropElement;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment