142 lines
4.7 KiB
JavaScript
142 lines
4.7 KiB
JavaScript
var tokenRegex = /\{([^\}]+)\}/g,
|
|
objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,
|
|
replacer = function (all, key, obj) {
|
|
var res = obj;
|
|
key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
|
|
name = name || quotedName;
|
|
if (res) {
|
|
if (name in res) {
|
|
res = res[name];
|
|
}
|
|
typeof res == "function" && isFunc && (res = res());
|
|
}
|
|
});
|
|
res = (res == null || res == obj ? all : res) + "";
|
|
return res;
|
|
},
|
|
fill = function (str, obj) {
|
|
return String(str).replace(tokenRegex, function (all, key) {
|
|
return replacer(all, key, obj);
|
|
});
|
|
};
|
|
|
|
|
|
Raphael.fn.popup = function (X, Y, set, pos, ret) {
|
|
pos = String(pos || "top-middle").split("-");
|
|
pos[1] = pos[1] || "middle";
|
|
var r = 5,
|
|
bb = set.getBBox(),
|
|
w = Math.round(bb.width),
|
|
h = Math.round(bb.height),
|
|
x = Math.round(bb.x) - r,
|
|
y = Math.round(bb.y) - r,
|
|
gap = Math.min(h / 2, w / 2, 10),
|
|
shapes = {
|
|
top: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}l-{right},0-{gap},{gap}-{gap}-{gap}-{left},0a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z",
|
|
bottom: "M{x},{y}l{left},0,{gap}-{gap},{gap},{gap},{right},0a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z",
|
|
right: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}l0-{bottom}-{gap}-{gap},{gap}-{gap},0-{top}a{r},{r},0,0,1,{r}-{r}z",
|
|
left: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}l0,{top},{gap},{gap}-{gap},{gap},0,{bottom}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z"
|
|
},
|
|
offset = {
|
|
hx0: X - (x + r + w - gap * 2),
|
|
hx1: X - (x + r + w / 2 - gap),
|
|
hx2: X - (x + r + gap),
|
|
vhy: Y - (y + r + h + r + gap),
|
|
"^hy": Y - (y - gap)
|
|
|
|
},
|
|
mask = [{
|
|
x: x + r,
|
|
y: y,
|
|
w: w,
|
|
w4: w / 4,
|
|
h4: h / 4,
|
|
right: 0,
|
|
left: w - gap * 2,
|
|
bottom: 0,
|
|
top: h - gap * 2,
|
|
r: r,
|
|
h: h,
|
|
gap: gap
|
|
}, {
|
|
x: x + r,
|
|
y: y,
|
|
w: w,
|
|
w4: w / 4,
|
|
h4: h / 4,
|
|
left: w / 2 - gap,
|
|
right: w / 2 - gap,
|
|
top: h / 2 - gap,
|
|
bottom: h / 2 - gap,
|
|
r: r,
|
|
h: h,
|
|
gap: gap
|
|
}, {
|
|
x: x + r,
|
|
y: y,
|
|
w: w,
|
|
w4: w / 4,
|
|
h4: h / 4,
|
|
left: 0,
|
|
right: w - gap * 2,
|
|
top: 0,
|
|
bottom: h - gap * 2,
|
|
r: r,
|
|
h: h,
|
|
gap: gap
|
|
}][pos[1] == "middle" ? 1 : (pos[1] == "top" || pos[1] == "left") * 2];
|
|
var dx = 0,
|
|
dy = 0,
|
|
out = this.path(fill(shapes[pos[0]], mask)).insertBefore(set);
|
|
switch (pos[0]) {
|
|
case "top":
|
|
dx = X - (x + r + mask.left + gap);
|
|
dy = Y - (y + r + h + r + gap);
|
|
break;
|
|
case "bottom":
|
|
dx = X - (x + r + mask.left + gap);
|
|
dy = Y - (y - gap);
|
|
break;
|
|
case "left":
|
|
dx = X - (x + r + w + r + gap);
|
|
dy = Y - (y + r + mask.top + gap);
|
|
break;
|
|
case "right":
|
|
dx = X - (x - gap);
|
|
dy = Y - (y + r + mask.top + gap);
|
|
break;
|
|
}
|
|
out.translate(dx, dy);
|
|
if (ret) {
|
|
ret = out.attr("path");
|
|
out.remove();
|
|
return {
|
|
path: ret,
|
|
dx: dx,
|
|
dy: dy
|
|
};
|
|
}
|
|
set.translate(dx, dy);
|
|
return out;
|
|
};
|
|
|
|
|
|
function getAnchors(p1x, p1y, p2x, p2y, p3x, p3y) {
|
|
var l1 = (p2x - p1x) / 2,
|
|
l2 = (p3x - p2x) / 2,
|
|
a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),
|
|
b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y));
|
|
a = p1y < p2y ? Math.PI - a : a;
|
|
b = p3y < p2y ? Math.PI - b : b;
|
|
var alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2,
|
|
dx1 = l1 * Math.sin(alpha + a),
|
|
dy1 = l1 * Math.cos(alpha + a),
|
|
dx2 = l2 * Math.sin(alpha + b),
|
|
dy2 = l2 * Math.cos(alpha + b);
|
|
return {
|
|
x1: p2x - dx1,
|
|
y1: p2y + dy1,
|
|
x2: p2x + dx2,
|
|
y2: p2y + dy2
|
|
};
|
|
} |