高效的HTML5画布发光效果,无形状 [英] Efficient HTML5 Canvas Glow Effect without shape
问题描述
我正在使用HTML5 Canvas元素创建游戏,作为视觉效果之一,我想创建发光效果(如灯光)。以前,对于发光效果,我发现了涉及创建形状阴影的解决方案,但是这些方法需要使用实体形状或对象才能投射阴影。我正在寻找的是一种创建具有源位置但周围没有对象的环境光发光的方法。
I am creating a game using the HTML5 Canvas element, and as one of the visual effects I would like to create a glow (like a light) effect. Previously for glow effects I found solutions involving creating shadows of shapes, but these require a solid shape or object to cast the shadow. What I am looking for is a way to create something like an ambient light glow with a source location but no object at the position.
我想到的是定义一个中心点 x
和 y
并创建数百个同心圆,每个同心圆都比上一个大1px,并且每个点都非常低不透明性,因此它们共同创建了坚实的中心和透明的边缘。但是,这在计算上非常繁琐,而且看起来一点也不优雅,因为产生的辉光看起来很尴尬。
Something I have thought of was to define a centerpoint x
and y
and create hundreds of concentric circles, each 1px larger than the last and each with a very low opacity, so that together they create a solid center and a transparent edge. However, this is very computationally heavy and does not seem elegant at all, as the resulting glow looks awkward.
虽然这是我要的全部,但我会乐于在此停下来,如果您的解决方案是A)计算上的光,B)可以修改以创建聚焦的光的方向,或者甚至更好,C)如果有办法创建倒置光系统,则可以加分
While this is all that I am asking of and I would be more than happy to stop here, bonus points if your solution is A) computationally light, B) modifiable to create a focused direction of light, or even better, C) if there was a way to create an "inverted" light system in which the entire screen is darkened by a mask and the shade is lifted where there is light.
我进行了几次搜索,但都没有找到任何特别有启发性的结果。
I have done several searches, but none have turned up any particularly illuminating results.
推荐答案
所以我不太确定您想要什么,但是我希望以下代码片段会有所帮助。
So I'm not quite sure what you want, but I hope the following snippet will help.
而不是创建多个同心圆,而是创建一个radialGradient。
然后,您可以将此径向渐变与某些混合效果结合使用,甚至可以根据需要过滤以修改效果。
Instead of creating a lot of concentric circles, create one radialGradient.
Then you can combine this radial gradient with some blending, and even filters to modify the effect as you wish.
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>
这篇关于高效的HTML5画布发光效果,无形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!