2011-01-05 16 views
11

私は、エンドユーザがsvg-editのようにブラウザで描画し、SVGデータをサーバに送信して処理できるようにするプロジェクトに取り組んでいます。Raphael JS「鉛筆」ツールを効率的に実装する

私はRaphaelフレームワークで試合を始めましたが、これは有望そうです。

現在、私は鉛筆またはフリーラインタイプのツールを実装しようとしています。基本的には、描画領域内のマウスの動きの割合に基づいて新しいパスを描画しています。しかし、最終的にこれは対処すべき膨大な量の経路を作り出すでしょう。

ではなく線 セグメント曲線とラインパスを使用するマウスの動きを変換することにより、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

はあなたのラインを簡素化するためにダグラスPeuckerアルゴリズムを見てください。

私は(Googleが開発者をマップするためのフォーラムに私を監督グーグルが)任意のJavaScriptの実装を知っているが、ここで理解するのは簡単であるTCLの実装ですません。http://wiki.tcl.tk/27610

そしてここでは、アルゴリズムを説明するWikipediaの記事です(擬似コードと一緒に):http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithmここ

+0

これは興味深いようです。私はこれが私のカーブをもっと細かく見せてくれると思います。 –

+0

アルゴリズムには調整可能なエラー値があり、結果の行を元の行に似せる程度を決定するために使用できます。ウィキペディアの記事では、アルゴリズムの仕組みを説明するために、その図の中で少し誇張しています。基本的には、ラインのポイント数を減らして、ラインをより細かくすることができます。ちょうどゲームが低ポリゴン3Dオブジェクトを使ってスピードを上げるように。ここでも同じですが、2Dでも同じです。 – slebetman

0

私は同様のことに取り組んでいます。私は、答えをhereで概説したように、Raphael APIを少しバイパスして段階的にパスコマンドを追加する方法を見つけました。私がテストした現代のブラウザでは、これはかなりうまくいくが、線が滑らかに見える程度は、mousemoveハンドラがどれくらい速く動くかによって決まる。

私は、ラインセグメントを使ってパスを描き、最初のギザギザのパスが描画された後に(または何とか行って)スムージングを実行してみましょう。sleeptmanが示唆するようにRamer-Douglas-Peuckerを使用して座標を剪定し、 SVG曲線コマンドの残りの部分はLです。

0

私はシミラーの問題を抱えています。私はマウスを使ってMコマンドを使用して描画します。次に、そのパスをサーバー上のデータベースに保存します。私が抱えている問題は解決策と関係しています。私は、ユーザーが画像の一部に線や形を描く背景画像を持っていますが、画像が1つの解像度で表示され、パスがその解像度で作成され、おそらく低い解像度で再オープンされると、正確なサイズではありません。私は何を求めているのかというと、画像の上にパスを描き、下にある画像のサイズに関係なく、そのパスが常に正しいかどうかを確認する方法はありますか?

関連する問題