2017-04-15 17 views
0

私はHTML5 Canvas要素を使用してゲームを作成しています。視覚効果の1つとしてグロー効果(光のような)を作りたいと思います。以前はグロー効果のために、シェイプのシェイプを作成するという解決策が見つかりましたが、シェイプを描画するにはソリッドシェイプまたはオブジェクトが必要です。私が探しているのは、光源の位置を持つ周囲の光のようなものを作成する方法ですが、その位置にはオブジェクトはありません。効率的なHTML5キャンバスグローエフェクト(形状なし)

中心点xyを定義し、最後の1pxよりも大きく、それぞれが非常に低い不透明度を持つ数百の同心円を作成して、一緒にソリッドセンターと透明エッジを作成することが考えられました。しかし、これは非常に計算量が重く、結果として得られるグローが厄介なように見えるので、エレガントに見えません。

解決策がA)計算上明るい場合、B)修正された光の方向を作成する場合、またはそれ以上の効果が得られる場合、ボーナスポイントはここでやめてください。 C)画面全体がマスクで暗くなり、光がある場所で陰が上がる「反転」ライトシステムを作成する方法がある場合。

私はいくつかの検索を行っていますが、特に明るい結果は得られていません。

+0

あなたは、少なくともあなたの心に持っているもののいくつかのモックアップを含めることができます。それはかなり広範に見えます。しかし、探知すべき事柄:放射状グラジエントとフィルターブラー+ gCOブレンディングモードの組み合わせ? – Kaiido

答えて

2

私はあなたが何を望んでいるのかよく分かりませんが、次のスニペットが役立つことを願っています。

多くの同心円を作成する代わりに、1つの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