| 119 |
ghuddy |
1 |
/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
|
|
|
2 |
|
|
|
3 |
/* FIXME: assumes position styles are specified in 'px' */
|
|
|
4 |
|
|
|
5 |
ToolMan._coordinatesFactory = {
|
|
|
6 |
|
|
|
7 |
create : function(x, y) {
|
|
|
8 |
// FIXME: Safari won't parse 'throw' and aborts trying to do anything with this file
|
|
|
9 |
//if (isNaN(x) || isNaN(y)) throw "invalid x,y: " + x + "," + y
|
|
|
10 |
return new _ToolManCoordinate(this, x, y)
|
|
|
11 |
},
|
|
|
12 |
|
|
|
13 |
origin : function() {
|
|
|
14 |
return this.create(0, 0)
|
|
|
15 |
},
|
|
|
16 |
|
|
|
17 |
/*
|
|
|
18 |
* FIXME: Safari 1.2, returns (0,0) on absolutely positioned elements
|
|
|
19 |
*/
|
|
|
20 |
topLeftPosition : function(element) {
|
|
|
21 |
var left = parseInt(ToolMan.css().readStyle(element, "left"))
|
|
|
22 |
var left = isNaN(left) ? 0 : left
|
|
|
23 |
var top = parseInt(ToolMan.css().readStyle(element, "top"))
|
|
|
24 |
var top = isNaN(top) ? 0 : top
|
|
|
25 |
|
|
|
26 |
return this.create(left, top)
|
|
|
27 |
},
|
|
|
28 |
|
|
|
29 |
bottomRightPosition : function(element) {
|
|
|
30 |
return this.topLeftPosition(element).plus(this._size(element))
|
|
|
31 |
},
|
|
|
32 |
|
|
|
33 |
topLeftOffset : function(element) {
|
|
|
34 |
var offset = this._offset(element)
|
|
|
35 |
|
|
|
36 |
var parent = element.offsetParent
|
|
|
37 |
while (parent) {
|
|
|
38 |
offset = offset.plus(this._offset(parent))
|
|
|
39 |
parent = parent.offsetParent
|
|
|
40 |
}
|
|
|
41 |
return offset
|
|
|
42 |
},
|
|
|
43 |
|
|
|
44 |
bottomRightOffset : function(element) {
|
|
|
45 |
return this.topLeftOffset(element).plus(
|
|
|
46 |
this.create(element.offsetWidth, element.offsetHeight))
|
|
|
47 |
},
|
|
|
48 |
|
|
|
49 |
scrollOffset : function() {
|
|
|
50 |
if (window.pageXOffset) {
|
|
|
51 |
return this.create(window.pageXOffset, window.pageYOffset)
|
|
|
52 |
} else if (document.documentElement) {
|
|
|
53 |
return this.create(
|
|
|
54 |
document.body.scrollLeft + document.documentElement.scrollLeft,
|
|
|
55 |
document.body.scrollTop + document.documentElement.scrollTop)
|
|
|
56 |
} else if (document.body.scrollLeft >= 0) {
|
|
|
57 |
return this.create(document.body.scrollLeft, document.body.scrollTop)
|
|
|
58 |
} else {
|
|
|
59 |
return this.create(0, 0)
|
|
|
60 |
}
|
|
|
61 |
},
|
|
|
62 |
|
|
|
63 |
clientSize : function() {
|
|
|
64 |
if (window.innerHeight >= 0) {
|
|
|
65 |
return this.create(window.innerWidth, window.innerHeight)
|
|
|
66 |
} else if (document.documentElement) {
|
|
|
67 |
return this.create(document.documentElement.clientWidth,
|
|
|
68 |
document.documentElement.clientHeight)
|
|
|
69 |
} else if (document.body.clientHeight >= 0) {
|
|
|
70 |
return this.create(document.body.clientWidth,
|
|
|
71 |
document.body.clientHeight)
|
|
|
72 |
} else {
|
|
|
73 |
return this.create(0, 0)
|
|
|
74 |
}
|
|
|
75 |
},
|
|
|
76 |
|
|
|
77 |
/**
|
|
|
78 |
* mouse coordinate relative to the window (technically the
|
|
|
79 |
* browser client area) i.e. the part showing your page
|
|
|
80 |
*
|
|
|
81 |
* NOTE: in Safari the coordinate is relative to the document
|
|
|
82 |
*/
|
|
|
83 |
mousePosition : function(event) {
|
|
|
84 |
event = ToolMan.events().fix(event)
|
|
|
85 |
return this.create(event.clientX, event.clientY)
|
|
|
86 |
},
|
|
|
87 |
|
|
|
88 |
/**
|
|
|
89 |
* mouse coordinate relative to the document
|
|
|
90 |
*/
|
|
|
91 |
mouseOffset : function(event) {
|
|
|
92 |
event = ToolMan.events().fix(event)
|
|
|
93 |
if (event.pageX >= 0 || event.pageX < 0) {
|
|
|
94 |
return this.create(event.pageX, event.pageY)
|
|
|
95 |
} else if (event.clientX >= 0 || event.clientX < 0) {
|
|
|
96 |
return this.mousePosition(event).plus(this.scrollOffset())
|
|
|
97 |
}
|
|
|
98 |
},
|
|
|
99 |
|
|
|
100 |
_size : function(element) {
|
|
|
101 |
/* TODO: move to a Dimension class */
|
|
|
102 |
return this.create(element.offsetWidth, element.offsetHeight)
|
|
|
103 |
},
|
|
|
104 |
|
|
|
105 |
_offset : function(element) {
|
|
|
106 |
return this.create(element.offsetLeft, element.offsetTop)
|
|
|
107 |
}
|
|
|
108 |
}
|
|
|
109 |
|
|
|
110 |
function _ToolManCoordinate(factory, x, y) {
|
|
|
111 |
this.factory = factory
|
|
|
112 |
this.x = isNaN(x) ? 0 : x
|
|
|
113 |
this.y = isNaN(y) ? 0 : y
|
|
|
114 |
}
|
|
|
115 |
|
|
|
116 |
_ToolManCoordinate.prototype = {
|
|
|
117 |
toString : function() {
|
|
|
118 |
return "(" + this.x + "," + this.y + ")"
|
|
|
119 |
},
|
|
|
120 |
|
|
|
121 |
plus : function(that) {
|
|
|
122 |
return this.factory.create(this.x + that.x, this.y + that.y)
|
|
|
123 |
},
|
|
|
124 |
|
|
|
125 |
minus : function(that) {
|
|
|
126 |
return this.factory.create(this.x - that.x, this.y - that.y)
|
|
|
127 |
},
|
|
|
128 |
|
|
|
129 |
min : function(that) {
|
|
|
130 |
return this.factory.create(
|
|
|
131 |
Math.min(this.x , that.x), Math.min(this.y , that.y))
|
|
|
132 |
},
|
|
|
133 |
|
|
|
134 |
max : function(that) {
|
|
|
135 |
return this.factory.create(
|
|
|
136 |
Math.max(this.x , that.x), Math.max(this.y , that.y))
|
|
|
137 |
},
|
|
|
138 |
|
|
|
139 |
constrainTo : function (one, two) {
|
|
|
140 |
var min = one.min(two)
|
|
|
141 |
var max = one.max(two)
|
|
|
142 |
|
|
|
143 |
return this.max(min).min(max)
|
|
|
144 |
},
|
|
|
145 |
|
|
|
146 |
distance : function (that) {
|
|
|
147 |
return Math.sqrt(Math.pow(this.x - that.x, 2) + Math.pow(this.y - that.y, 2))
|
|
|
148 |
},
|
|
|
149 |
|
|
|
150 |
reposition : function(element) {
|
|
|
151 |
element.style["top"] = this.y + "px"
|
|
|
152 |
element.style["left"] = this.x + "px"
|
|
|
153 |
}
|
|
|
154 |
}
|