import * as utils from '@interactjs/utils';
import InteractEvent from '@interactjs/core/InteractEvent';
function init (scope) {
const {
actions,
Interactable,
interactions,
defaults,
} = scope;
const gesture = {
defaults: {
},
checker: function (pointer, event, interactable, element, interaction) {
if (interaction.pointers.length >= 2) {
return { name: 'gesture' };
}
return null;
},
getCursor: function () {
return '';
},
};
/**
* ```js
* interact(element).gesturable({
* onstart: function (event) {},
* onmove : function (event) {},
* onend : function (event) {},
*
* // limit multiple gestures.
* // See the explanation in {@link Interactable.draggable} example
* max: Infinity,
* maxPerElement: 1,
* });
*
* var isGestureable = interact(element).gesturable();
* ```
*
* Gets or sets whether multitouch gestures can be performed on the target
*
* @param {boolean | object} [options] true/false or An object with event
* listeners to be fired on gesture events (makes the Interactable gesturable)
* @return {boolean | Interactable} A boolean indicating if this can be the
* target of gesture events, or this Interactable
*/
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;
};
interactions.signals.on('action-start', start);
interactions.signals.on('action-move', move);
interactions.signals.on('action-start', updateGestureProps);
interactions.signals.on('action-move', updateGestureProps);
interactions.signals.on('action-end', updateGestureProps);
interactions.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.arr.merge(actions.eventTypes, [
'gesturestart',
'gesturemove',
'gestureend',
]);
actions.methodDict.gesture = 'gesturable';
defaults.gesture = gesture.defaults;
}
function start ({ iEvent, interaction }) {
if (interaction.prepared.name !== 'gesture') { return; }
iEvent.ds = 0;
interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance;
interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle;
interaction.gesture.scale = 1;
}
function move ({ iEvent, interaction }) {
if (interaction.prepared.name !== 'gesture') { 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;
}
}
function updateGestureProps ({ interaction, iEvent, event, phase, deltaSource }) {
if (interaction.prepared.name !== 'gesture') { return; }
const pointers = interaction.pointers;
const starting = phase === 'start';
const ending = phase === 'end';
iEvent.touches = [pointers[0].pointer, pointers[1].pointer];
if (starting) {
iEvent.distance = utils.pointer.touchDistance(pointers, deltaSource);
iEvent.box = utils.pointer.touchBBox(pointers);
iEvent.scale = 1;
iEvent.ds = 0;
iEvent.angle = utils.pointer.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.pointer.touchDistance(pointers, deltaSource);
iEvent.box = utils.pointer.touchBBox(pointers);
iEvent.scale = iEvent.distance / interaction.gesture.startDistance;
iEvent.angle = utils.pointer.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);
iEvent.ds = iEvent.scale - interaction.gesture.prevScale;
iEvent.da = iEvent.angle - interaction.gesture.prevAngle;
}
}
export default { init };