interactjs
Version:
Drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE8+)
239 lines (205 loc) • 6.17 kB
JavaScript
const browser = require('./utils/browser');
const events = require('./utils/events');
const utils = require('./utils');
const scope = require('./scope');
const Interactable = require('./Interactable');
const Interaction = require('./Interaction');
const globalEvents = {};
/*\
* interact
[ method ]
*
* The methods of this variable can be used to set elements as
* interactables and also to change various default settings.
*
* Calling it as a function and passing an element or a valid CSS selector
* string returns an Interactable object which has various methods to
* configure it.
*
- element (Element | string) The HTML or SVG Element to interact with or CSS selector
= (object) An @Interactable
*
> Usage
| interact('#draggable').draggable(true);
|
| var rectables = interact('rect');
| rectables
| .gesturable(true)
| .on('gesturemove', function (event) {
| // ...
| });
\*/
function interact (element, options) {
let interactable = scope.interactables.get(element, options);
if (!interactable) {
interactable = new Interactable(element, options);
interactable.events.global = globalEvents;
}
return interactable;
}
/*\
* interact.isSet
[ method ]
*
* Check if an element has been set
- element (Element) The Element being searched for
= (boolean) Indicates if the element or CSS selector was previously passed to interact
\*/
interact.isSet = function (element, options) {
return scope.interactables.indexOfElement(element, options && options.context) !== -1;
};
/*\
* interact.on
[ method ]
*
* Adds a global listener for an InteractEvent or adds a DOM event to
* `document`
*
- type (string | array | object) The types of events to listen for
- listener (function) The function event (s)
- options (object | boolean) #optional options object or useCapture flag for addEventListener
= (object) interact
\*/
interact.on = function (type, listener, options) {
if (utils.is.string(type) && type.search(' ') !== -1) {
type = type.trim().split(/ +/);
}
if (utils.is.array(type)) {
for (const eventType of type) {
interact.on(eventType, listener, options);
}
return interact;
}
if (utils.is.object(type)) {
for (const prop in type) {
interact.on(prop, type[prop], listener);
}
return interact;
}
// if it is an InteractEvent type, add listener to globalEvents
if (utils.contains(Interactable.eventTypes, type)) {
// if this type of event was never bound
if (!globalEvents[type]) {
globalEvents[type] = [listener];
}
else {
globalEvents[type].push(listener);
}
}
// If non InteractEvent type, addEventListener to document
else {
events.add(scope.document, type, listener, { options });
}
return interact;
};
/*\
* interact.off
[ method ]
*
* Removes a global InteractEvent listener or DOM event from `document`
*
- type (string | array | object) The types of events that were listened for
- listener (function) The listener function to be removed
- options (object | boolean) #optional options object or useCapture flag for removeEventListener
= (object) interact
\*/
interact.off = function (type, listener, options) {
if (utils.is.string(type) && type.search(' ') !== -1) {
type = type.trim().split(/ +/);
}
if (utils.is.array(type)) {
for (const eventType of type) {
interact.off(eventType, listener, options);
}
return interact;
}
if (utils.is.object(type)) {
for (const prop in type) {
interact.off(prop, type[prop], listener);
}
return interact;
}
if (!utils.contains(Interactable.eventTypes, type)) {
events.remove(scope.document, type, listener, options);
}
else {
let index;
if (type in globalEvents
&& (index = utils.indexOf(globalEvents[type], listener)) !== -1) {
globalEvents[type].splice(index, 1);
}
}
return interact;
};
/*\
* interact.debug
[ method ]
*
* Returns an object which exposes internal data
= (object) An object with properties that outline the current state and expose internal functions and variables
\*/
interact.debug = function () {
return scope;
};
// expose the functions used to calculate multi-touch properties
interact.getPointerAverage = utils.pointerAverage;
interact.getTouchBBox = utils.touchBBox;
interact.getTouchDistance = utils.touchDistance;
interact.getTouchAngle = utils.touchAngle;
interact.getElementRect = utils.getElementRect;
interact.getElementClientRect = utils.getElementClientRect;
interact.matchesSelector = utils.matchesSelector;
interact.closest = utils.closest;
/*\
* interact.supportsTouch
[ method ]
*
= (boolean) Whether or not the browser supports touch input
\*/
interact.supportsTouch = function () {
return browser.supportsTouch;
};
/*\
* interact.supportsPointerEvent
[ method ]
*
= (boolean) Whether or not the browser supports PointerEvents
\*/
interact.supportsPointerEvent = function () {
return browser.supportsPointerEvent;
};
/*\
* interact.stop
[ method ]
*
* Cancels all interactions (end events are not fired)
*
- event (Event) An event on which to call preventDefault()
= (object) interact
\*/
interact.stop = function (event) {
for (let i = scope.interactions.length - 1; i >= 0; i--) {
scope.interactions[i].stop(event);
}
return interact;
};
/*\
* interact.pointerMoveTolerance
[ method ]
* Returns or sets the distance the pointer must be moved before an action
* sequence occurs. This also affects tolerance for tap events.
*
- newValue (number) #optional The movement from the start position must be greater than this value
= (number | Interactable) The current setting or interact
\*/
interact.pointerMoveTolerance = function (newValue) {
if (utils.is.number(newValue)) {
Interaction.pointerMoveTolerance = newValue;
return this;
}
return Interaction.pointerMoveTolerance;
};
interact.addDocument = scope.addDocument;
interact.removeDocument = scope.removeDocument;
scope.interact = interact;
module.exports = interact;