/********************************************************** Very minorly modified from the example by Tim Taylor http://tool-man.org/examples/sorting.html Added Coordinate.prototype.inside( northwest, southeast ); **********************************************************/ var Coordinates = { ORIGIN : new Coordinate(0, 0), coordinatesData: function(element, recurse) { var data = {}; data.recurse = recurse; data.size = new Coordinate(element.offsetWidth, element.offsetHeight); data.nwOffset = Coordinates.northwestOffset(element, recurse); data.seOffset = data.nwOffset.plus(data.size); data.midPoint = data.nwOffset.plus(new Coordinate(Math.round(data.size.x/2), Math.round(data.size.y/2))); return data; }, northwestPosition : function(element) { var x = parseInt(element.style.left); var y = parseInt(element.style.top); return new Coordinate(isNaN(x) ? 0 : x, isNaN(y) ? 0 : y); }, southeastPosition : function(element) { return Coordinates.northwestPosition(element).plus( new Coordinate(element.offsetWidth, element.offsetHeight)); }, northwestOffset : function(element, isRecursive) { var offset = new Coordinate(element.offsetLeft, element.offsetTop); if (!isRecursive) return offset; var parent = element.offsetParent; while (parent) { offset = offset.plus( new Coordinate(parent.offsetLeft, parent.offsetTop)); parent = parent.offsetParent; } return offset; }, southeastOffset : function(element, isRecursive) { return Coordinates.northwestOffset(element, isRecursive).plus( new Coordinate(element.offsetWidth, element.offsetHeight)); } }; function Coordinate(x, y) { this.x = x || 0; this.y = y || 0; } Coordinate.prototype.toString = function() { return "(" + this.x + "," + this.y + ")"; }; Coordinate.prototype.plus = function(that) { return new Coordinate(this.x + that.x, this.y + that.y); }; Coordinate.prototype.minus = function(that) { return new Coordinate(this.x - that.x, this.y - that.y); }; Coordinate.prototype.distance = function(that) { var deltaX = this.x - that.x; var deltaY = this.y - that.y; return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); }; Coordinate.prototype.max = function(that) { var x = Math.max(this.x, that.x); var y = Math.max(this.y, that.y); return new Coordinate(x, y); }; Coordinate.prototype.constrain = function(min, max) { if (min.x > max.x || min.y > max.y) return this; var x = this.x; var y = this.y; if (min.x != null) x = Math.max(x, min.x); if (max.x != null) x = Math.min(x, max.x); if (min.y != null) y = Math.max(y, min.y); if (max.y != null) y = Math.min(y, max.y); return new Coordinate(x, y); }; Coordinate.prototype.reposition = function(element) { element.style["top"] = this.y + "px"; element.style["left"] = this.x + "px"; }; Coordinate.prototype.equals = function(that) { if (this == that) return true; if (!that || that == null) return false; return this.x == that.x && this.y == that.y; }; // returns true of this point is inside specified box Coordinate.prototype.inside = function(northwest, southeast) { if ((this.x >= northwest.x) && (this.x <= southeast.x) && (this.y >= northwest.y) && (this.y <= southeast.y)) { return true; } else { return false; } }; Coordinate.prototype.insideObject = function(obj, recurse) { var data = Coordinates.coordinatesData(obj); data.recurse = recurse; data.quadrant = this.insideObjectData(data); return data.quadrant ? data : null; }; Coordinate.prototype.insideObjectData = function(data) { var nwOffset = data.nwOffset; var seOffset = data.seOffset; var rt = 0; if (this.inside(nwOffset, seOffset)) { var mid = data.midPoint; if (this.x <= mid.x && this.y <= mid.y) { rt = 1; } else if (this.x >= mid.x && this.y <= mid.y) { rt = 2; } else if (this.x >= mid.x && this.y >= mid.y) { rt = 3; } else if (this.x <= mid.x && this.y >= mid.y) { rt = 4; } } return rt; }; function MousePos () { }; // Extend the "Coordinate" class MousePos.prototype = new Coordinate(); MousePos.prototype.update = function(event) { if (typeof event == 'undefined') { event = window.event; } var position = new Coordinate(event.clientX, event.clientY); var scrollOffset = Viewport.scroll(); this.x = position.x + scrollOffset.x; this.y = position.y + scrollOffset.y; if (this.x < 0) this.x = 0; if (this.y < 0) this.y = 0; return event; }; // Track mouse's absolute position (counting scrollbars) var mousePos = new MousePos(0,0); /* * jQuery extension */ jQuery.each([ "coordinatesData", "northwestPosition", "southeastPosition", "northwestOffset", "southeastOffset" ], function(i,n){ jQuery.fn[ n ] = function(h) { return this.length > 0 ? Coordinates[n](this[0], h) : null; }; }); jQuery.fn.xySize = function() { return new Coordinate(this.width(), this.height()); };