2011-01-05 59 views
11

我正在开发一个项目,该项目要求最终用户能够像浏览器一样在svg-edit中绘制图像,并将SVG数据发送到服务器进行处理。Raphael JS高效实现“铅笔”工具

我已经开始玩Raphael框架,它似乎很有前途。

目前我正在尝试实现铅笔或freeline类型的工具。基本上我只是根据绘图区域中鼠标移动的百分比绘制一条新路径。然而,最终这将创造大量的路径来处理。

是否有可能缩短通过将鼠标移动的SVG路径 使用 曲线和的线路路径,而不是线 段?

下面是代码草案一刮起来完成这项工作...

// 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; 
     } 
    } 
    }); 


    }); 

回答

3

看一看道格拉斯 - 普克算法,简化您的生产线。

我不知道任何JavaScript实现的(虽然谷歌搜索指示我到论坛,谷歌地图开发者),但这里有一个TCL实现,是很容易理解:http://wiki.tcl.tk/27610

而且这里有一个维基百科的文章,解释的算法(连同伪代码):http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm

+0

这看起来很有趣。我想这会让我的曲线看起来更加细分。 – 2011-01-05 16:36:18

+0

该算法具有可调整的错误值,您可以使用该值来确定想要的结果与最初的行相似程度。维基百科文章当然会在其图中夸大一点,以说明该算法的工作原理。基本上任何时候你减少一行中的点数就可以使这一行更“分段”。就像游戏如何使用低多边形3D对象来提高速度一样。这里同样的原则,但在二维。 – slebetman 2011-01-05 23:13:33

0

我正在做类似的事情。我找到了一种方法,通过我的回答here中概述的Raphael API的一点旁路来增加路径命令。在我测试过的现代浏览器中,这表现得相当不错,但线条看起来平滑的程度取决于mousemove处理程序的工作速度。

你可以尝试我的方法,使用线段绘制路径,然后在绘制初始锯齿状路径之后执行平滑处理(或者按照某种方式进行),通过使用Ramer-Douglas-Peucker修改坐标并按照slebetman的建议进行修剪,其余的L s到SVG曲线命令。

0

我有一个simillar问题,我使用鼠标拖动和M命令。然后将该路径保存到服务器上的数据库中。我遇到的问题是解决问题。我有一个背景图像,用户在图像的某些部分上绘制线条和形状,但如果图像显示在一个分辨率上,并且路径是以该分辨率创建的,然后以不同的低分辨率重新打开,我的路径会移动并且尺寸不正确。我想我所问的是:有没有一种方法可以在图像上绘制路径,并确保路径保持正确无误的底层图像的大小。