高效的HTML5画布发光效果,无形状 [英] Efficient HTML5 Canvas Glow Effect without shape

查看:131
本文介绍了高效的HTML5画布发光效果,无形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆