2014-07-08 48 views
0

我想在html5 canvas元素中使用基於單位/法向矢量的漸變,然後將它們轉換爲所需的結果。但是,我似乎認爲這可能是因爲我缺乏數學。我試圖創建一個從0,0到1,0的簡單線性漸變(即從左到右的簡單單位漸變)。之後,我轉換畫布進行縮放,旋轉和移動漸變。但是,例如,如果給出45DEG的旋轉值,則實際梯度會出現錯誤。右下角的方式非常黑,即漸變看起來不夠「大」。這裏是我的代碼:畫布和單位/正常梯度

var rect = {x: 0, y: 0, w: 500, h: 500}; 
var rotation = 45 * Math.PI/180; 
var sx = 1; 
var sy = 1; 
var tx = 0; 
var ty = 0; 
var radial = false; 

// Create unit vector 0,0 1,1 
var grd = radial ? ctx.createRadialGradient(0, 0, 0, 0, 0, 0.5) : ctx.createLinearGradient(0, 0, 1, 0); 
grd.addColorStop(0, 'black'); 
grd.addColorStop(0.1, 'lime'); 
grd.addColorStop(0.9, 'yellow'); 
grd.addColorStop(1, 'black'); 

// Add our rectangle path before transforming 
ctx.beginPath(); 
ctx.moveTo(rect.x, rect.y); 
ctx.lineTo(rect.x + rect.w, rect.y); 
ctx.lineTo(rect.x + rect.w, rect.y + rect.h); 
ctx.lineTo(rect.x, rect.y + rect.h); 
ctx.closePath(); 

// Rotate and scale unit gradient 
ctx.rotate(rotation); 
ctx.scale(sx * rect.w, sy * rect.h); 
ctx.fillStyle = grd; 

// Fill gradient 
ctx.fill(); 

而這裏的小提琴嘗試一下:

http://jsfiddle.net/4GsCE/1/

好奇的是,改變單位線性漸變向量的一個因素約爲1.41,使梯度看的權利:

ctx.createLinearGradient(0, 0, 1.41, 0) 

可以在這個小提琴可以看出:

http://jsfiddle.net/4GsCE/2/

但我不知道如何計算該因子?

回答

0

由於您想使用標準化漸變,您必須決定如何標準化。在這裏你選擇以漸變爲中心,並使其(x,y)在[-0.5,0.5]範圍內。
第一個問題是線性漸變不居中,它在[0,1.0]範圍內。
歸他們以同樣的方式:

var linGrd = ctx.createLinearGradient(-0.5, 0, 0.5, 0); 

第二個問題是,你必須翻譯你圖的中心,那麼規模,然後以標準化的方式繪製。
含義您必須使用與您的漸變相同的座標系統。
由於您既繪製了具有(w,h)尺寸的形狀,又使用了(w,h)的比例尺,因此您正在繪製一個尺寸爲()的尺寸爲()的尺寸爲(w)的尺寸。
正確的抽獎代碼是這一個:

function drawRect(rect, fill) { 
    ctx.save(); 
    // translate to the center of the rect (the new (0,0)) 
    ctx.translate(rect.x + rect.w/2, rect.y + rect.h/2); 
    // Rotate 
    ctx.rotate(rotation); 
    // scale to the size of the rect 
    ctx.scale(rect.w, rect.h); 
    // ... 
    ctx.fillStyle = fill; 
    // draw 'normalized' rect 
    ctx.fillRect(-0.5, -0.5, 1, 1); 
    ctx.restore(); 
} 

注意,默認的RadialGradient將以0.5,這意味着,端的距離,如果你正在填補一個矩形,這將填補四角採用的最後一種顏色漸變。也許你想要角落結束漸變。
在這種情況下,你想有梯度在距離達到它的價值:

sqrt (0.5*0.5 + 0.5*0.5) = 0.7 (pythagore in the normalized circle) 

所以你定義喜歡你的歸一化的梯度:

var fullRadGrd = ctx.createRadialGradient(0, 0, 0, 0, 0, 0.7) ; 

http://jsfiddle.net/gamealchemist/4GsCE/4/

enter image description here

+0

哇,很好的答案。其實,就在幾分鐘之前,我已經想出了線性漸變的中心問題:) – anderswelt