2011-12-14 9 views
3

私はHTMLで色空間をマップしようとしています。私の知識はCSS HTMLとJavascriptにかなり制限されています。私は2つのベクトルに沿って2つの変数で、2次元の勾配を構築する方法を探しています。私の研究は、CSSとSVGの技術は単次元のgrdaientsの能力しか持っていないことを示しています。あるいは、リニアグラードは単一のベクトルしか持てません。この制限を補うために、JSを使用して、2つのRGBカラーチャンネルでグラデーションを得るために必要な256の変更を反復処理しています。たとえば、赤とグラデーション(0〜255)、y軸(相対的に同じ) - 緑とグラデーション(0〜255)、CSS線形ではなくJS反復-grad。HTMLで色空間をマッピング

最後に、RGBカラースペースの美しい表現です!この例ではz軸の青チャンネルを変更すると、新しいCSS線形グラデーションで256個のDOM要素のバックグラウンドを更新する256回のループを繰り返すJS関数を呼び出す必要があります。

現在のWebベースのカラーピッカーでは、Z軸が変更されるたびに256ステップのループが表示されるため、このプログラムには許容できないほどの計算オーバーヘッドが発生します。

デュアルベクトルグラデーションを作成するためのより良い方法はありますか?おそらく私はHTML 5のキャンバス要素のためのアプリ固有のライブラリを作ることができましたか?私がDOM要素の代わりにビットマップ上で操作する場所では、プロセッサの通話単価を大幅に下げることができますか?

答えて

2

基本的に、透明から任意のrgbaカラーに移動する2つの直線勾配、水平1つの垂直を作成します。次にキャンバス上にもう一方のグラデーションを描画します。しかし、私はキャンバスが非常にきれいなrgbaグラデーションを作っていないことを発見しましたが、半透明の色を使用し、最初のものを1回、2回目のものを2回、次に最初のものをもう一度描きます。かなり良い結果を出します。あなたはそれで遊ぶことができます、ここでいくつかのコードをオフに動作します。ここで

var Draw = function(clr1, clr2){ 
     clr1 = clr1 || 'rgba(255, 0, 0, 0.5)'; 
     clr2 = clr2 || 'rgba(0, 0, 255, 0.5)'; 

     var bg1 = document.getElementById('canvas').getContext('2d'),    
      grad1 = bg1.createLinearGradient(0, 128, 256, 128), 
      grad2 = bg1.createLinearGradient(128, 0, 128, 256); 

     grad1.addColorStop(0, 'rgba(255, 0, 0, 0)'); 
     grad1.addColorStop(1, clr1); 

     grad2.addColorStop(0, 'rgba(0, 0, 255, 0)'); 
     grad2.addColorStop(1, clr2); 

     bg1.fillStyle = grad1; 
     bg1.fillRect(0, 0, 256, 256); 


     bg1.fillStyle = grad2; 
     bg1.fillRect(0, 0, 256, 256); 
     bg1.fillRect(0, 0, 256, 256); 

     bg1.fillStyle = grad1; 
     bg1.fillRect(0, 0, 256, 256); 
    } 
+0

。私はそれをもう少し試してみて、何か効果があるかどうか見てみましょう。他のすべてが失敗した場合は、改良された方法でキャンバス用の小さなライブラリを作成するかもしれません、と私は本当にリニアグラデーションメソッドはとにかくモードの恩恵を受けることができると思う。 – user1078253

1

は、ピクセル単位の制御で、キャンバス上で任意のグラデーションを作成する方法を示す簡単な例です:私はそれをうまくすることができましたhttp://jsfiddle.net/j85FQ/3/

enter image description here

colorField(myCanvas, 500, 500, pretty); 

function colorField(canvas,width,height,colorLookup){ 
    var w = width-1, h = height-1; 
    canvas.width = width; 
    canvas.height = height; 
    var ctx = canvas.getContext('2d'), 
     idata = ctx.getImageData(0,0,width,height), 
     data = idata.data; 
    for (var x=0;x<width;++x){ 
    for (var y=0;y<height;++y){ 
     var rgba = colorLookup(x/w,y/h); 
     var o = (width*y+x)*4; 
     for (var i=0;i<4;++i) data[o+i] = rgba[i]*255; 
    } 
    } 
    ctx.putImageData(idata,0,0); 
} 

function pretty(xPct,yPct){ 
    return [ xPct, yPct, xPct*(1-yPct), 1]; 
} 
+0

FWIW複雑な色のルックアップを使って3つの300×300のキャンバスを塗りつぶすには、コンピュータを〜40ms必要とします。 – Phrogz

0

みんなありがとうキャンバス要素で私は、zチャネル値にはバケット塗りを使用し、xとyチャネルには0〜255の水平方向の勾配&を使用しました。 context.globalCompositeOperation = "ライター"を設定することは、私が欠けていたキーでした。これは単純な加算モードでしたが、適切なアルファ合成方法を見つけるのがはるかに簡単でした。以下は、私が書いたキャンバスのinit関数です。しかし、私は私がRGB色空間で探していた結果を生成するために微調整することができないと思う、私はHSL色空間のための効果的なオーバーレイを作ることができた非常によく似た方法を使用して

function init() { 
    var c = document.getElementById('myCanvas'); 
    var ctx = c.getContext('2d'); 
    ctx.globalCompositeOperation = "lighter"; 
    var grd = ctx.createLinearGradient(0, 0, 512, 0); 
    grd.addColorStop(0, "#000000"); 
    grd.addColorStop(1, "#FF0000"); 
    var grd2 = ctx.createLinearGradient(0, 0, 0, 512); 
    grd2.addColorStop(0, "#000000"); 
    grd2.addColorStop(1, "#00FF00"); 
    ctx.fillStyle = "#0000FF"; 
    ctx.fillRect(0, 0, 512, 512); 
    ctx.fillStyle = grd; 
    ctx.fillRect(0, 0, 512, 512); 
    ctx.fillStyle = grd2 
    ctx.fillRect(0, 0, 512, 512) 
    } 
関連する問題