Raphael JS有效地实施“铅笔”工具

时间:2011-01-05 03:16:35

标签: javascript svg raphael

我正在开发一个项目,要求最终用户能够像svg-edit那样在浏览器中绘图,并将SVG数据发送到服务器进行处理。

我开始玩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; 
      }
     }
    });


   }); 

4 个答案:

答案 0 :(得分:3)

查看Douglas-Peucker算法以简化您的生产线。

我不知道任何javascript实现(虽然谷歌搜索引导我到谷歌地图开发人员的论坛)但这里是一个易于理解的tcl实现:http://wiki.tcl.tk/27610

这是一篇维基百科文章解释算法(以及伪代码):http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm

答案 1 :(得分:3)

这是一个可与iPhone或鼠标配合使用的绘图工具 http://irunmywebsite.com/raphael/drawtool2.php 不过也看看Daves“游戏实用工具”@ http://irunmywebsite.com/raphael/raphaelsource.php在绘制时生成路径数据。

答案 2 :(得分:0)

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

你可以尝试我的方法使用线段绘制路径,然后在绘制初始锯齿状路径(或者你不知何故)之后执行平滑,通过使用Ramer-Douglas-Peucker修剪坐标作为slebetman建议,并转换保留L到SVG曲线命令。

答案 3 :(得分:0)

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