|
525
|
1 |
/* |
|
|
2 |
YUI 3.10.3 (build 2fb5187) |
|
|
3 |
Copyright 2013 Yahoo! Inc. All rights reserved. |
|
|
4 |
Licensed under the BSD License. |
|
|
5 |
http://yuilibrary.com/license/ |
|
|
6 |
*/ |
|
|
7 |
|
|
|
8 |
YUI.add('dd-constrain', function (Y, NAME) { |
|
|
9 |
|
|
|
10 |
|
|
|
11 |
/** |
|
|
12 |
* The Drag & Drop Utility allows you to create a draggable interface efficiently, |
|
|
13 |
* buffering you from browser-level abnormalities and enabling you to focus on the interesting |
|
|
14 |
* logic surrounding your particular implementation. This component enables you to create a |
|
|
15 |
* variety of standard draggable objects with just a few lines of code and then, |
|
|
16 |
* using its extensive API, add your own specific implementation logic. |
|
|
17 |
* @module dd |
|
|
18 |
* @main dd |
|
|
19 |
* @submodule dd-constrain |
|
|
20 |
*/ |
|
|
21 |
/** |
|
|
22 |
* Plugin for the dd-drag module to add the constraining methods to it. |
|
|
23 |
* It supports constraining to a node or viewport. It supports tick based moves and XY axis constraints. |
|
|
24 |
* @class DDConstrained |
|
|
25 |
* @extends Base |
|
|
26 |
* @constructor |
|
|
27 |
* @namespace Plugin |
|
|
28 |
*/ |
|
|
29 |
|
|
|
30 |
var DRAG_NODE = 'dragNode', |
|
|
31 |
OFFSET_HEIGHT = 'offsetHeight', |
|
|
32 |
OFFSET_WIDTH = 'offsetWidth', |
|
|
33 |
HOST = 'host', |
|
|
34 |
TICK_X_ARRAY = 'tickXArray', |
|
|
35 |
TICK_Y_ARRAY = 'tickYArray', |
|
|
36 |
DDM = Y.DD.DDM, |
|
|
37 |
TOP = 'top', |
|
|
38 |
RIGHT = 'right', |
|
|
39 |
BOTTOM = 'bottom', |
|
|
40 |
LEFT = 'left', |
|
|
41 |
VIEW = 'view', |
|
|
42 |
proto = null, |
|
|
43 |
|
|
|
44 |
/** |
|
|
45 |
* Fires when this node is aligned with the tickX value. |
|
|
46 |
* @event drag:tickAlignX |
|
|
47 |
* @param {EventFacade} event An Event Facade object |
|
|
48 |
* @type {CustomEvent} |
|
|
49 |
*/ |
|
|
50 |
EV_TICK_ALIGN_X = 'drag:tickAlignX', |
|
|
51 |
|
|
|
52 |
/** |
|
|
53 |
* Fires when this node is aligned with the tickY value. |
|
|
54 |
* @event drag:tickAlignY |
|
|
55 |
* @param {EventFacade} event An Event Facade object |
|
|
56 |
* @type {CustomEvent} |
|
|
57 |
*/ |
|
|
58 |
EV_TICK_ALIGN_Y = 'drag:tickAlignY', |
|
|
59 |
|
|
|
60 |
C = function() { |
|
|
61 |
this._lazyAddAttrs = false; |
|
|
62 |
C.superclass.constructor.apply(this, arguments); |
|
|
63 |
}; |
|
|
64 |
|
|
|
65 |
C.NAME = 'ddConstrained'; |
|
|
66 |
/** |
|
|
67 |
* The Constrained instance will be placed on the Drag instance under the con namespace. |
|
|
68 |
* @property NS |
|
|
69 |
* @default con |
|
|
70 |
* @readonly |
|
|
71 |
* @protected |
|
|
72 |
* @static |
|
|
73 |
* @type {String} |
|
|
74 |
*/ |
|
|
75 |
C.NS = 'con'; |
|
|
76 |
|
|
|
77 |
C.ATTRS = { |
|
|
78 |
host: { |
|
|
79 |
}, |
|
|
80 |
/** |
|
|
81 |
* Stick the drag movement to the X-Axis. Default: false |
|
|
82 |
* @attribute stickX |
|
|
83 |
* @type Boolean |
|
|
84 |
*/ |
|
|
85 |
stickX: { |
|
|
86 |
value: false |
|
|
87 |
}, |
|
|
88 |
/** |
|
|
89 |
* Stick the drag movement to the Y-Axis |
|
|
90 |
* @type Boolean |
|
|
91 |
* @attribute stickY |
|
|
92 |
*/ |
|
|
93 |
stickY: { |
|
|
94 |
value: false |
|
|
95 |
}, |
|
|
96 |
/** |
|
|
97 |
* The X tick offset the drag node should snap to on each drag move. False for no ticks. Default: false |
|
|
98 |
* @type Number/false |
|
|
99 |
* @attribute tickX |
|
|
100 |
*/ |
|
|
101 |
tickX: { |
|
|
102 |
value: false |
|
|
103 |
}, |
|
|
104 |
/** |
|
|
105 |
* The Y tick offset the drag node should snap to on each drag move. False for no ticks. Default: false |
|
|
106 |
* @type Number/false |
|
|
107 |
* @attribute tickY |
|
|
108 |
*/ |
|
|
109 |
tickY: { |
|
|
110 |
value: false |
|
|
111 |
}, |
|
|
112 |
/** |
|
|
113 |
* An array of page coordinates to use as X ticks for drag movement. |
|
|
114 |
* @type Array |
|
|
115 |
* @attribute tickXArray |
|
|
116 |
*/ |
|
|
117 |
tickXArray: { |
|
|
118 |
value: false |
|
|
119 |
}, |
|
|
120 |
/** |
|
|
121 |
* An array of page coordinates to use as Y ticks for drag movement. |
|
|
122 |
* @type Array |
|
|
123 |
* @attribute tickYArray |
|
|
124 |
*/ |
|
|
125 |
tickYArray: { |
|
|
126 |
value: false |
|
|
127 |
}, |
|
|
128 |
/** |
|
|
129 |
* CSS style string for the gutter of a region (supports negative values): '5 0' |
|
|
130 |
* (sets top and bottom to 5px, left and right to 0px), '1 2 3 4' (top 1px, right 2px, bottom 3px, left 4px) |
|
|
131 |
* @attribute gutter |
|
|
132 |
* @type String |
|
|
133 |
*/ |
|
|
134 |
gutter: { |
|
|
135 |
value: '0', |
|
|
136 |
setter: function(gutter) { |
|
|
137 |
return Y.DD.DDM.cssSizestoObject(gutter); |
|
|
138 |
} |
|
|
139 |
}, |
|
|
140 |
/** |
|
|
141 |
* Will attempt to constrain the drag node to the boundaries. Arguments:<br> |
|
|
142 |
* 'view': Contrain to Viewport<br> |
|
|
143 |
* '#selector_string': Constrain to this node<br> |
|
|
144 |
* '{Region Object}': An Object Literal containing a valid region (top, right, bottom, left) of page positions |
|
|
145 |
* @attribute constrain |
|
|
146 |
* @type {String/Object/Node} |
|
|
147 |
*/ |
|
|
148 |
constrain: { |
|
|
149 |
value: VIEW, |
|
|
150 |
setter: function(con) { |
|
|
151 |
var node = Y.one(con); |
|
|
152 |
if (node) { |
|
|
153 |
con = node; |
|
|
154 |
} |
|
|
155 |
return con; |
|
|
156 |
} |
|
|
157 |
}, |
|
|
158 |
/** |
|
|
159 |
* An Object Literal containing a valid region (top, right, bottom, left) of page positions to constrain the drag node to. |
|
|
160 |
* @deprecated |
|
|
161 |
* @attribute constrain2region |
|
|
162 |
* @type Object |
|
|
163 |
*/ |
|
|
164 |
constrain2region: { |
|
|
165 |
setter: function(r) { |
|
|
166 |
return this.set('constrain', r); |
|
|
167 |
} |
|
|
168 |
}, |
|
|
169 |
/** |
|
|
170 |
* Will attempt to constrain the drag node to the boundaries of this node. |
|
|
171 |
* @deprecated |
|
|
172 |
* @attribute constrain2node |
|
|
173 |
* @type Object |
|
|
174 |
*/ |
|
|
175 |
constrain2node: { |
|
|
176 |
setter: function(n) { |
|
|
177 |
return this.set('constrain', Y.one(n)); |
|
|
178 |
} |
|
|
179 |
}, |
|
|
180 |
/** |
|
|
181 |
* Will attempt to constrain the drag node to the boundaries of the viewport region. |
|
|
182 |
* @deprecated |
|
|
183 |
* @attribute constrain2view |
|
|
184 |
* @type Object |
|
|
185 |
*/ |
|
|
186 |
constrain2view: { |
|
|
187 |
setter: function() { |
|
|
188 |
return this.set('constrain', VIEW); |
|
|
189 |
} |
|
|
190 |
}, |
|
|
191 |
/** |
|
|
192 |
* Should the region be cached for performace. Default: true |
|
|
193 |
* @attribute cacheRegion |
|
|
194 |
* @type Boolean |
|
|
195 |
*/ |
|
|
196 |
cacheRegion: { |
|
|
197 |
value: true |
|
|
198 |
} |
|
|
199 |
}; |
|
|
200 |
|
|
|
201 |
proto = { |
|
|
202 |
_lastTickXFired: null, |
|
|
203 |
_lastTickYFired: null, |
|
|
204 |
|
|
|
205 |
initializer: function() { |
|
|
206 |
this._createEvents(); |
|
|
207 |
|
|
|
208 |
this._eventHandles = [ |
|
|
209 |
this.get(HOST).on('drag:end', Y.bind(this._handleEnd, this)), |
|
|
210 |
this.get(HOST).on('drag:start', Y.bind(this._handleStart, this)), |
|
|
211 |
this.get(HOST).after('drag:align', Y.bind(this.align, this)), |
|
|
212 |
this.get(HOST).after('drag:drag', Y.bind(this.drag, this)) |
|
|
213 |
]; |
|
|
214 |
}, |
|
|
215 |
destructor: function() { |
|
|
216 |
Y.Array.each( |
|
|
217 |
this._eventHandles, |
|
|
218 |
function(handle) { |
|
|
219 |
handle.detach(); |
|
|
220 |
} |
|
|
221 |
); |
|
|
222 |
|
|
|
223 |
this._eventHandles.length = 0; |
|
|
224 |
}, |
|
|
225 |
/** |
|
|
226 |
* This method creates all the events for this Event Target and publishes them so we get Event Bubbling. |
|
|
227 |
* @private |
|
|
228 |
* @method _createEvents |
|
|
229 |
*/ |
|
|
230 |
_createEvents: function() { |
|
|
231 |
var ev = [ |
|
|
232 |
EV_TICK_ALIGN_X, |
|
|
233 |
EV_TICK_ALIGN_Y |
|
|
234 |
]; |
|
|
235 |
|
|
|
236 |
Y.Array.each(ev, function(v) { |
|
|
237 |
this.publish(v, { |
|
|
238 |
type: v, |
|
|
239 |
emitFacade: true, |
|
|
240 |
bubbles: true, |
|
|
241 |
queuable: false, |
|
|
242 |
prefix: 'drag' |
|
|
243 |
}); |
|
|
244 |
}, this); |
|
|
245 |
}, |
|
|
246 |
/** |
|
|
247 |
* Fires on drag:end |
|
|
248 |
* @private |
|
|
249 |
* @method _handleEnd |
|
|
250 |
*/ |
|
|
251 |
_handleEnd: function() { |
|
|
252 |
this._lastTickYFired = null; |
|
|
253 |
this._lastTickXFired = null; |
|
|
254 |
}, |
|
|
255 |
/** |
|
|
256 |
* Fires on drag:start and clears the _regionCache |
|
|
257 |
* @private |
|
|
258 |
* @method _handleStart |
|
|
259 |
*/ |
|
|
260 |
_handleStart: function() { |
|
|
261 |
this.resetCache(); |
|
|
262 |
}, |
|
|
263 |
/** |
|
|
264 |
* Store a cache of the region that we are constraining to |
|
|
265 |
* @private |
|
|
266 |
* @property _regionCache |
|
|
267 |
* @type Object |
|
|
268 |
*/ |
|
|
269 |
_regionCache: null, |
|
|
270 |
/** |
|
|
271 |
* Get's the region and caches it, called from window.resize and when the cache is null |
|
|
272 |
* @private |
|
|
273 |
* @method _cacheRegion |
|
|
274 |
*/ |
|
|
275 |
_cacheRegion: function() { |
|
|
276 |
this._regionCache = this.get('constrain').get('region'); |
|
|
277 |
}, |
|
|
278 |
/** |
|
|
279 |
* Reset the internal region cache. |
|
|
280 |
* @method resetCache |
|
|
281 |
*/ |
|
|
282 |
resetCache: function() { |
|
|
283 |
this._regionCache = null; |
|
|
284 |
}, |
|
|
285 |
/** |
|
|
286 |
* Standardizes the 'constraint' attribute |
|
|
287 |
* @private |
|
|
288 |
* @method _getConstraint |
|
|
289 |
*/ |
|
|
290 |
_getConstraint: function() { |
|
|
291 |
var con = this.get('constrain'), |
|
|
292 |
g = this.get('gutter'), |
|
|
293 |
region; |
|
|
294 |
|
|
|
295 |
if (con) { |
|
|
296 |
if (con instanceof Y.Node) { |
|
|
297 |
if (!this._regionCache) { |
|
|
298 |
this._eventHandles.push(Y.on('resize', Y.bind(this._cacheRegion, this), Y.config.win)); |
|
|
299 |
this._cacheRegion(); |
|
|
300 |
} |
|
|
301 |
region = Y.clone(this._regionCache); |
|
|
302 |
if (!this.get('cacheRegion')) { |
|
|
303 |
this.resetCache(); |
|
|
304 |
} |
|
|
305 |
} else if (Y.Lang.isObject(con)) { |
|
|
306 |
region = Y.clone(con); |
|
|
307 |
} |
|
|
308 |
} |
|
|
309 |
if (!con || !region) { |
|
|
310 |
con = VIEW; |
|
|
311 |
} |
|
|
312 |
if (con === VIEW) { |
|
|
313 |
region = this.get(HOST).get(DRAG_NODE).get('viewportRegion'); |
|
|
314 |
} |
|
|
315 |
|
|
|
316 |
Y.Object.each(g, function(i, n) { |
|
|
317 |
if ((n === RIGHT) || (n === BOTTOM)) { |
|
|
318 |
region[n] -= i; |
|
|
319 |
} else { |
|
|
320 |
region[n] += i; |
|
|
321 |
} |
|
|
322 |
}); |
|
|
323 |
return region; |
|
|
324 |
}, |
|
|
325 |
|
|
|
326 |
/** |
|
|
327 |
* Get the active region: viewport, node, custom region |
|
|
328 |
* @method getRegion |
|
|
329 |
* @param {Boolean} inc Include the node's height and width |
|
|
330 |
* @return {Object} The active region. |
|
|
331 |
*/ |
|
|
332 |
getRegion: function(inc) { |
|
|
333 |
var r = {}, oh = null, ow = null, |
|
|
334 |
host = this.get(HOST); |
|
|
335 |
|
|
|
336 |
r = this._getConstraint(); |
|
|
337 |
|
|
|
338 |
if (inc) { |
|
|
339 |
oh = host.get(DRAG_NODE).get(OFFSET_HEIGHT); |
|
|
340 |
ow = host.get(DRAG_NODE).get(OFFSET_WIDTH); |
|
|
341 |
r[RIGHT] = r[RIGHT] - ow; |
|
|
342 |
r[BOTTOM] = r[BOTTOM] - oh; |
|
|
343 |
} |
|
|
344 |
return r; |
|
|
345 |
}, |
|
|
346 |
/** |
|
|
347 |
* Check if xy is inside a given region, if not change to it be inside. |
|
|
348 |
* @private |
|
|
349 |
* @method _checkRegion |
|
|
350 |
* @param {Array} _xy The XY to check if it's in the current region, if it isn't |
|
|
351 |
* inside the region, it will reset the xy array to be inside the region. |
|
|
352 |
* @return {Array} The new XY that is inside the region |
|
|
353 |
*/ |
|
|
354 |
_checkRegion: function(_xy) { |
|
|
355 |
var oxy = _xy, |
|
|
356 |
r = this.getRegion(), |
|
|
357 |
host = this.get(HOST), |
|
|
358 |
oh = host.get(DRAG_NODE).get(OFFSET_HEIGHT), |
|
|
359 |
ow = host.get(DRAG_NODE).get(OFFSET_WIDTH); |
|
|
360 |
|
|
|
361 |
if (oxy[1] > (r[BOTTOM] - oh)) { |
|
|
362 |
_xy[1] = (r[BOTTOM] - oh); |
|
|
363 |
} |
|
|
364 |
if (r[TOP] > oxy[1]) { |
|
|
365 |
_xy[1] = r[TOP]; |
|
|
366 |
|
|
|
367 |
} |
|
|
368 |
if (oxy[0] > (r[RIGHT] - ow)) { |
|
|
369 |
_xy[0] = (r[RIGHT] - ow); |
|
|
370 |
} |
|
|
371 |
if (r[LEFT] > oxy[0]) { |
|
|
372 |
_xy[0] = r[LEFT]; |
|
|
373 |
} |
|
|
374 |
|
|
|
375 |
return _xy; |
|
|
376 |
}, |
|
|
377 |
/** |
|
|
378 |
* Checks if the XY passed or the dragNode is inside the active region. |
|
|
379 |
* @method inRegion |
|
|
380 |
* @param {Array} xy Optional XY to check, if not supplied this.get('dragNode').getXY() is used. |
|
|
381 |
* @return {Boolean} True if the XY is inside the region, false otherwise. |
|
|
382 |
*/ |
|
|
383 |
inRegion: function(xy) { |
|
|
384 |
xy = xy || this.get(HOST).get(DRAG_NODE).getXY(); |
|
|
385 |
|
|
|
386 |
var _xy = this._checkRegion([xy[0], xy[1]]), |
|
|
387 |
inside = false; |
|
|
388 |
if ((xy[0] === _xy[0]) && (xy[1] === _xy[1])) { |
|
|
389 |
inside = true; |
|
|
390 |
} |
|
|
391 |
return inside; |
|
|
392 |
}, |
|
|
393 |
/** |
|
|
394 |
* Modifies the Drag.actXY method from the after drag:align event. This is where the constraining happens. |
|
|
395 |
* @method align |
|
|
396 |
*/ |
|
|
397 |
align: function() { |
|
|
398 |
var host = this.get(HOST), |
|
|
399 |
_xy = [host.actXY[0], host.actXY[1]], |
|
|
400 |
r = this.getRegion(true); |
|
|
401 |
|
|
|
402 |
if (this.get('stickX')) { |
|
|
403 |
_xy[1] = (host.startXY[1] - host.deltaXY[1]); |
|
|
404 |
} |
|
|
405 |
if (this.get('stickY')) { |
|
|
406 |
_xy[0] = (host.startXY[0] - host.deltaXY[0]); |
|
|
407 |
} |
|
|
408 |
|
|
|
409 |
if (r) { |
|
|
410 |
_xy = this._checkRegion(_xy); |
|
|
411 |
} |
|
|
412 |
|
|
|
413 |
_xy = this._checkTicks(_xy, r); |
|
|
414 |
|
|
|
415 |
host.actXY = _xy; |
|
|
416 |
}, |
|
|
417 |
/** |
|
|
418 |
* Fires after drag:drag. Handle the tickX and tickX align events. |
|
|
419 |
* @method drag |
|
|
420 |
*/ |
|
|
421 |
drag: function() { |
|
|
422 |
var host = this.get(HOST), |
|
|
423 |
xt = this.get('tickX'), |
|
|
424 |
yt = this.get('tickY'), |
|
|
425 |
_xy = [host.actXY[0], host.actXY[1]]; |
|
|
426 |
|
|
|
427 |
if ((Y.Lang.isNumber(xt) || this.get(TICK_X_ARRAY)) && (this._lastTickXFired !== _xy[0])) { |
|
|
428 |
this._tickAlignX(); |
|
|
429 |
this._lastTickXFired = _xy[0]; |
|
|
430 |
} |
|
|
431 |
|
|
|
432 |
if ((Y.Lang.isNumber(yt) || this.get(TICK_Y_ARRAY)) && (this._lastTickYFired !== _xy[1])) { |
|
|
433 |
this._tickAlignY(); |
|
|
434 |
this._lastTickYFired = _xy[1]; |
|
|
435 |
} |
|
|
436 |
}, |
|
|
437 |
/** |
|
|
438 |
* This method delegates the proper helper method for tick calculations |
|
|
439 |
* @private |
|
|
440 |
* @method _checkTicks |
|
|
441 |
* @param {Array} xy The XY coords for the Drag |
|
|
442 |
* @param {Object} r The optional region that we are bound to. |
|
|
443 |
* @return {Array} The calced XY coords |
|
|
444 |
*/ |
|
|
445 |
_checkTicks: function(xy, r) { |
|
|
446 |
var host = this.get(HOST), |
|
|
447 |
lx = (host.startXY[0] - host.deltaXY[0]), |
|
|
448 |
ly = (host.startXY[1] - host.deltaXY[1]), |
|
|
449 |
xt = this.get('tickX'), |
|
|
450 |
yt = this.get('tickY'); |
|
|
451 |
if (xt && !this.get(TICK_X_ARRAY)) { |
|
|
452 |
xy[0] = DDM._calcTicks(xy[0], lx, xt, r[LEFT], r[RIGHT]); |
|
|
453 |
} |
|
|
454 |
if (yt && !this.get(TICK_Y_ARRAY)) { |
|
|
455 |
xy[1] = DDM._calcTicks(xy[1], ly, yt, r[TOP], r[BOTTOM]); |
|
|
456 |
} |
|
|
457 |
if (this.get(TICK_X_ARRAY)) { |
|
|
458 |
xy[0] = DDM._calcTickArray(xy[0], this.get(TICK_X_ARRAY), r[LEFT], r[RIGHT]); |
|
|
459 |
} |
|
|
460 |
if (this.get(TICK_Y_ARRAY)) { |
|
|
461 |
xy[1] = DDM._calcTickArray(xy[1], this.get(TICK_Y_ARRAY), r[TOP], r[BOTTOM]); |
|
|
462 |
} |
|
|
463 |
|
|
|
464 |
return xy; |
|
|
465 |
}, |
|
|
466 |
/** |
|
|
467 |
* Fires when the actXY[0] reach a new value respecting the tickX gap. |
|
|
468 |
* @private |
|
|
469 |
* @method _tickAlignX |
|
|
470 |
*/ |
|
|
471 |
_tickAlignX: function() { |
|
|
472 |
this.fire(EV_TICK_ALIGN_X); |
|
|
473 |
}, |
|
|
474 |
/** |
|
|
475 |
* Fires when the actXY[1] reach a new value respecting the tickY gap. |
|
|
476 |
* @private |
|
|
477 |
* @method _tickAlignY |
|
|
478 |
*/ |
|
|
479 |
_tickAlignY: function() { |
|
|
480 |
this.fire(EV_TICK_ALIGN_Y); |
|
|
481 |
} |
|
|
482 |
}; |
|
|
483 |
|
|
|
484 |
Y.namespace('Plugin'); |
|
|
485 |
Y.extend(C, Y.Base, proto); |
|
|
486 |
Y.Plugin.DDConstrained = C; |
|
|
487 |
|
|
|
488 |
Y.mix(DDM, { |
|
|
489 |
/** |
|
|
490 |
* Helper method to calculate the tick offsets for a given position |
|
|
491 |
* @for DDM |
|
|
492 |
* @namespace DD |
|
|
493 |
* @private |
|
|
494 |
* @method _calcTicks |
|
|
495 |
* @param {Number} pos The current X or Y position |
|
|
496 |
* @param {Number} start The start X or Y position |
|
|
497 |
* @param {Number} tick The X or Y tick increment |
|
|
498 |
* @param {Number} off1 The min offset that we can't pass (region) |
|
|
499 |
* @param {Number} off2 The max offset that we can't pass (region) |
|
|
500 |
* @return {Number} The new position based on the tick calculation |
|
|
501 |
*/ |
|
|
502 |
_calcTicks: function(pos, start, tick, off1, off2) { |
|
|
503 |
var ix = ((pos - start) / tick), |
|
|
504 |
min = Math.floor(ix), |
|
|
505 |
max = Math.ceil(ix); |
|
|
506 |
if ((min !== 0) || (max !== 0)) { |
|
|
507 |
if ((ix >= min) && (ix <= max)) { |
|
|
508 |
pos = (start + (tick * min)); |
|
|
509 |
if (off1 && off2) { |
|
|
510 |
if (pos < off1) { |
|
|
511 |
pos = (start + (tick * (min + 1))); |
|
|
512 |
} |
|
|
513 |
if (pos > off2) { |
|
|
514 |
pos = (start + (tick * (min - 1))); |
|
|
515 |
} |
|
|
516 |
} |
|
|
517 |
} |
|
|
518 |
} |
|
|
519 |
return pos; |
|
|
520 |
}, |
|
|
521 |
/** |
|
|
522 |
* This method is used with the tickXArray and tickYArray config options |
|
|
523 |
* @for DDM |
|
|
524 |
* @namespace DD |
|
|
525 |
* @private |
|
|
526 |
* @method _calcTickArray |
|
|
527 |
* @param {Number} pos The current X or Y position |
|
|
528 |
* @param {Number} ticks The array containing our custom tick positions. |
|
|
529 |
* @param {Number} off1 The min offset that we can't pass (region) |
|
|
530 |
* @param {Number} off2 The max offset that we can't pass (region) |
|
|
531 |
* @return The tick position |
|
|
532 |
*/ |
|
|
533 |
_calcTickArray: function(pos, ticks, off1, off2) { |
|
|
534 |
var i = 0, len = ticks.length, next = 0, |
|
|
535 |
diff1, diff2, ret; |
|
|
536 |
|
|
|
537 |
if (!ticks || (ticks.length === 0)) { |
|
|
538 |
return pos; |
|
|
539 |
} |
|
|
540 |
if (ticks[0] >= pos) { |
|
|
541 |
return ticks[0]; |
|
|
542 |
} |
|
|
543 |
|
|
|
544 |
for (i = 0; i < len; i++) { |
|
|
545 |
next = (i + 1); |
|
|
546 |
if (ticks[next] && ticks[next] >= pos) { |
|
|
547 |
diff1 = pos - ticks[i]; |
|
|
548 |
diff2 = ticks[next] - pos; |
|
|
549 |
ret = (diff2 > diff1) ? ticks[i] : ticks[next]; |
|
|
550 |
if (off1 && off2) { |
|
|
551 |
if (ret > off2) { |
|
|
552 |
if (ticks[i]) { |
|
|
553 |
ret = ticks[i]; |
|
|
554 |
} else { |
|
|
555 |
ret = ticks[len - 1]; |
|
|
556 |
} |
|
|
557 |
} |
|
|
558 |
} |
|
|
559 |
return ret; |
|
|
560 |
} |
|
|
561 |
|
|
|
562 |
} |
|
|
563 |
return ticks[ticks.length - 1]; |
|
|
564 |
} |
|
|
565 |
}); |
|
|
566 |
|
|
|
567 |
|
|
|
568 |
|
|
|
569 |
}, '3.10.3', {"requires": ["dd-drag"]}); |