2017-02-18 10 views
0

私はJavaからJavascriptにシンボル描画ライブラリを移植しています。シンボルはHTML5 Canvasオブジェクトに描画されます。シンボルには、座標と形状のプロパティ(四角、円、十字など)、サイズ、色があります。HTML5 Canvasでシンボル描画ライブラリを実装する正しい方法は何ですか?

私は長年にわたりJavaでこのような作業シンボル描画ライブラリを持っていました。 Javascriptでは、私は色がついていない。シンボルは通常、正しい形状とサイズで描画されますが、必ずしも正しい色で描画されるわけではありません。 1つのシンボルからの色は、(通常は黒で)描画している他の図形軸などのものにも「流出」することがあります。だから私はどのようにシンボルを描画の "原子的な"単位とするためにシンボルを作って、私が描いている他のものに副作用がないのでしょうか?私は、パスとサブパスの概念とコンテキストがどのような状態を格納しているのか分からないように感じます。私はこの問題の解決策を広範に探求してきましたが、何も問題が見つかっていません。ここで

は私のシンボルライブラリからのいくつかの典型的なコードです:

function plotSymbol(ctx, symbol, h, v, width, symcolor) { 
    var i; 
    if (width == 0) return; 

    if (symbol == Resources.PlotSymbolsEnum.SYMBOL_SQUARE) { 
     ctx.strokeStyle = symcolor; 
     ctx.strokeRect(h - width/2.0, v - width/2.0, width, width); 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_SQUAREFILLED) { 
     ctx.fillStyle = symcolor; 
     ctx.fillRect(h - width/2.0, v - width/2.0, width, width); 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CIRCLE) { 
     var x = h - width/2; 
     var y = v - width/2; 
     drawCircle(ctx, x, y, width/2, 1, symcolor, false); 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CIRCLEFILLED) { 
     var x = h - width/2; 
     var y = v - width/2; 
     drawCircle(ctx, x, y, width/2, 1, symcolor, true); 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_DIAMOND) { 
     var xpoints1 = [ h, h + width/2, h, h - width/2 ]; 
     var ypoints1 = [ v - width/2, v, v + width/2, v ]; 

     ctx.strokeStyle = symcolor; 
     ctx.beginPath(); 
     ctx.moveTo(xpoints1[0], ypoints1[0]); 
     for (i = 1; i < xpoints1.length; i++) { 
      ctx.lineTo(xpoints1[i], ypoints1[i]); 
     } 
//  ctx.closePath(); 
     ctx.stroke(); 
     ctx.strokeStyle = 'black'; 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_DIAMONDFILLED) { 
     var xpoints2 = [ h, h + width/2, h, h - width/2 ]; 
     var ypoints2 = [ v - width/2, v, v + width/2, v ]; 

     ctx.fillStyle = symcolor; 
     ctx.beginPath(); 
     ctx.moveTo(xpoints2[0], ypoints2[0]); 
     for (i = 1; i < xpoints2.length; i++) { 
      ctx.lineTo(xpoints2[i], ypoints2[i]); 
     } 

//  ctx.closePath(); 
     ctx.fill(); 
     ctx.stroke(); 
     ctx.fillStyle = 'white'; 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_TRIANGLE) { 
     var xpoints3 = [ h - width/2, h + width/2, h ]; 
     var ypoints3 = [ v + width/2, v + width/2, v - width/2 ]; 

     ctx.strokeStyle = symcolor; 
     ctx.beginPath(); 
     ctx.moveTo(xpoints3[0], ypoints3[0]); 
     for (i = 1; i < xpoints3.length; i++) { 
      ctx.lineTo(xpoints3[i], ypoints3[i]); 
     } 

//  ctx.closePath(); 
     ctx.stroke(); 
     ctx.strokeStyle = 'black'; 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_TRIANGLEFILLED) { 
     var xpoints3 = [ h - width/2, h + width/2, h ]; 
     var ypoints3 = [ v + width/2, v + width/2, v - width/2 ]; 

     ctx.strokeStyle = symcolor; 
     ctx.beginPath(); 
     ctx.moveTo(xpoints3[0], ypoints3[0]); 
     for (i = 1; i < xpoints3.length; i++) { 
      ctx.lineTo(xpoints3[i], ypoints3[i]); 
     } 

//  ctx.closePath(); 
     ctx.fill(); 
     ctx.stroke(); 
     ctx.strokeStyle = 'black'; 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CROSS1) { 
     ctx.strokeStyle = symcolor; 
     width += 1; 
     ctx.beginPath(); 
     ctx.moveTo(h - width/2, v); 
     ctx.lineTo(h + width/2, v); 
     ctx.moveTo(h, v - width/2); 
     ctx.lineTo(h, v + width/2); 
//  ctx.closePath(); 
     ctx.stroke(); 
     ctx.strokeStyle = 'black'; 
    } 
    else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CROSS2) { 
     ctx.strokeStyle = symcolor; 
     ctx.beginPath(); 
     ctx.moveTo(h - width/2, v - width/2); 
     ctx.lineTo(h + width/2, v + width/2); 
     ctx.moveTo(h - width/2, v + width/2); 
     ctx.lineTo(h + width/2, v - width/2); 
//  ctx.closePath(); 
     ctx.stroke(); 
     ctx.strokeStyle = 'black'; 
    } 
} 

私はいつも形状は原点に戻るにはしたくないので、私はclosepathsをコメントアウトしています。 closePath()が何をしているのか誤解し、他のシンボルとは独立したシンボルを描くと思っていたので、私はそれらを元々入れました。私は大いにHTML5キャンバスに正しくこれを行うための任意のアドバイスやポインタをいただければ幸いです

ctx.save(); 
ctx.rect(left, y1, width, height); 
ctx.clip(); 
. 
. 
. 
y = this.mMonthlyMeans[i]; 
y = (y - yOrigin) * yScale; 
y = Math.floor(y) + 0.5; 
plotSymbol(ctx, theMeanSym, this.getPlotLeft() + xCtr, y, theMeanSymSize, theMeanSymbolColor); 
ctx.strokeStyle = 'black'; // this call is perhaps unnecessary in properly written code but seems to head off some problems 
. 
. 
. 
ctx.restore() // to restore the clip 

:ここ

そして、それが呼ばれるかもしれない方法です。あなたがctx.stroke()またはctx.strokeXXX()を呼び出す前にstrokeStyleを設定し、あなたの状態のブロックのそれぞれに、ctx.fill()またはctx.fillXXX()fillStyleを設定する必要があります

答えて

0

、単にJavaのようなGraphics2Dオブジェクトにピクセルを描画するのと同じくらい簡単ではありません。

strokeStyleブロックにはSYMBOL_DIAMONDFILLEDブロック、fillStyleブロックには、SYMBOL_TRIANGLEFILLEDブロックがありませんでした。

+0

ありがとう:私ストロークのセグメントを個別に正しい色で描画される全てのシンボルの原因となるよう

は、コードを変更します! –

0

私は解決策を見つけたと信じています。今日について私は、キャンバスオブジェクトに描画するチュートリアル(http://eloquentjavascript.net/16_canvas.html)を見つけました。著者は、

"パスには複数のシェイプを含めることができます - 各moveToモーションは新しいものを開始します。"

これは手がかりを探していました。私は、moveToとlineToを使って十字記号とx記号を描くメソッドを持っています。

ctx.strokeStyle = symcolor; 
    ctx.beginPath(); 
    ctx.moveTo(h - width/2, v); 
    ctx.lineTo(h + width/2, v); 
    ctx.moveTo(h, v - width/2); 
    ctx.lineTo(h, v + width/2); 
    ctx.stroke(); 

間違いが内部のmoveToは新しいサブパスを開始し、ストロークコマンドは、strokeStyle色で最初のサブパスを描画するために表示されるか、使用していることです。これは、(ジャワから移植)私のクロスシンボルコードが気に入って見えたものですデフォルトの色。正味の効果は、ほとんどの記号が正しい色で描かれていますが、最後の記号が黒色に見えるデフォルトの色で描かれている(私は思う)。これらの欠落を指摘して

ctx.strokeStyle = symcolor; 
    ctx.beginPath(); 
    ctx.moveTo(h - width/2, v); 
    ctx.lineTo(h + width/2, v); 
    ctx.stroke(); 

    ctx.beginPath(); 
    ctx.moveTo(h, v - width/2); 
    ctx.lineTo(h, v + width/2); 
    ctx.stroke(); 
関連する問題