Repository URL to install this package:
|
Version:
1.2.9 ▾
|
"use strict";
// #onenoop
const _require = require("../../../exotic"),
NO_OP = _require.NO_OP;
const EvEmitter = require("./EvEmitter");
module.exports = Unipointer;
function Unipointer() {} // inherit EvEmitter
var proto = Unipointer.prototype = Object.create(EvEmitter.prototype);
proto.bindStartEvent = function (elem) {
this._bindStartEvent(elem, true);
};
proto.unbindStartEvent = function (elem) {
this._bindStartEvent(elem, false);
};
/**
* works as unbinder, as you can ._bindStart( false ) to unbind
* @param {Boolean} isBind - will unbind if falsey
*/
proto._bindStartEvent = function (elem, isBind) {
// munge isBind, default to true
isBind = isBind === undefined ? true : !!isBind;
var bindMethod = isBind ? 'addEventListener' : 'removeEventListener';
if (window.PointerEvent) {
// Pointer Events. Chrome 55, IE11, Edge 14
elem[bindMethod]('pointerdown', this);
} else {
// listen for both, for devices like Chrome Pixel
elem[bindMethod]('mousedown', this);
elem[bindMethod]('touchstart', this);
}
}; // trigger handler methods for events
proto.handleEvent = function (event) {
var method = 'on' + event.type;
if (this[method]) {
this[method](event);
}
}; // returns the touch that we're keeping track of
proto.getTouch = function (touches) {
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
if (touch.identifier == this.pointerIdentifier) {
return touch;
}
}
}; // ----- start event ----- //
proto.onmousedown = function (event) {
// dismiss clicks from right or middle buttons
var button = event.button;
if (button && button !== 0 && button !== 1) {
return;
}
this._pointerDown(event, event);
};
proto.ontouchstart = function (event) {
this._pointerDown(event, event.changedTouches[0]);
};
proto.onpointerdown = function (event) {
this._pointerDown(event, event);
};
/**
* pointer start
* @param {Event} event
* @param {Event or Touch} pointer
*/
proto._pointerDown = function (event, pointer) {
// dismiss right click and other pointers
// button = 0 is okay, 1-4 not
if (event.button || this.isPointerDown) {
return;
}
this.isPointerDown = true; // save pointer identifier to match up touch events
this.pointerIdentifier = pointer.pointerId !== undefined ? // pointerId for pointer events, touch.indentifier for touch events
pointer.pointerId : pointer.identifier;
this.pointerDown(event, pointer);
};
proto.pointerDown = function (event, pointer) {
this._bindPostStartEvents(event);
this.emitEvent('pointerDown', [event, pointer]);
}; // hash of events to be bound after start event
var postStartEvents = {
mousedown: ['mousemove', 'mouseup'],
touchstart: ['touchmove', 'touchend', 'touchcancel'],
pointerdown: ['pointermove', 'pointerup', 'pointercancel']
};
proto._bindPostStartEvents = function (event) {
if (!event) {
return;
} // get proper events to match start event
var events = postStartEvents[event.type]; // bind events to node
events.forEach(function (eventName) {
window.addEventListener(eventName, this);
}, this); // save these arguments
this._boundPointerEvents = events;
};
proto._unbindPostStartEvents = function () {
// check for _boundEvents, in case dragEnd triggered twice (old IE8 bug)
if (!this._boundPointerEvents) {
return;
}
this._boundPointerEvents.forEach(function (eventName) {
window.removeEventListener(eventName, this);
}, this);
delete this._boundPointerEvents;
}; // ----- move event ----- //
proto.onmousemove = function (event) {
this._pointerMove(event, event);
};
proto.onpointermove = function (event) {
if (event.pointerId == this.pointerIdentifier) {
this._pointerMove(event, event);
}
};
proto.ontouchmove = function (event) {
var touch = this.getTouch(event.changedTouches);
if (touch) {
this._pointerMove(event, touch);
}
};
/**
* pointer move
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
proto._pointerMove = function (event, pointer) {
this.pointerMove(event, pointer);
}; // public
proto.pointerMove = function (event, pointer) {
this.emitEvent('pointerMove', [event, pointer]);
}; // ----- end event ----- //
proto.onmouseup = function (event) {
this._pointerUp(event, event);
};
proto.onpointerup = function (event) {
if (event.pointerId == this.pointerIdentifier) {
this._pointerUp(event, event);
}
};
proto.ontouchend = function (event) {
var touch = this.getTouch(event.changedTouches);
if (touch) {
this._pointerUp(event, touch);
}
};
/**
* pointer up
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
proto._pointerUp = function (event, pointer) {
this._pointerDone();
this.pointerUp(event, pointer);
}; // public
proto.pointerUp = function (event, pointer) {
this.emitEvent('pointerUp', [event, pointer]);
}; // ----- pointer done ----- //
// triggered on pointer up & pointer cancel
proto._pointerDone = function () {
// reset properties
this.isPointerDown = false;
delete this.pointerIdentifier; // remove events
this._unbindPostStartEvents();
this.pointerDone();
};
proto.pointerDone = NO_OP; // ----- pointer cancel ----- //
proto.onpointercancel = function (event) {
if (event.pointerId == this.pointerIdentifier) {
this._pointerCancel(event, event);
}
};
proto.ontouchcancel = function (event) {
var touch = this.getTouch(event.changedTouches);
if (touch) {
this._pointerCancel(event, touch);
}
};
/**
* pointer cancel
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
proto._pointerCancel = function (event, pointer) {
this._pointerDone();
this.pointerCancel(event, pointer);
}; // public
proto.pointerCancel = function (event, pointer) {
this.emitEvent('pointerCancel', [event, pointer]);
}; // ----- ----- //
// utility function for getting x/y coords from event
Unipointer.getPointerPoint = function (pointer) {
return {
x: pointer.pageX,
y: pointer.pageY
};
}; // ----- ----- //