2020-05-20 04:50:46 +00:00
|
|
|
/**
|
|
|
|
* Small utility to help with processing mouse-drag events. Usage is:
|
|
|
|
* dom('div', mouseDrag((startEvent, elem) => ({
|
|
|
|
* onMove(moveEvent) { ... },
|
|
|
|
* onStop(stopEvent) { ... },
|
|
|
|
* })));
|
|
|
|
*
|
|
|
|
* The passed-in callback is called on 'mousedown' events. It may return null to ignore the event.
|
|
|
|
* Otherwise, it should return a handler for mousemove/mouseup: we will then subscribe to these
|
|
|
|
* events, and clean up on mouseup.
|
|
|
|
*/
|
|
|
|
import {dom, DomElementMethod, IDisposable} from "grainjs";
|
|
|
|
|
|
|
|
|
|
|
|
export interface MouseDragHandler {
|
|
|
|
onMove(moveEv: MouseEvent): void;
|
|
|
|
onStop(endEv: MouseEvent): void;
|
|
|
|
}
|
|
|
|
|
2021-04-30 22:34:09 +00:00
|
|
|
export type MouseDragStart = (startEv: MouseEvent, elem: HTMLElement) => MouseDragHandler|null;
|
2020-05-20 04:50:46 +00:00
|
|
|
|
|
|
|
export function mouseDragElem(elem: HTMLElement, onStart: MouseDragStart): IDisposable {
|
|
|
|
|
|
|
|
// This prevents the default text-drag behavior when elem is part of a text selection.
|
|
|
|
elem.style.userSelect = 'none';
|
|
|
|
|
|
|
|
return dom.onElem(elem, 'mousedown', (ev, el) => _startDragging(ev, el, onStart));
|
|
|
|
}
|
|
|
|
export function mouseDrag(onStart: MouseDragStart): DomElementMethod {
|
|
|
|
return (elem) => { mouseDragElem(elem, onStart); };
|
|
|
|
}
|
|
|
|
|
2022-09-29 16:32:54 +00:00
|
|
|
// Same as mouseDragElem, but listens for mousedown on descendants of elem that match selector.
|
|
|
|
export function mouseDragMatchElem(elem: HTMLElement, selector: string, onStart: MouseDragStart): IDisposable {
|
|
|
|
return dom.onMatchElem(elem, selector, 'mousedown',
|
|
|
|
(ev, el) => _startDragging(ev as MouseEvent, el as HTMLElement, onStart));
|
|
|
|
}
|
|
|
|
|
2021-04-30 22:34:09 +00:00
|
|
|
function _startDragging(startEv: MouseEvent, elem: HTMLElement, onStart: MouseDragStart) {
|
2020-05-20 04:50:46 +00:00
|
|
|
const dragHandler = onStart(startEv, elem);
|
|
|
|
if (dragHandler) {
|
|
|
|
|
|
|
|
const {onMove, onStop} = dragHandler;
|
|
|
|
const upLis = dom.onElem(document, 'mouseup', stop, {useCapture: true});
|
|
|
|
const moveLis = dom.onElem(document, 'mousemove', onMove, {useCapture: true});
|
|
|
|
|
|
|
|
function stop(stopEv: MouseEvent) {
|
|
|
|
moveLis.dispose();
|
|
|
|
upLis.dispose();
|
|
|
|
onStop(stopEv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|