我正在使用Raphael javascript基于Raphael网站上给出的一个示例(曲线示例)为CMS创建图像标记功能。它的工作原理是让用户向图像添加箭头(路径)和标签(文本)并移动它们以标记图像中的结构(“兴趣点”)。我已经让它适用于一条路径pr。标签(jsfiddle.net/nartex1234/9m5d7fqd/),但努力使其适用于多个路径pr。标签(jsfiddle.net/nartex1234/wm1odgtz/)。
我觉得这一切都归结为我编程技巧的极限。我真的不知道如何掌握解决方案。我已经包含了下面工作示例的代码。任何关于如何使这项工作的建议或提示都是最受欢迎的。
// Create canvas
var R = Raphael(0, 0, "100%", "100%");
// This is the style objects for the article labels
var labelattr = {
font: "30px Helvetica",
"font-weight": "bold",
opacity: 0.9,
fill: "#fff",
"stroke-width": 1,
stroke: "#000"
};
var discattr = {
fill: "#f0f",
stroke: "none",
opacity: 0.3 // normaly set to 0.01 so that it is not visible
};
var arrowattr = {
"stroke-width": 3,
"stroke-linecap": "round",
"arrow-end": "classic -wide"
};
// The JSON data object (normally provided via AJAX from a database)
var data = [{
"label": "Red",
"articlelabelid": "12",
"labelid": "28",
"x1": "400",
"y1": "150",
"pois": [{
"articlelabelid": "12",
"poid": "3",
"x2": "300",
"y2": "400"
}]
}, {
"label": "Yellow",
"articlelabelid": "13",
"labelid": "30",
"x1": "300",
"y1": "500",
"pois": [{
"articlelabelid": "13",
"poid": "4",
"x2": "400",
"y2": "600"
}, {
"articlelabelid": "13",
"poid": "5",
"x2": "450",
"y2": "600"
}, {
"articlelabelid": "13",
"poid": "6",
"x2": "200",
"y2": "500"
}]
}, {
"label": "Blue",
"articlelabelid": "14",
"labelid": "29",
"x1": "700",
"y1": "450",
"pois": [{
"articlelabelid": "14",
"poid": "13",
"x2": "900",
"y2": "800"
}, {
"articlelabelid": "14",
"poid": "14",
"x2": "800",
"y2": "700"
}]
}, {
"label": "Black",
"articlelabelid": "15",
"labelid": "31",
"x1": "100",
"y1": "100",
"pois": [{
"articlelabelid": "15",
"poid": "15",
"x2": "200",
"y2": "200"
}]
}];
// The start, move and up functions
function start() {}
function move(dx, dy) {
this.update(dx - (this.dx || 0), dy - (this.dy || 0));
this.dx = dx;
this.dy = dy;
}
function up() {
this.dx = this.dy = 0;
switch (this.type) {
case "text":
x = this.attr("x"), y = this.attr("y"), objclass = 'articlelabel_' + this.node.id;
break;
case "circle":
x = this.attr("cx"), y = this.attr("cy"), objclass = 'poi_' + this.node.id;
break;
}
}
// Function to draw the labels and lines, but only the first line/poi (point of interest) in the object
function labeline(object) {
// Find coordinates of label
var x = parseInt(object.x1, 10);
var y = parseInt(object.y1, 10);
// Number of pois (points of interest) for this label
var poi_count = Object.keys(object.pois).length;
var ax = parseInt(object['pois'][0]['x2'], 10);
var ay = parseInt(object['pois'][0]['y2'], 10);
var label = object.label;
var articlelabelid = object.articlelabelid;
var poid = object['pois'][0]['poid'];
// The path - creates an array with two arrays within it
var path = [
["M", x, y],
["L", ax, ay]
],
// The set
controls = R.set(
R.path(path).attr(arrowattr), // Controls [0]
R.circle(ax, ay, 9).attr(discattr), // Controls [1]
R.text(x, y, label).attr(labelattr) // Controls [2]
);
controls[2].update = function(x, y) {
this.node.id = articlelabelid;
var X = this.attr("x") + x,
Y = this.attr("y") + y;
this.attr({
x: X,
y: Y
});
path[0][1] = X;
path[0][2] = Y;
controls[0].attr({
path: path
});
};
controls[1].update = function(x, y) {
this.node.id = poid;
var X = this.attr("cx") + x,
Y = this.attr("cy") + y;
this.attr({
cx: X,
cy: Y
});
path[1][1] = X;
path[1][2] = Y;
controls[0].attr({
path: path
});
};
controls.drag(move, start, up);
}
// Run function for every label in the JSON data object
for (var i = 0; i < data.length; i++) {
labeline(data[i]);
}
答案 0 :(得分:0)
我找到了解决方案也许不是最优雅的解决方案,但它确实有效。这一切都归结为每个点使用for循环。我已将此脚本与我的CMS集成,现在它的工作方式应该如此(在数据库中添加和保存标签和箭头位置)。如果有人发现它有用,我会包含该脚本。 Heres是更新的JS Fiddle http://jsfiddle.net/nartex1234/wm1odgtz/
// Create canvas
var R = Raphael(0, 0, "100%", "100%");
// This is the style objects for the article labels
var labelattr = {
font: "30px Helvetica",
"font-weight": "bold",
opacity: 0.9,
fill: "#fff",
"stroke-width": 1,
stroke: "#000"
};
var discattr = {
fill: "#f0f",
stroke: "none",
opacity: 0.3 // normaly set to 0.01 so that it is not visible
};
var arrowattr = {
"stroke-width": 3,
"stroke-linecap": "round",
"arrow-end": "classic -wide"
};
// The JSON data object (normally provided via AJAX from a database)
var data = [{
"label": "Red",
"articlelabelid": "12",
"labelid": "28",
"x1": "400",
"y1": "150",
"pois": [{
"articlelabelid": "12",
"poid": "3",
"x2": "300",
"y2": "400"
}]
}, {
"label": "Yellow",
"articlelabelid": "13",
"labelid": "30",
"x1": "300",
"y1": "500",
"pois": [{
"articlelabelid": "13",
"poid": "4",
"x2": "400",
"y2": "600"
}, {
"articlelabelid": "13",
"poid": "5",
"x2": "450",
"y2": "600"
}, {
"articlelabelid": "13",
"poid": "6",
"x2": "200",
"y2": "500"
}]
}, {
"label": "Blue",
"articlelabelid": "14",
"labelid": "29",
"x1": "700",
"y1": "450",
"pois": [{
"articlelabelid": "14",
"poid": "13",
"x2": "900",
"y2": "800"
}, {
"articlelabelid": "14",
"poid": "14",
"x2": "800",
"y2": "700"
}]
}, {
"label": "Black",
"articlelabelid": "15",
"labelid": "31",
"x1": "100",
"y1": "100",
"pois": [{
"articlelabelid": "15",
"poid": "15",
"x2": "200",
"y2": "200"
}]
}];
// The start, move and up functions
function start() {}
function move(dx, dy) {
this.update(dx - (this.dx || 0), dy - (this.dy || 0));
this.dx = dx;
this.dy = dy;
}
function up() {
this.dx = this.dy = 0;
switch (this.type) {
case "text":
x = this.attr("x"), y = this.attr("y")
break;
case "circle":
x = this.attr("cx"), y = this.attr("cy")
break;
}
}
// Make array of all paths and circles
function pointers(count, object, x, y) {
var pointers = [];
for (var i = 0; i < count; i++) {
var ax = parseInt(object.pois[i].x2, 10);
var ay = parseInt(object.pois[i].y2, 10);
pointers[i] =
[
[ax, ay, 9], /*POI [0] */
[ /*PATH [1] */
["M", x, y],
["L", ax, ay]
]
]
}
return pointers;
}
// This works for one pois pr. label, but not multiple pois pr label or labels without poi
function labeline(object) {
// Find coordinates of label
var x = parseInt(object.x1, 10);
var y = parseInt(object.y1, 10);
// Number of pois (points of interest) for this label
var poi_count = Object.keys(object.pois).length;
// Label variables from objevt
var label = object.label;
var articlelabelid = object.articlelabelid;
// Make array of all paths and circles
var result = pointers(poi_count, object, x, y);
// Makes new arrays for paths and controls
var path = [];
var controls = [];
for (var i = 0; i < result.length; i++) {
// Adds paths to the path array
path[i] = result[i][1];
// The set
controls[i] = R.set(
R.path(path[i]).attr(arrowattr), // Controls [0]
R.circle(result[i][0][0], result[i][0][1], result[i][0][2]).attr(discattr)//, // Controls [1]
);
// Sets the key of the controls as a 'parentkey' property of the child array and the id of the point of interest as the node id
controls[i][1].parentkey = i;
controls[i][1].node.id = 'poi_' + object.pois[i].poid;
// Updating the correct path
controls[i][1].update = function (x, y) {
var X = this.attr("cx") + x,
Y = this.attr("cy") + y;
this.attr({
cx: X,
cy: Y
});
path[this.parentkey][1][1] = X;
path[this.parentkey][1][2] = Y;
controls[this.parentkey][0].attr({
path: path[this.parentkey]
});
};
controls[i].drag(move, start, up);
}
// The label
label = R.text(x, y, label).attr(labelattr);
label.node.id = 'articlelabel_' + articlelabelid;
label.update = function (x, y) {
var X = this.attr("x") + x,
Y = this.attr("y") + y;
this.attr({
x: X,
y: Y
});
for (var i = 0; i < path.length; i++) {
path[i][0][1] = X;
path[i][0][2] = Y;
controls[i][0].attr({
path: path[i]
});
}
};
label.drag(move, start, up);
}
// Run function for every label in the JSON data object
for (var i = 0; i < data.length; i++) {
labeline(data[i]);
}