我正在使用HTML5 Canvas元素创建游戏,并且作为视觉效果之一,我想创建一个发光(如光)效果。以前对于发光效果我发现了涉及创建形状阴影的解决方案,但这些需要一个实体形状或对象来投射阴影。我正在寻找的是一种方法来创建类似环境光发光的东西,其中包含源位置但位置没有物体。
我想到的是定义一个中心点x
和y
并创建数百个同心圆,每个圆圈比最后一个大1px且每个都具有非常低的不透明度,因此它们一起创建坚实的中心和透明的边缘。然而,这在计算上非常重,并且看起来并不优雅,因为产生的光晕看起来很尴尬。
虽然这就是我所要求的,但我很乐意在这里停下来,如果你的解决方案是A)计算上很轻,B)可以修改,以创建一个聚焦的光方向,甚至更好,C )如果有办法建立一个“倒置”的灯光系统,其中整个屏幕被一个面罩变暗,并且在有光的地方抬起灯罩。
我已经完成了几次搜索,但没有一次搜索出现任何特别有启发性的结果。
答案 0 :(得分:3)
所以我不太确定你想要什么,但我希望以下代码片段会有所帮助。
创建一个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>
&#13;