2011-08-12 14 views
1

私はHTML5 lineToを使用していますが、1より大きいストロークは、線の四角形のコーナーを作成します(線は描画する線のパスに垂直に伸びます)。 http://muro.deviantart.comに似た円形のブラシチップを作成したいと思います。HTML5キャンバス描画アプリケーションで円形の「ブラシチップ」を作成するにはどうすればよいですか?

アイデア?

+0

あなたは 'ctx.lineCap'を見ましたか?おそらくそれはあなたの後です。 – pimvdb

答えて

3

コーナーは、ラインキャップを設定することで丸められます。

ctx.lineCap = "round"

また、ラインの各点のために、によって、スムーズな全体的なラインを作成するために、全体的なラインにベジェ曲線を適用することができますP「、...、P」のn + 1 、式P」 K =(K /(N + 1))P K-1 +(1-(K /(N + 1)))P K[NB適用:あなたがかもしれないししきい値を設定することによってベジェ曲線のスムージングを適用するポイントを選択することもできます。おそらくP nとP のn + 1]

ライン自体に標準ボックスブラーでこれら2つの手法を組み合わせることで、あなたにずっとスムーズに表示される行を提供します。あなたは完全にあなた次第です使用 -

私が言うことができるものから、編集

が、実際にこれを行うにはいくつかの方法があります。私はあなたに例を挙げて、あなたに決めさせよう:最初の点p m(mousedown)から終点(マウスアップ)までの道があると仮定しよう。 n。そのパスは、サブパス(マイターによって結合された点)で構成されています。コンテキストにパスを描画するには、p0からp1までlineTo()およびstroke()を通常どおりに行います。コンソール出力を見るだけで、サブパスが結合するポイントはmousemoveイベントの発生です。これらの点を配列順に記録します。

もちろん、これをメインコンテキストに描画すると問題がありますので、これをバッファコンテキスト(たとえば、追加のcanvas要素)に行う必要があります。バッファーはクリアされ、マイターのポイントを使用してカーブを計算します。いるbezierCurveToはキュービック関数(B(T)=(1-T) Pを印刷 +3(1-T) P +3(1-T)T P + T P 、T ∈ [0,1]。あなたのアレイをステップ、これらの点の行を再計算0 N-3 P にP から曲線を更新する(forループと思います)。(頭部をすばやく計算するこのエンドポイントを考える必要があるかもしれませんが、これはどのアーク方程式を使用するかによって異なります)

私はこれで何かできるかどうか見てみましょう...私はバグを保証するためにそれをテストしていません。

// Assume: 
// bfr = buffer context. 
// ctx = main context. 
// md = boolean value for mousedown 
// pts = []; <-- already contains lp (below) at pts[0]; 
// We've also recorded Pm in associative array lp [last point] 
// Draw is fired on mousemove. Mousemove records a current point in associative array cp 
draw = function() { 
    if(md) { 
     bfr.beginPath(); 
     bfr.moveTo(lp.x-.5, lp.y-.5); 
     bfr.lineTo(cp.x-.5, cp.y-.5); 
     pts.push({cp.x, cp.y}); 
     bfr.stroke(); 
    } 
} 

// Optionally, you could make this function recursive. 
// This assumes that you want to estimate the curve based on the whole line. 
bezier = function(pts) { 
    ctx.beginPath(); 
    ctx.moveTo(pts[0].x, pts[0].y); 
    for(var i = 0; i < pts.length - 3; i++) { 
    ctx.bezierCurveTo(pts[i+1].x, pts[i+1].y, pts[i+2].x, pts[i+2].y, pts[i+3].x, pts[i+3].y); 
    } 
    ctx.stroke(); 
} 

また、これは私が見るものです。他の誰かが完全に異なっている可能性があります。私がやったことの塊を裂き、あなたにいくつかのアイデアを与えるためにいくつかの新しいコードを素早くまとめようとしています。

+0

lineCapのヒントについてのヒント。ありがとう。ベジェ曲線について...私はどのように方程式を「適用」するのですか?私は各点Pを計算した後にlineToを使うだけですか?私はquadraticCurveTo関数とベジェバージョンを発見したが、それらは3または4入力ポイントを取るだけです。どのようにしてブラシストローク全体にベジェ曲線を適用できますか? – Homan

+0

私はカスタム関数を書くだろう。配列に記録されたサンプル点を選択し、曲線を適用します。 'mousemove'が発生する点をサンプリングし、3点の間の角度を決定して、サンプル点に大きな違いがあるかどうかを確認し、そうであればフラグを立てて、カーブを適用します。評価を行うために、フラグ付きの配列の配列を関数に渡します。常に 'mousedown'と' mouseup'を0とn + 1として起動してください。 – stslavik

+0

ユーザーが高速円を描画したとしますが、サンプル点は八角形の角のように分散しています。あなたは、ある種のカスタム関数bezierLine(sample_points)を使ってラインを "曲線"にすることを提案していますか?私はその機能で何が起こるのか理解していませんか?この関数は、すべてのピクセル座標を計算することによってすべての単一ピクセルを描画しますか?または、関数はBezier(t)トラバーサルのtステップパラメータをとります。この場合、関数は最終的にlineToを使用して線を引きます。 – Homan