UNPKG

@studiometa/js-toolkit

Version:

A set of useful little bits of JavaScript to boost your project! 🚀

130 lines (129 loc) • 3.22 kB
import { AbstractService } from "./AbstractService.js"; import { ONCE_CAPTURE_EVENT_OPTIONS, PASSIVE_CAPTURE_EVENT_OPTIONS } from "./utils.js"; class PointerService extends AbstractService { static config = [ [ () => document, [ ["mouseenter", ONCE_CAPTURE_EVENT_OPTIONS], ["mousemove", PASSIVE_CAPTURE_EVENT_OPTIONS], ["touchmove", PASSIVE_CAPTURE_EVENT_OPTIONS], ["mousedown", PASSIVE_CAPTURE_EVENT_OPTIONS], ["touchstart", PASSIVE_CAPTURE_EVENT_OPTIONS], ["mouseup", PASSIVE_CAPTURE_EVENT_OPTIONS], ["touchend", PASSIVE_CAPTURE_EVENT_OPTIONS] ] ] ]; target; props = { event: null, isDown: false, x: 0, y: 0, changed: { x: false, y: false }, last: { x: 0, y: 0 }, delta: { x: 0, y: 0 }, progress: { x: 0.5, y: 0.5 }, max: { x: 0, y: 0 } }; constructor(target) { super(); this.target = target; const targetSize = this.getTargetSize(); this.props.x = this.props.last.x = targetSize.x / 2; this.props.y = this.props.last.y = targetSize.y / 2; this.props.max.x = targetSize.width; this.props.max.y = targetSize.height; } isTouchEvent(event) { return typeof TouchEvent !== "undefined" && event instanceof TouchEvent; } getTargetSize() { const { target } = this; return target instanceof Element ? target.getBoundingClientRect() : { width: window.innerWidth, height: window.innerHeight, x: 0, y: 0 }; } /** * Update the pointer positions. */ updateProps(event) { const { props } = this; props.event = event; const yLast = props.y; const xLast = props.x; const targetSize = this.getTargetSize(); let y = this.isTouchEvent(event) ? event.touches[0]?.clientY : event.clientY; y -= targetSize.y; if (y !== props.y) { props.y = y; } let x = this.isTouchEvent(event) ? event.touches[0]?.clientX : event.clientX; x -= targetSize.x; if (x !== props.x) { props.x = x; } props.changed.x = props.x !== xLast; props.changed.y = props.y !== yLast; props.last.x = xLast; props.last.y = yLast; props.delta.x = props.x - xLast; props.delta.y = props.y - yLast; props.max.x = targetSize.width; props.max.y = targetSize.height; props.progress.x = props.x / props.max.x; props.progress.y = props.y / props.max.y; return props; } /** * Handle events. * * @todo handle scroll as well */ handleEvent(event) { switch (event.type) { case "mouseenter": case "mousemove": case "touchmove": this.trigger(this.updateProps(event)); break; case "mousedown": case "touchstart": this.props.isDown = true; this.trigger(this.props); break; case "mouseup": case "touchend": this.props.isDown = false; this.trigger(this.props); break; } } } function usePointer(target = window) { return PointerService.getInstance([target], target); } export { PointerService, usePointer }; //# sourceMappingURL=PointerService.js.map