UNPKG

interactjs

Version:

Drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE8+)

162 lines (131 loc) 4.78 kB
const actions = require('./base'); const utils = require('../utils'); const InteractEvent = require('../InteractEvent'); const Interactable = require('../Interactable'); const Interaction = require('../Interaction'); const defaultOptions = require('../defaultOptions'); const gesture = { defaults: { enabled : false, origin : null, restrict: null, }, checker: function (pointer, event, interactable, element, interaction) { if (interaction.pointerIds.length >= 2) { return { name: 'gesture' }; } return null; }, getCursor: function () { return ''; }, }; InteractEvent.signals.on('new', function ({ iEvent, interaction }) { if (iEvent.type !== 'gesturestart') { return; } iEvent.ds = 0; interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance; interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle; interaction.gesture.scale = 1; }); InteractEvent.signals.on('new', function ({ iEvent, interaction }) { if (iEvent.type !== 'gesturemove') { return; } iEvent.ds = iEvent.scale - interaction.gesture.scale; interaction.target.fire(iEvent); interaction.gesture.prevAngle = iEvent.angle; interaction.gesture.prevDistance = iEvent.distance; if (iEvent.scale !== Infinity && iEvent.scale !== null && iEvent.scale !== undefined && !isNaN(iEvent.scale)) { interaction.gesture.scale = iEvent.scale; } }); /*\ * Interactable.gesturable [ method ] * * Gets or sets whether multitouch gestures can be performed on the * Interactable's element * = (boolean) Indicates if this can be the target of gesture events | var isGestureable = interact(element).gesturable(); * or - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable) = (object) this Interactable | interact(element).gesturable({ | onstart: function (event) {}, | onmove : function (event) {}, | onend : function (event) {}, | | // limit multiple gestures. | // See the explanation in @Interactable.draggable example | max: Infinity, | maxPerElement: 1, | }); \*/ Interactable.prototype.gesturable = function (options) { if (utils.is.object(options)) { this.options.gesture.enabled = options.enabled === false? false: true; this.setPerAction('gesture', options); this.setOnEvents('gesture', options); return this; } if (utils.is.bool(options)) { this.options.gesture.enabled = options; if (!options) { this.ongesturestart = this.ongesturestart = this.ongestureend = null; } return this; } return this.options.gesture; }; InteractEvent.signals.on('set-delta', function ({ interaction, iEvent, action, event, starting, ending, deltaSource }) { if (action !== 'gesture') { return; } const pointers = interaction.pointers; iEvent.touches = [pointers[0], pointers[1]]; if (starting) { iEvent.distance = utils.touchDistance(pointers, deltaSource); iEvent.box = utils.touchBBox(pointers); iEvent.scale = 1; iEvent.ds = 0; iEvent.angle = utils.touchAngle(pointers, undefined, deltaSource); iEvent.da = 0; } else if (ending || event instanceof InteractEvent) { iEvent.distance = interaction.prevEvent.distance; iEvent.box = interaction.prevEvent.box; iEvent.scale = interaction.prevEvent.scale; iEvent.ds = iEvent.scale - 1; iEvent.angle = interaction.prevEvent.angle; iEvent.da = iEvent.angle - interaction.gesture.startAngle; } else { iEvent.distance = utils.touchDistance(pointers, deltaSource); iEvent.box = utils.touchBBox(pointers); iEvent.scale = iEvent.distance / interaction.gesture.startDistance; iEvent.angle = utils.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource); iEvent.ds = iEvent.scale - interaction.gesture.prevScale; iEvent.da = iEvent.angle - interaction.gesture.prevAngle; } }); Interaction.signals.on('new', function (interaction) { interaction.gesture = { start: { x: 0, y: 0 }, startDistance: 0, // distance between two touches of touchStart prevDistance : 0, distance : 0, scale: 1, // gesture.distance / gesture.startDistance startAngle: 0, // angle of line joining two touches prevAngle : 0, // angle of the previous gesture event }; }); actions.gesture = gesture; actions.names.push('gesture'); utils.merge(Interactable.eventTypes, [ 'gesturestart', 'gesturemove', 'gestureend', ]); actions.methodDict.gesture = 'gesturable'; defaultOptions.gesture = gesture.defaults; module.exports = gesture;