I am working on a project that requires end users to be able draw in the browser much like svg-edit and send SVG data to the server for processing.
I've started playing with the Raphael framework and it seems promising.
Currently I am trying to implement a pencil or freeline type tool. Basically I am just drawing a new path based on percentage of mouse movement in the drawing area. However, in the end this is going to create massive amount of paths to deal with.
Is it possible to shorten an SVG path by converting mouse movement to use Curve and Line paths instead of line segments?
Below is draft code I whipped up to do the job ...
// 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;
}
}
});
});
Have a look at the Douglas-Peucker algorithm to simplify your line.
I don't know of any javascript implementation (though googling directed me to forums for google maps developers) but here's a tcl implementation that is easy enough to understand: http://wiki.tcl.tk/27610
And here's a wikipedia article explaining the algorithm (along with pseudocode): http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
Here is a drawing tool which works with the iPhone or the mouse http://irunmywebsite.com/raphael/drawtool2.php However also look at Daves "game utility" @ http://irunmywebsite.com/raphael/raphaelsource.php which generates path data as you draw.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With