UNPKG

4.78 kBJavaScriptView Raw
1const actions = require('./base');
2const utils = require('../utils');
3const InteractEvent = require('../InteractEvent');
4/** @lends Interactable */
5const Interactable = require('../Interactable');
6const Interaction = require('../Interaction');
7const defaultOptions = require('../defaultOptions');
8
9const drag = {
10 defaults: {
11 enabled : false,
12 mouseButtons: null,
13
14 origin : null,
15 snap : null,
16 restrict : null,
17 inertia : null,
18 autoScroll: null,
19
20 startAxis : 'xy',
21 lockAxis : 'xy',
22 },
23
24 checker: function (pointer, event, interactable) {
25 const dragOptions = interactable.options.drag;
26
27 return dragOptions.enabled
28 ? { name: 'drag', axis: (dragOptions.lockAxis === 'start'
29 ? dragOptions.startAxis
30 : dragOptions.lockAxis)}
31 : null;
32 },
33
34 getCursor: function () {
35 return 'move';
36 },
37};
38
39Interaction.signals.on('before-action-move', function ({ interaction }) {
40 if (interaction.prepared.name !== 'drag') { return; }
41
42 const axis = interaction.prepared.axis;
43
44 if (axis === 'x') {
45 interaction.curCoords.page.y = interaction.startCoords.page.y;
46 interaction.curCoords.client.y = interaction.startCoords.client.y;
47
48 interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vx);
49 interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vx);
50 interaction.pointerDelta.client.vy = 0;
51 interaction.pointerDelta.page.vy = 0;
52 }
53 else if (axis === 'y') {
54 interaction.curCoords.page.x = interaction.startCoords.page.x;
55 interaction.curCoords.client.x = interaction.startCoords.client.x;
56
57 interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vy);
58 interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vy);
59 interaction.pointerDelta.client.vx = 0;
60 interaction.pointerDelta.page.vx = 0;
61 }
62});
63
64// dragmove
65InteractEvent.signals.on('new', function ({ iEvent, interaction }) {
66 if (iEvent.type !== 'dragmove') { return; }
67
68 const axis = interaction.prepared.axis;
69
70 if (axis === 'x') {
71 iEvent.pageY = interaction.startCoords.page.y;
72 iEvent.clientY = interaction.startCoords.client.y;
73 iEvent.dy = 0;
74 }
75 else if (axis === 'y') {
76 iEvent.pageX = interaction.startCoords.page.x;
77 iEvent.clientX = interaction.startCoords.client.x;
78 iEvent.dx = 0;
79 }
80});
81
82/**
83 * ```js
84 * interact(element).draggable({
85 * onstart: function (event) {},
86 * onmove : function (event) {},
87 * onend : function (event) {},
88 *
89 * // the axis in which the first movement must be
90 * // for the drag sequence to start
91 * // 'xy' by default - any direction
92 * startAxis: 'x' || 'y' || 'xy',
93 *
94 * // 'xy' by default - don't restrict to one axis (move in any direction)
95 * // 'x' or 'y' to restrict movement to either axis
96 * // 'start' to restrict movement to the axis the drag started in
97 * lockAxis: 'x' || 'y' || 'xy' || 'start',
98 *
99 * // max number of drags that can happen concurrently
100 * // with elements of this Interactable. Infinity by default
101 * max: Infinity,
102 *
103 * // max number of drags that can target the same element+Interactable
104 * // 1 by default
105 * maxPerElement: 2
106 * });
107 *
108 * var isDraggable = interact('element').draggable(); // true
109 * ```
110 *
111 * Get or set whether drag actions can be performed on the target
112 *
113 * @param {boolean | object} [options] true/false or An object with event
114 * listeners to be fired on drag events (object makes the Interactable
115 * draggable)
116 * @return {boolean | Interactable} boolean indicating if this can be the
117 * target of drag events, or this Interctable
118 */
119Interactable.prototype.draggable = function (options) {
120 if (utils.is.object(options)) {
121 this.options.drag.enabled = options.enabled === false? false: true;
122 this.setPerAction('drag', options);
123 this.setOnEvents('drag', options);
124
125 if (/^(xy|x|y|start)$/.test(options.lockAxis)) {
126 this.options.drag.lockAxis = options.lockAxis;
127 }
128 if (/^(xy|x|y)$/.test(options.startAxis)) {
129 this.options.drag.startAxis = options.startAxis;
130 }
131
132 return this;
133 }
134
135 if (utils.is.bool(options)) {
136 this.options.drag.enabled = options;
137
138 if (!options) {
139 this.ondragstart = this.ondragstart = this.ondragend = null;
140 }
141
142 return this;
143 }
144
145 return this.options.drag;
146};
147
148actions.drag = drag;
149actions.names.push('drag');
150utils.merge(Interactable.eventTypes, [
151 'dragstart',
152 'dragmove',
153 'draginertiastart',
154 'draginertiaresume',
155 'dragend',
156]);
157actions.methodDict.drag = 'draggable';
158
159defaultOptions.drag = drag.defaults;
160
161module.exports = drag;