2011-12-14 114 views
3

所以我試圖在HTML中映射色彩空間,我的知識幾乎侷限於CSS HTML和Javascript。我正在尋找一種構建2維梯度的方法,其中2個變量沿着2個向量。我的研究表明,CSS和SVG技術只具有單維度容量。或者說,線性梯度只能有一個向量。所以爲了彌補這個限制,我使用JS來遍歷我需要的256個更改,以便我可以在2個RGB顏色通道上獲得漸變。所以想象一下,如果你將X軸相對於例如目的 - 紅色和從0到255的梯度和同樣相對的Y軸 - 綠色和從0到255的梯度,但是用JS迭代而不是CSS線性-grad。在HTML中映射色彩空間

我最終得到的是RGB色彩空間的美麗表現!但是!在這個例子中改變了z軸 - 藍色通道 - 意味着我必須調用一個JS函數,該函數遍歷256個循環,用新的CSS線性漸變更新256個DOM元素的背景。

由於我在當前基於Web的顏色選擇器中看到的侷限性,我對這個Web應用程序做了一個256步循環,每次更改Z軸都會給程序帶來不可接受的計算開銷。

任何想法是一個更好的方式來做雙向量梯度?也許我可以爲HTML 5 canvas元素製作一個特定於應用程序的庫?在哪裏我將在位圖上而不是DOM元素上運行,這可能會大大降低處理器的每次處理成本?

回答

2

基本上你想要創建兩個線性漸變,一個水平一個垂直,從透明移動到任何你想要的rgba顏色。然後在畫布上繪製一個漸變。雖然有一些問題,但我發現畫布不能製作非常乾淨的rgba漸變色,但是您可以使用半透明顏色,一次繪製第一個,第二個繪製兩次,然後再繪製第一個,並且看起來像給出相當不錯的結果。儘管如此,你可以使用它,下面是一些代碼。

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

使用非常類似的方法,我能夠做出HSL色彩空間的有效覆蓋,但是,我不認爲它可以調整生產我正在尋找在RGB色彩空間的結果。我會再玩一次,看看我能否想出一些有效的東西。如果一切都失敗了,我可以使用改進的方法爲畫布編寫一個小的庫,我真的認爲線性漸變方法可以從'模式'中受益。 – user1078253 2011-12-14 15:49:28

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需要我的電腦〜40毫秒,以複雜的顏色查找填充三個300×300的畫布。 – Phrogz 2011-12-14 21:06:51

0

感謝球員,我能夠做出來與畫布元素。對於x和y通道,我爲z通道值和0到255的水平垂直線性梯度使用了桶填充。設置context.globalCompositeOperation =「打火機」是我失蹤的關鍵。這是我需要簡單的加法模式,然後試圖找到合適的alpha合成方法。以下是我寫的畫布初始化函數。

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) 
    }