我有很多年的编码经验,但很少有 javascript 和 raphael。我一直在网上找一本我在拉斐尔买的书。我正在尝试做的部分事情是拥有一条线/路径,并为用户提供向这条线添加或编辑点的能力。类似于谷歌地图上的路线。
我知道可以使用数组构建路径。我相信这些元素可以有一个唯一的 id,这将有助于访问它们。
我正在考虑类似于此问题中建议的一种方法,特别是 Adam Moszczyński 将绘图与数据分离的方法;特别是在路上,很可能需要持久化/加载此路径数据。
我有很多年的编码经验,但很少有 javascript 和 raphael。我一直在网上找一本我在拉斐尔买的书。我正在尝试做的部分事情是拥有一条线/路径,并为用户提供向这条线添加或编辑点的能力。类似于谷歌地图上的路线。
我知道可以使用数组构建路径。我相信这些元素可以有一个唯一的 id,这将有助于访问它们。
我正在考虑类似于此问题中建议的一种方法,特别是 Adam Moszczyński 将绘图与数据分离的方法;特别是在路上,很可能需要持久化/加载此路径数据。
如果您只想绘制直线,那么 SVG 路径语法相当简单。您实际上只需要知道两个命令:M
设置路径上第一个点的位置,并L
在其余点上画一条线。
例如,要绘制以下折线:
[5,2]___________[12,2]
/ \
/ \
/ [13,5]
/
[1,10]
您将使用以下 SVG 路径:
M 1 10 L 5 2 L 12 2 L 13 5
请注意,SVG 接受,
数字分隔符,命令和参数之间的空格是可选的,如果它们是明确的。所以上面的路径也可以写成:
M 1,10 L 5,2 L 12,2 L 13,5
甚至:
M1,10L5,2L12,2L13,5
但是第一种形式是最方便我们以编程方式使用的,因为它可以简单地通过将数组元素与空格字符连接起来来构造:
var svgpath = [
'M', 1, 10,
'L', 5, 2,
'L', 12, 2,
'L', 13, 5
].join(' ');
鉴于此,很容易编写一个在 Raphael 中绘制路径的函数。有两种方法可以做到这一点:
编写自己独立的线描函数/库,并使用 Raphael 作为工具在屏幕上绘图。最简单的只是一个绘制折线的函数。
function draw_polyline(paper,coords) {
var first = coords.shift();
var path = ['M', first[0], first[1]];
for (var i=0; i<coords.length; i++) {
path.push('L',coords[i][0],coords[i][1]);
}
return paper.path(path.join[' ']);
}
draw_polyline(paper,[[1,10],[5,2],[12,2],[13,5]]);
把它写成 Raphael 的扩展。该函数完全相同,但表现得好像它是 Raphael 的一部分:
Raphael.fn.polyline = function (coords) {
var first = coords.shift();
var path = ['M', first[0], first[1]];
for (var i=0; i<coords.length; i++) {
path.push('L',coords[i][0],coords[i][1]);
}
return this.path(path.join[' ']);
}
var paper = Raphael('div',640,480);
paper.polyline([[1,10],[5,2],[12,2],[13,5]]);
请注意,上面的简单函数只是从给定坐标绘制直线。要向直线添加或删除点,您必须通过使用更新的坐标调用折线函数来重绘路径。这可行,但并不完全理想,因为您必须跟踪旧线并在绘制新线时将其删除。
更好的解决方案是让生产线自行更新。为此,我们需要重构上面的代码,将 svg 路径生成与绘图函数分开:
function polyline_path(coords) {
var first = coords.shift();
var path = ['M', first[0], first[1]];
for (var i=0; i<coords.length; i++) {
path.push('L',coords[i][0],coords[i][1]);
}
return path.join(' ');
}
那么 Raphael 的实现很简单:
Raphael.fn.polyline = function (coords) {
return this.path(polyline_path(coords));
}
现在我们可以向代表折线的 Raphael 路径对象添加一些功能:
Raphael.fn.polyline = function (coords) {
var path = this.path(polyline_path(coords));
path.coords = function(xy) {
if (!xy) {return coords} // return coordinates if no arguments given
coords = xy;
path.attr('path',polyline_path(coords)); // otherwise update svg path
}
return path;
}
现在我们可以像这样使用它:
var route = paper.polyline([[1,10],[5,2],[12,2],[13,5]]);
// Add point to route:
route.coords(route.coords().push([15,10]));
这仍然有点笨拙,但你明白了。您可以使用这个基本概念来实现更高级的 API。例如,如果折线对象实现了大多数 Array 方法,那就太好了,这样您就可以简单地执行以下操作:
route.push([15,10]); // add point to route
route.shift(); // remove point from beginning of route
route.splice(1,1,[5,3]); // modify the second point
// etc..
你想走多远真的取决于你。