2011-01-05 10 views
11

Ich arbeite an einem Projekt, das erfordert, dass Endbenutzer im Browser ähnlich wie svg-edit zeichnen und SVG-Daten zur Verarbeitung an den Server senden können.Raphael JS Implementieren eines "Stift" -Tools effizient

Ich habe angefangen mit dem Raphael Framework zu spielen und es scheint vielversprechend.

Momentan versuche ich, ein Stift- oder Freeline-Werkzeug zu implementieren. Im Grunde zeichne ich nur einen neuen Pfad basierend auf dem Prozentsatz der Mausbewegung im Zeichenbereich. Am Ende wird dies jedoch eine enorme Anzahl von Pfaden schaffen, mit denen umzugehen ist.

Ist es möglich, eine SVG-Pfad durch Umwandlung der Mausbewegung zu verkürzen Kurven- und Linienwege statt Linie Segmente zu bedienen?

Im Folgenden finden Sie Entwurf Code, den ich peitschte die Arbeit zu tun ...

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


    }); 

Antwort

3

einen Blick auf die Douglas-Peucker Algorithmus Haben Sie Ihre Linie zu vereinfachen.

Ich weiß nicht jede JavaScript-Implementierung (obwohl ich Foren gerichtet googeln für Google-Entwickler-Karten), aber hier ist eine tcl-Implementierung, die leicht zu verstehen ist genug: http://wiki.tcl.tk/27610

Und hier ist ein Wikipedia-Artikel erklärt, den Algorithmus (zusammen mit Pseudo-Code): http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm

+0

Das sieht interessant aus. Ich stelle mir vor, dass dies meine Kurven segmentierter erscheinen lässt. –

+0

Der Algorithmus hat einen einstellbaren Fehlerwert, mit dem Sie entscheiden können, wie genau die resultierende Linie der ursprünglichen Linie ähnelt. Der Wikipedia-Artikel übertreibt natürlich ein wenig in seinen Diagrammen, um zu veranschaulichen, wie der Algorithmus funktioniert. Grundsätzlich, wenn Sie die Anzahl der Punkte in einer Linie reduzieren, machen Sie die Linie "segmentierter".Genauso wie Spiele Low Polygon 3D-Objekte verwenden, um die Geschwindigkeit zu verbessern. Gleiches Prinzip hier aber in 2D. – slebetman

0

Ich arbeite an etwas ähnliches. Ich habe einen Weg gefunden, Pfadbefehle schrittweise hinzuzufügen, indem ich die RAPHAEL-API umgangen habe, wie in meiner Antwort here beschrieben. In den modernen Browsern, die ich getestet habe, funktioniert das einigermaßen gut, aber der Grad, in dem Ihre Zeilen glatt erscheinen, hängt davon ab, wie schnell der Mauszeiger-Handler arbeiten kann.

Sie könnten meine Methode zum Zeichnen von Pfaden mit Liniensegmenten versuchen und führen nach der ersten gezackten Bahnglättung gezogen (oder wie Sie gehen irgendwie), indem Sie die Koordinaten Beschneiden mit Ramer-Douglas-Peucker als slebetman vorgeschlagen, und Umwandeln die restlichen L s zu SVG-Kurvenbefehlen.

0

Ich habe ein simillar Problem, ich zeichne mit der Maus nach unten und den M-Befehl. Ich speichere diesen Pfad dann in einer Datenbank auf dem Server. Das Problem, das ich habe, hat mit der Lösung zu tun. Ich habe ein Hintergrundbild, in dem die Benutzer Linien und Formen über Teile des Bildes zeichnen, aber wenn das Bild in einer Auflösung angezeigt wird und die Pfade in dieser Auflösung erzeugt werden, dann werden meine Pfade verschoben und sind nicht richtig dimensioniert. Ich denke, was ich frage, ist: Gibt es eine Möglichkeit, einen Pfad über ein Bild zu zeichnen und sicherzustellen, dass unabhängig von der Größe des zugrunde liegenden Bildes der Pfad genau richtig bleibt.