interactjs
Version:
Drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)
123 lines (102 loc) • 3.63 kB
JavaScript
const scope = require('../scope');
const utils = require('./index');
const finder = {
methodOrder: [ 'simulationResume', 'mouseOrPen', 'hasPointer', 'idle' ],
search: function (pointer, eventType, eventTarget) {
const pointerType = utils.getPointerType(pointer);
const pointerId = utils.getPointerId(pointer);
const details = { pointer, pointerId, pointerType, eventType, eventTarget };
for (const method of finder.methodOrder) {
const interaction = finder[method](details);
if (interaction) {
return interaction;
}
}
},
// try to resume simulation with a new pointer
simulationResume: function ({ pointerType, eventType, eventTarget }) {
if (!/down|start/i.test(eventType)) {
return null;
}
for (const interaction of scope.interactions) {
let element = eventTarget;
if (interaction.simulation && interaction.simulation.allowResume
&& (interaction.pointerType === pointerType)) {
while (element) {
// if the element is the interaction element
if (element === interaction.element) {
return interaction;
}
element = utils.parentNode(element);
}
}
}
return null;
},
// if it's a mouse or pen interaction
mouseOrPen: function ({ pointerId, pointerType, eventType }) {
if (pointerType !== 'mouse' && pointerType !== 'pen') {
return null;
}
let firstNonActive;
for (const interaction of scope.interactions) {
if (interaction.pointerType === pointerType) {
// if it's a down event, skip interactions with running simulations
if (interaction.simulation && !utils.contains(interaction.pointerIds, pointerId)) { continue; }
// if the interaction is active, return it immediately
if (interaction.interacting()) {
return interaction;
}
// otherwise save it and look for another active interaction
else if (!firstNonActive) {
firstNonActive = interaction;
}
}
}
// if no active mouse interaction was found use the first inactive mouse
// interaction
if (firstNonActive) {
return firstNonActive;
}
// find any mouse or pen interaction.
// ignore the interaction if the eventType is a *down, and a simulation
// is active
for (const interaction of scope.interactions) {
if (interaction.pointerType === pointerType && !(/down/i.test(eventType) && interaction.simulation)) {
return interaction;
}
}
return null;
},
// get interaction that has this pointer
hasPointer: function ({ pointerId }) {
for (const interaction of scope.interactions) {
if (utils.contains(interaction.pointerIds, pointerId)) {
return interaction;
}
}
},
// get first idle interaction with a matching pointerType
idle: function ({ pointerType }) {
for (const interaction of scope.interactions) {
// if there's already a pointer held down
if (interaction.pointerIds.length === 1) {
const target = interaction.target;
// don't add this pointer if there is a target interactable and it
// isn't gesturable
if (target && !target.options.gesture.enabled) {
continue;
}
}
// maximum of 2 pointers per interaction
else if (interaction.pointerIds.length >= 2) {
continue;
}
if (!interaction.interacting() && (pointerType === interaction.pointerType)) {
return interaction;
}
}
return null;
},
};
module.exports = finder;