1 | const actions = require('./base');
|
2 | const utils = require('../utils');
|
3 | const InteractEvent = require('../InteractEvent');
|
4 | const Interactable = require('../Interactable');
|
5 | const Interaction = require('../Interaction');
|
6 | const defaultOptions = require('../defaultOptions');
|
7 |
|
8 | const gesture = {
|
9 | defaults: {
|
10 | enabled : false,
|
11 | origin : null,
|
12 | restrict: null,
|
13 | },
|
14 |
|
15 | checker: function (pointer, event, interactable, element, interaction) {
|
16 | if (interaction.pointerIds.length >= 2) {
|
17 | return { name: 'gesture' };
|
18 | }
|
19 |
|
20 | return null;
|
21 | },
|
22 |
|
23 | getCursor: function () {
|
24 | return '';
|
25 | },
|
26 | };
|
27 |
|
28 | InteractEvent.signals.on('new', function ({ iEvent, interaction }) {
|
29 | if (iEvent.type !== 'gesturestart') { return; }
|
30 | iEvent.ds = 0;
|
31 |
|
32 | interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance;
|
33 | interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle;
|
34 | interaction.gesture.scale = 1;
|
35 | });
|
36 |
|
37 | InteractEvent.signals.on('new', function ({ iEvent, interaction }) {
|
38 | if (iEvent.type !== 'gesturemove') { return; }
|
39 |
|
40 | iEvent.ds = iEvent.scale - interaction.gesture.scale;
|
41 |
|
42 | interaction.target.fire(iEvent);
|
43 |
|
44 | interaction.gesture.prevAngle = iEvent.angle;
|
45 | interaction.gesture.prevDistance = iEvent.distance;
|
46 |
|
47 | if (iEvent.scale !== Infinity
|
48 | && iEvent.scale !== null
|
49 | && iEvent.scale !== undefined
|
50 | && !isNaN(iEvent.scale)) {
|
51 |
|
52 | interaction.gesture.scale = iEvent.scale;
|
53 | }
|
54 | });
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 | Interactable.prototype.gesturable = function (options) {
|
80 | if (utils.is.object(options)) {
|
81 | this.options.gesture.enabled = options.enabled === false? false: true;
|
82 | this.setPerAction('gesture', options);
|
83 | this.setOnEvents('gesture', options);
|
84 |
|
85 | return this;
|
86 | }
|
87 |
|
88 | if (utils.is.bool(options)) {
|
89 | this.options.gesture.enabled = options;
|
90 |
|
91 | if (!options) {
|
92 | this.ongesturestart = this.ongesturestart = this.ongestureend = null;
|
93 | }
|
94 |
|
95 | return this;
|
96 | }
|
97 |
|
98 | return this.options.gesture;
|
99 | };
|
100 |
|
101 | InteractEvent.signals.on('set-delta', function ({ interaction, iEvent, action, event, starting, ending, deltaSource }) {
|
102 | if (action !== 'gesture') { return; }
|
103 |
|
104 | const pointers = interaction.pointers;
|
105 |
|
106 | iEvent.touches = [pointers[0], pointers[1]];
|
107 |
|
108 | if (starting) {
|
109 | iEvent.distance = utils.touchDistance(pointers, deltaSource);
|
110 | iEvent.box = utils.touchBBox(pointers);
|
111 | iEvent.scale = 1;
|
112 | iEvent.ds = 0;
|
113 | iEvent.angle = utils.touchAngle(pointers, undefined, deltaSource);
|
114 | iEvent.da = 0;
|
115 | }
|
116 | else if (ending || event instanceof InteractEvent) {
|
117 | iEvent.distance = interaction.prevEvent.distance;
|
118 | iEvent.box = interaction.prevEvent.box;
|
119 | iEvent.scale = interaction.prevEvent.scale;
|
120 | iEvent.ds = iEvent.scale - 1;
|
121 | iEvent.angle = interaction.prevEvent.angle;
|
122 | iEvent.da = iEvent.angle - interaction.gesture.startAngle;
|
123 | }
|
124 | else {
|
125 | iEvent.distance = utils.touchDistance(pointers, deltaSource);
|
126 | iEvent.box = utils.touchBBox(pointers);
|
127 | iEvent.scale = iEvent.distance / interaction.gesture.startDistance;
|
128 | iEvent.angle = utils.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);
|
129 |
|
130 | iEvent.ds = iEvent.scale - interaction.gesture.prevScale;
|
131 | iEvent.da = iEvent.angle - interaction.gesture.prevAngle;
|
132 | }
|
133 | });
|
134 |
|
135 | Interaction.signals.on('new', function (interaction) {
|
136 | interaction.gesture = {
|
137 | start: { x: 0, y: 0 },
|
138 |
|
139 | startDistance: 0,
|
140 | prevDistance : 0,
|
141 | distance : 0,
|
142 |
|
143 | scale: 1,
|
144 |
|
145 | startAngle: 0,
|
146 | prevAngle : 0,
|
147 | };
|
148 | });
|
149 |
|
150 | actions.gesture = gesture;
|
151 | actions.names.push('gesture');
|
152 | utils.merge(Interactable.eventTypes, [
|
153 | 'gesturestart',
|
154 | 'gesturemove',
|
155 | 'gestureend',
|
156 | ]);
|
157 | actions.methodDict.gesture = 'gesturable';
|
158 |
|
159 | defaultOptions.gesture = gesture.defaults;
|
160 |
|
161 | module.exports = gesture;
|