Javascript 拉斐尔JS实现了一个;铅笔“;高效工具
我正在从事一个项目,该项目要求最终用户能够像在浏览器中绘制一样,将SVG数据发送到服务器进行处理 我已经开始使用这个框架,它看起来很有前途 目前我正在尝试实现铅笔或自由线类型的工具。基本上,我只是根据绘图区域中鼠标移动的百分比绘制一条新路径。然而,最终这将创建大量的路径来处理 是否可以缩短SVG路径 通过将鼠标移动转换为使用 曲线和直线路径,而不是直线路径 分段 下面是我为完成这项工作而起草的代码草案Javascript 拉斐尔JS实现了一个;铅笔“;高效工具,javascript,svg,raphael,Javascript,Svg,Raphael,我正在从事一个项目,该项目要求最终用户能够像在浏览器中绘制一样,将SVG数据发送到服务器进行处理 我已经开始使用这个框架,它看起来很有前途 目前我正在尝试实现铅笔或自由线类型的工具。基本上,我只是根据绘图区域中鼠标移动的百分比绘制一条新路径。然而,最终这将创建大量的路径来处理 是否可以缩短SVG路径 通过将鼠标移动转换为使用 曲线和直线路径,而不是直线路径 分段 下面是我为完成这项工作而起草的代码草案 // Drawing area size const var SVG_WIDTH
// Drawing area size const
var SVG_WIDTH = 620;
var SVG_HEIGHT = 420;
// Compute movement required for new line
var xMove = Math.round(SVG_WIDTH * .01);
var yMove = Math.round(SVG_HEIGHT * .01);
// Min must be 1
var X_MOVE = xMove ? xMove : 1;
var Y_MOVE = yMove ? yMove : 1;
// Coords
var start, end, coords = null;
var paperOffset = null;
var mouseDown = false;
// Get drawing area coords
function toDrawCoords(coords) {
return {
x: coords.clientX - paperOffset.left,
y: coords.clientY - paperOffset.top
};
}
$(document).ready(function() {
// Get area offset
paperOffset = $("#paper").offset();
paperOffset.left = Math.round(paperOffset.left);
paperOffset.top = Math.round(paperOffset.top);
// Init area
var paper = Raphael("paper", 620, 420);
// Create draw area
var drawArea = paper.rect(0, 0, 619, 419, 10)
drawArea.attr({fill: "#666"});
// EVENTS
drawArea.mousedown(function (event) {
mouseDown = true;
start = toDrawCoords(event);
$("#startCoords").text("Start coords: " + $.dump(start));
});
drawArea.mouseup(function (event) {
mouseDown = false;
end = toDrawCoords(event);
$("#endCoords").text("End coords: " + $.dump(end));
buildJSON(paper);
});
drawArea.mousemove(function (event) {
coords = toDrawCoords(event);
$("#paperCoords").text("Paper coords: " + $.dump(coords));
// if down and we've at least moved min percentage requirments
if (mouseDown) {
var xMovement = Math.abs(start.x - coords.x);
var yMovement = Math.abs(start.y - coords.y);
if (xMovement > X_MOVE || yMovement > Y_MOVE) {
paper.path("M{0} {1}L{2} {3}", start.x, start.y, coords.x, coords.y);
start = coords;
}
}
});
});
看一看道格拉斯·佩克算法来简化你的线路 我不知道有什么javascript实现(尽管谷歌将我引向谷歌地图开发者论坛),但这里有一个tcl实现,很容易理解:
这里有一篇维基百科文章解释了算法(以及伪代码):这是一个可以与iPhone或鼠标一起使用的绘图工具 不过,也可以看看Daves的“游戏实用程序”@
它在绘制时生成路径数据。我正在做类似的工作。我找到了一种方法,通过稍微绕过Raphael API,以增量方式添加path命令,如我在回答中所述。在我测试过的现代浏览器中,它的性能相当好,但线条的平滑程度取决于mousemove处理程序的工作速度
您可以尝试我使用线段绘制路径的方法,然后在绘制初始锯齿状路径后(或在您进行任何操作时)执行平滑,方法是按照slebetman的建议使用Ramer–Douglas–Peucker修剪坐标,并将剩余的
L
s转换为SVG曲线命令。我有一个类似的问题,我使用鼠标向下和M命令绘制。然后,我将该路径保存到服务器上的数据库中。我面临的问题与决心有关。我有一个背景图像,用户在图像的某些部分上绘制线条和形状,但是如果图像以一种分辨率显示,并且路径是以该分辨率创建的,然后以另一种可能更低的分辨率重新打开,则我的路径会移动,并且大小不正确。我想我要问的是:有没有一种方法可以在图像上画一条路径,并确保无论底层图像的大小,路径都保持正确 这看起来很有趣。我想这会使我的曲线看起来更分段。但是,该算法有一个可调的误差值,您可以使用该值来决定结果线与原始线的相似程度。当然,维基百科的文章在图表中有点夸张,以说明算法是如何工作的。基本上,只要你减少一条线中的点数,你就会使这条线更加“分段”。就像游戏如何使用低多边形3D对象来提高速度一样。同样的原理在这里,但在2D中。对于一个新的SO问题,这似乎是一个更长的讨论。已经有一段时间了,但我相信这种行为是直接在svg画布上设置的。