2

Raphael.path2curve()に問題があります。この関数は、すべてのパス コマンドが絶対 3 次曲線 (C) に変換されるように、SVG パス文字列を変更します。この関数はすべてのパス コマンドをサポートします ( mlcqahvstMLCQAHVSTSVG SPECを参照)。

Raphael.path2curve() は、多くの場合、パスを適切に処理できます。簡単な計算ではありませんが、アークを立方体に変換することもできます。QT私は多くのテストを行い、コマンドで構成されるパス、CSまたは適切にHT変換されることに気付きました。以下も問題ありませんMS, HS, VS, LS, TC, TH, TL, TV, QA, TA

ただし、コマンドをQS, TS, AS, TT(その順序で) 処理することはできません。

例えば。次のようなパスがあると、変換は失敗します。

M 0 0  T 205.4 112.9  S 260.8 23.36 82.45 72.86 

しかし、これは正しく変換されます:

M 0 0  S 211.9 54.20 52.14 144.4  T 98.85 44.45 

つまり、MTS は問題ありませんが、MST は問題ありません。問題があるのは S と T です。これらは、何かが失敗したときに常に問題となるからです。

ランダム パス ジェネレーターを作成しました(低速ですが、高速化のためにjsbinを使用します)。ランダム パスを取得し、Raphael.path2curve() を使用して Cubic コマンドに変換できます。フィドルで SVG をクリックするか、入力フィールドで Enter キーを押して、新しいランダム パスを取得します。間違ったものを見つけるまで繰り返します。HTML ウィンドウのjsfiddleには、var list = "st";ランダム化するパス コマンドを設定できるパラメーターがあります。

これはサンプル画像です。青が元のパス、赤が変換後のパスです。それらは同一である必要があります。

道

Raphael コードを正しく変換するにはどうすればよいですか?

(私はバグレポートを作成しましたが、問題を数時間解決しようとしましたが、うまくいきませんでした。

4

1 に答える 1

7

やっと直ったようです。テストしてください!2 つの jsbin バージョンを作成しました。

1) 変更されていない Raphael ライブラリを使用する非修正バージョン: jsbin.com/oqojan/33
2) path2curve() 関数が変更された修正バージョン: jsbin.com/oqojan/32

どちらのバージョンにも、黒 (オリジナル) と白 (正規化) のパスがあります。すべてが正常に機能する場合、黒いパスの下に白いパスが表示されないはずです。白いパスが表示される場合は、lib コードにバグがあります (以下の小さなちらつきの説明を参照してください)。

入力フィールドで ENTER を 1 分ほど押し続けてください。ENTER が押されている限り、コードはランダム パスを繰り返し生成します。属性var list = "mlcqahvstz";を変更して、ランダム化の基本文字を変更します。

そして、これがlibコードで何をしなければならなかったかの説明です。オリジナルの Raphaël 2.1.0 lib コードには、次の行を持つ関数 path2curve() があります。

case "S":
    nx = d.x + (d.x - (d.bx || d.x));
    ny = d.y + (d.y - (d.by || d.y));
    path = ["C", nx, ny][concat](path.slice(1));
    break;
case "T":
    d.qx = d.x + (d.x - (d.qx || d.x));
    d.qy = d.y + (d.y - (d.qy || d.y));
    path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
    break;

それらを次のように変更したとき:

case "S":
    if (pcom == "C" || pcom == "S") { // In "S" case we have to take into
                                      // account, if the previous command
                                      // is C/S.
        nx = d.x * 2 - d.bx;          // And reflect the previous 
        ny = d.y * 2 - d.by;          // command's control point relative
                                      // to the current point.  
    }
    else {                            // or some else or nothing
        nx = d.x;
        ny = d.y;
    }
    path = ["C", nx, ny][concat](path.slice(1));
    break;
case "T":
    if (pcom == "Q" || pcom == "T") { // In "T" case we have to take
                                      // into account, if the
                                      // previous command is Q/T.
        d.qx = d.x * 2 - d.qx;        // And make a reflection similar 
        d.qy = d.y * 2 - d.qy;        // to case "S".
    }
    else {                            // or something else or nothing
        d.qx = d.x;
        d.qy = d.y;
    }
    path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
    break;

関数は期待どおりに機能しました (つまり、考えられるすべてのパス コマンドの組み合わせで元のパス形状を尊重します)。pcomvariable は ORIGINAL パスの前のセグメントを参照し、取得する方法も追加する必要がありましたがpcom、これはかなり簡単でした。A 以外のすべてのパス コマンドに関して、元のパス セグメント タイプから 3 次曲線 (C) への変換では 1 つしか生成されないためです。キュービック コマンド。A の場合、関数は複数の C コマンドを生成する場合があります (短い角度で 1 つまたは少数の C セグメントが生成され、角度が大きいほどより多くの C セグメントが生成されます)。

Raphaël はすべての Z を C に変換するため、Z コマンドにわずかな矛盾が生じるだけです。これは、パスの開始 (または終了) の視覚的な外観に影響しますが、大きな違いはありません。Z を C に変換して、パスをアニメート可能にすると仮定します。アニメーションが必要ない場合は、関数を編集して Z:s を変換しないままにすることを検討できます。この場合、変換の忠実度は優れています。

すべてのパス コマンドが 3 次曲線として非常に確実に表現できることに驚いています。

Raphaël の将来のリリースでこのバグが修正されることを願っています。

編集: パス アニメーションのテストベッドも作成:
1) 非修正: http://jsbin.com/oqojan/44
2) 修正済み: http://jsbin.com/oqojan/42

アニメーション化されていないパスとアニメーション化されたパスの両方を徹底的にテストした後、path2curve 関数への修正が安定しており、製品コードに実装できることを確認できました。確実に知りたい場合は、上記のテストベッドを使用してください。

于 2012-10-26T00:49:53.160 に答える