qtip2
Version:
Introducing... qTip2. The second generation of the advanced qTip plugin for the ever popular jQuery framework.
119 lines (104 loc) • 3.44 kB
JavaScript
PLUGINS.polys = {
// POLY area coordinate calculator
// Special thanks to Ed Cradock for helping out with this.
// Uses a binary search algorithm to find suitable coordinates.
polygon: function(baseCoords, corner) {
var result = {
width: 0, height: 0,
position: {
top: 1e10, right: 0,
bottom: 0, left: 1e10
},
adjustable: FALSE
},
i = 0, next,
coords = [],
compareX = 1, compareY = 1,
realX = 0, realY = 0,
newWidth, newHeight;
// First pass, sanitize coords and determine outer edges
i = baseCoords.length;
while(i--) {
next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ];
if(next[0] > result.position.right){ result.position.right = next[0]; }
if(next[0] < result.position.left){ result.position.left = next[0]; }
if(next[1] > result.position.bottom){ result.position.bottom = next[1]; }
if(next[1] < result.position.top){ result.position.top = next[1]; }
coords.push(next);
}
// Calculate height and width from outer edges
newWidth = result.width = Math.abs(result.position.right - result.position.left);
newHeight = result.height = Math.abs(result.position.bottom - result.position.top);
// If it's the center corner...
if(corner.abbrev() === 'c') {
result.position = {
left: result.position.left + result.width / 2,
top: result.position.top + result.height / 2
};
}
else {
// Second pass, use a binary search algorithm to locate most suitable coordinate
while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0)
{
newWidth = Math.floor(newWidth / 2);
newHeight = Math.floor(newHeight / 2);
if(corner.x === LEFT){ compareX = newWidth; }
else if(corner.x === RIGHT){ compareX = result.width - newWidth; }
else{ compareX += Math.floor(newWidth / 2); }
if(corner.y === TOP){ compareY = newHeight; }
else if(corner.y === BOTTOM){ compareY = result.height - newHeight; }
else{ compareY += Math.floor(newHeight / 2); }
i = coords.length;
while(i--)
{
if(coords.length < 2){ break; }
realX = coords[i][0] - result.position.left;
realY = coords[i][1] - result.position.top;
if(
corner.x === LEFT && realX >= compareX ||
corner.x === RIGHT && realX <= compareX ||
corner.x === CENTER && (realX < compareX || realX > result.width - compareX) ||
corner.y === TOP && realY >= compareY ||
corner.y === BOTTOM && realY <= compareY ||
corner.y === CENTER && (realY < compareY || realY > result.height - compareY)) {
coords.splice(i, 1);
}
}
}
result.position = { left: coords[0][0], top: coords[0][1] };
}
return result;
},
rect: function(ax, ay, bx, by) {
return {
width: Math.abs(bx - ax),
height: Math.abs(by - ay),
position: {
left: Math.min(ax, bx),
top: Math.min(ay, by)
}
};
},
_angles: {
tc: 3 / 2, tr: 7 / 4, tl: 5 / 4,
bc: 1 / 2, br: 1 / 4, bl: 3 / 4,
rc: 2, lc: 1, c: 0
},
ellipse: function(cx, cy, rx, ry, corner) {
var c = PLUGINS.polys._angles[ corner.abbrev() ],
rxc = c === 0 ? 0 : rx * Math.cos( c * Math.PI ),
rys = ry * Math.sin( c * Math.PI );
return {
width: rx * 2 - Math.abs(rxc),
height: ry * 2 - Math.abs(rys),
position: {
left: cx + rxc,
top: cy + rys
},
adjustable: FALSE
};
},
circle: function(cx, cy, r, corner) {
return PLUGINS.polys.ellipse(cx, cy, r, r, corner);
}
};