2017-04-15 40 views
0

我使用HTML5 Canvas元素創建了一個遊戲,並將其作爲我希望創建輝光(如光線)效果的視覺效果之一。以前爲了發光效果,我找到了創建形狀陰影的解決方案,但這些都需要一個堅實的形狀或物體來投射陰影。我正在尋找的是一種創建類似環境光源的位置,但沒有物體位置的方法。高效的HTML5 Canvas無形狀的輝光效果

東西我想到的是定義一箇中心點xy和創建數百個同心圓,每1px的比上,並且每個具有非常低透明度大,所以他們一起創造了堅實的中心和透明邊界。但是,這個計算量非常大,看起來並不高雅,因爲所產生的輝光看起來很尷尬。雖然這就是我所要求的全部內容,但如果你的解決方案是A)計算光,B)可以修改以創建聚焦的光線方向,甚至更好, C)是否有創建一個「倒置」燈光系統的方法,其中整個屏幕被面罩變暗,而燈罩在有光的地方被擡起。

我已經做了幾次搜索,但沒有人發現任何特別照明的結果。

+0

你能不能至少包括你心中已經有了一些什麼原型。看起來相當寬泛。但要探索的事情:徑向漸變與濾鏡模糊+ gCO混合模式相結合? – Kaiido

回答

2

所以我不太清楚你想要什麼,但我希望下面的代碼片段可以幫助。

而不是創建很多同心圓,創建一個radialGradient。
然後,您可以將此徑向漸變與某些混合相結合,甚至可以根據需要過濾以修改效果。

var img = new Image(); 
 
img.onload = init; 
 
img.src = "https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/car.svg"; 
 
var ctx = c.getContext('2d'); 
 
var gradCtx = c.cloneNode().getContext('2d'); 
 
var w, h; 
 
var ratio; 
 

 
function init() { 
 
    w = c.width = gradCtx.canvas.width = img.width; 
 
    h = c.height = gradCtx.canvas.height = img.height; 
 
    draw(w/2, h/2) 
 
    updateGradient(); 
 
    c.onmousemove = throttle(handleMouseMove); 
 
} 
 

 
function updateGradient() { 
 
    var grad = gradCtx.createRadialGradient(w/2, h/2, w/8, w/2, h/2, 0); 
 
    grad.addColorStop(0, 'transparent'); 
 
    grad.addColorStop(1, 'white'); 
 
    gradCtx.fillStyle = grad; 
 
    gradCtx.filter = "blur(5px)"; 
 
    gradCtx.fillRect(0, 0, w, h); 
 
} 
 

 
function handleMouseMove(evt) { 
 
    var rect = c.getBoundingClientRect(); 
 
    var x = evt.clientX - rect.left; 
 
    var y = evt.clientY - rect.top; 
 
    draw(x, y); 
 
} 
 

 
function draw(x, y) { 
 
    ctx.clearRect(0, 0, w, h); 
 
    ctx.globalCompositeOperation = 'source-over'; 
 
    ctx.drawImage(img, 0, 0); 
 
    ctx.globalCompositeOperation = 'destination-in'; 
 
    ctx.drawImage(gradCtx.canvas, x - w/2, y - h/2); 
 
    ctx.globalCompositeOperation = 'lighten'; 
 
    ctx.fillRect(0, 0, w, h); 
 
} 
 

 
function throttle(callback) { 
 
    var active = false; // a simple flag 
 
    var evt; // to keep track of the last event 
 
    var handler = function() { // fired only when screen has refreshed 
 
    active = false; // release our flag 
 
    callback(evt); 
 
    } 
 
    return function handleEvent(e) { // the actual event handler 
 
    evt = e; // save our event at each call 
 
    if (!active) { // only if we weren't already doing it 
 
     active = true; // raise the flag 
 
     requestAnimationFrame(handler); // wait for next screen refresh 
 
    }; 
 
    } 
 
}
<canvas id="c"></canvas>

+0

所有不錯的,但模糊過濾器將殺死幀速率,爲什麼不當你創建畢業畫布。 – Blindman67

+0

@ Blindman67腦屁?你是完全正確的,這個過濾器只能應用在漸變畫布上......會在返回到鍵盤時修復。 – Kaiido

+0

做到了從我的手機,但無法測試是否它破壞了任何東西(沒有鼠標移動...) – Kaiido