constrain.js revision 0ce21a2762300a493f87331397ca2b814905718b
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * The Drag & Drop Utility allows you to create a draggable interface efficiently, buffering you from browser-level abnormalities and enabling you to focus on the interesting logic surrounding your particular implementation. This component enables you to create a variety of standard draggable objects with just a few lines of code and then, using its extensive API, add your own specific implementation logic.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @module dd
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @submodule dd-constrain
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * Plugin for the dd-drag module to add the constraining methods to it. It supports constraining to a node or viewport. It supports tick based moves and XY axis constraints.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @class DDConstrained
9831c611ec39b61dea834e7ac37564708865c6e6Luke Smith * @extends Base
8dd487c5a842e74ad5cb36d49493d0a0d552f8d3Jeff Conniff * @constructor
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @namespace Plugin
9c46bf9bc0ac9bab8d409ae4ab6d2a2ddc4dc55bJeff Conniff C = function(config) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney C.superclass.constructor.apply(this, arguments);
6340fd3eeb615e0720d218535598b6627a3d4c71Jeff Conniff * @property NS
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @default con
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @protected
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description The Constrained instance will be placed on the Drag instance under the con namespace.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type {String}
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @attribute stickX
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Stick the drag movement to the X-Axis. Default: false
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Boolean
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute stickY
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Stick the drag movement to the Y-Axis
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Boolean
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute tickX
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description The X tick offset the drag node should snap to on each drag move. False for no ticks. Default: false
4fb6ac462f41bde792472a5c16609fafb26421e5Jeff Conniff * @attribute tickY
4fb6ac462f41bde792472a5c16609fafb26421e5Jeff Conniff * @description The Y tick offset the drag node should snap to on each drag move. False for no ticks. Default: false
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute tickXArray
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description An array of page coordinates to use as X ticks for drag movement.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Array
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute tickYArray
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description An array of page coordinates to use as Y ticks for drag movement.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Array
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute gutter
d40e32ef6c95cddf35e9cc056dfdd259ba314fa2Jeff Conniff * @description CSS style string for the gutter of a region (supports negative values): '5 0' (sets top and bottom to 5px, left and right to 0px), '1 2 3 4' (top 1px, right 2px, bottom 3px, left 4px)
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type String
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @attribute constrain
6340fd3eeb615e0720d218535598b6627a3d4c71Jeff Conniff * @description Will attempt to constrain the drag node to the boundaries. Arguments:<br>
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * 'view': Contrain to Viewport<br>
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * '#selector_string': Constrain to this node<br>
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * '{Region Object}': An Object Literal containing a valid region (top, right, bottom, left) of page positions
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @deprecated
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute constrain2region
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description An Object Literal containing a valid region (top, right, bottom, left) of page positions to constrain the drag node to.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Object
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney setter: function(r) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.log('constrain2region is deprecated use constrain: {Region}', 'warn', 'dd');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @deprecated
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @attribute constrain2node
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Will attempt to constrain the drag node to the boundaries of this node.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Object
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney setter: function(n) {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff Y.log('constrain2node is deprecated use constrain: NodeInstance', 'warn', 'dd');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @deprecated
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute constrain2view
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Will attempt to constrain the drag node to the boundaries of the viewport region.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Object
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney setter: function(n) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.log('constrain2view is deprecated use constrain: "view"', 'warn', 'dd');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute cacheRegion
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Should the region be cached for performace. Default: true
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Boolean
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this.get(HOST).on('drag:start', Y.bind(this._handleStart, this));
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this.get(HOST).after('drag:align', Y.bind(this.align, this));
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @method _handleStart
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @description Fires on drag:start and clears the _regionCache
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @property _regionCache
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @description Store a cache of the region that we are constraining to
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @type Object
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @method _cacheRegion
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @description Get's the region and caches it, called from window.resize and when the cache is null
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this._regionCache = this.get('constrain').get('region');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method resetCache
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Reset the internal region cache.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method _getConstraint
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Standardizes the 'constraint' attribute
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.on('resize', Y.bind(this._cacheRegion, this), Y.config.win);
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff region = this.get(HOST).get(DRAG_NODE).get('viewportRegion');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.each(g, function(i, n) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method getRegion
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Get the active region: viewport, node, custom region
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @param {Boolean} inc Include the node's height and width
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @return {Object}
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method _checkRegion
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description Check if xy is inside a given region, if not change to it be inside.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Array} _xy The XY to check if it's in the current region, if it isn't inside the region, it will reset the xy array to be inside the region.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @return {Array} The new XY that is inside the region
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method inRegion
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description Checks if the XY passed or the dragNode is inside the active region.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Array} xy Optional XY to check, if not supplied this.get('dragNode').getXY() is used.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @return {Boolean} True if the XY is inside the region, false otherwise.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff xy = xy || this.get(HOST).get(DRAG_NODE).getXY();
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if ((xy[0] === _xy[0]) && (xy[1] === _xy[1])) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method align
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description Modifies the Drag.actXY method from the after drag:align event. This is where the constraining happens.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff align: function() {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff r = this.getRegion(true);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method _checkTicks
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description This method delegates the proper helper method for tick calculations
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Array} xy The XY coords for the Drag
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Object} r The optional region that we are bound to.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @return {Array} The calced XY coords
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[0] = DDM._calcTicks(xy[0], lx, xt, r[LEFT], r[RIGHT]);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[1] = DDM._calcTicks(xy[1], ly, yt, r[TOP], r[BOTTOM]);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[0] = DDM._calcTickArray(xy[0], this.get(TICK_X_ARRAY), r[LEFT], r[RIGHT]);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[1] = DDM._calcTickArray(xy[1], this.get(TICK_Y_ARRAY), r[TOP], r[BOTTOM]);
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @namespace DD
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @method _calcTicks
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @description Helper method to calculate the tick offsets for a given position
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @param {Number} pos The current X or Y position
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @param {Number} start The start X or Y position
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @param {Number} tick The X or Y tick increment
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @param {Number} off1 The min offset that we can't pass (region)
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @param {Number} off2 The max offset that we can't pass (region)
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @return {Number} The new position based on the tick calculation
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff _calcTicks: function(pos, start, tick, off1, off2) {
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff * @namespace DD
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method _calcTickArray
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description This method is used with the tickXArray and tickYArray config options
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} pos The current X or Y position
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} ticks The array containing our custom tick positions.
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} off1 The min offset that we can't pass (region)
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} off2 The max offset that we can't pass (region)
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @return The tick position
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith _calcTickArray: function(pos, ticks, off1, off2) {