在画布上绘制灯光

Drawing lights on a canvas

本文关键字:绘制      更新时间:2023-09-26

嗨,我正试图在画布上绘制灯光,如下所示:

<canvas id="myCanvas" width="600" height="300"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "rgba(0,0,0,0.75)";
ctx.fillRect(0,0,300,300);
ctx.clearRect(0,0,300,300);
var grd = ctx.createRadialGradient(150,150,0,150,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(0,0,300,300);
ctx.clearRect(300,0,600,300);
var grd = ctx.createRadialGradient(450,150,0,450,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(300,0,600,300);
</script>

问题是当灯光与重叠时

<canvas id="myCanvas" width="500" height="300"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "rgba(0,0,0,0.75)";
ctx.fillRect(0,0,300,300);
ctx.clearRect(0,0,300,300);
var grd = ctx.createRadialGradient(150,150,0,150,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(0,0,300,300);
ctx.clearRect(200,0,500,300);
var grd = ctx.createRadialGradient(350,150,0,350,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(200,0,500,300);
</script>

我需要灯合在一起,不要重叠我还需要在画布下面看到一张图片我该如何解决?

这就是我要找的的效果

我用了2块画布,1块用于风景,1块以上用于灯光

这几乎就是我想要的,但在光线重叠的地方仍然有点暗,每盏灯的中心光线太少,看起来像白光而不是黄光http://jsfiddle.net/vgmc4m87/

感谢

如果你真的想重叠这两个梯度,我建议你做一些事情,

  • 去掉clearRect()
  • 更改grd.addColorStop(0, "rgba(255,255,0,0)"); grd.addColorStop(1, "rgba(0,0,0,0.75)"); 这样,第二个颜色停止具有0个alpha分量,这样,当梯度朝向圆的边缘时,它实际上会逐渐消失。实际上,只有当圆在接近尾声时才可以重叠
  • 不要使用fillRect(),而是使用圆弧

参见,https://jsfiddle.net/fL4xffnq/3/.我没有保留颜色,但它应该会给你一个如何进行的好主意。

jsFiddle:https://jsfiddle.net/CanvasCode/p3k7cwqs/

javascript

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
var image = new Image();
image.src = "http://images4.fanpop.com/image/photos/16000000/Beautiful-Cat-cats-16096437-1280-800.jpg";
image.onload = function () {
    ctx.drawImage(image, 0, 0, 500, 400);
    var grd = ctx.createRadialGradient(150, 150, 0, 0, 150, 200);
    grd.addColorStop(0, "rgba(255,255,0,1)");
    grd.addColorStop(1, "rgba(0,0,0,0)");
    ctx.beginPath();
    ctx.fillStyle = grd;
    ctx.arc(150, 150, 200, 0, Math.PI * 2, false)
    ctx.fill();
    var grd = ctx.createRadialGradient(350, 150, 0, 350, 150, 200);
    grd.addColorStop(0, "rgba(255,255,0,1)");
    grd.addColorStop(1, "rgba(0,0,0,0)");
    ctx.beginPath();
    ctx.fillStyle = grd;
    ctx.arc(350, 150, 200, 0, Math.PI * 2, false)
    ctx.fill();
};

添加到@nisargjhaveri的答案设置ctx.globalCompositeOperation = "lighter"会产生不错的效果。

function drawBackground() {
  var can = document.getElementById('background');
  var ctx = can.getContext('2d');
  var grd = ctx.createLinearGradient(0, 0, 0, 150);
  grd.addColorStop(0, "rgba(0,255,255,1)");
  grd.addColorStop(1, "rgba(30,100,200,1)");
  ctx.fillStyle = grd;
  ctx.fillRect(0, 0, 500, 150);
  var grd = ctx.createLinearGradient(0, 150, 0, 300);
  grd.addColorStop(0, "rgba(15,75,25,1)");
  grd.addColorStop(1, "rgba(30,150,50,1)");
  ctx.fillStyle = grd;
  ctx.fillRect(0, 150, 500, 300);
}
drawBackground();
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var bg = document.getElementById("background");
var x1 = 150;
var y1 = 150;
var x2 = 350;
var y2 = 150;
var step1 = {
  x: 1,
  y: 1
};
var step2 = {
  x: -1,
  y: 1
};
function loop() {
  ctx.save();
  ctx.fillStyle = "rgba(0,0,0,1)";
  ctx.clearRect(0, 0, 500, 300);
  // Create a white to transparent gradient for the circles
  
  // Circle one
  var grd = ctx.createRadialGradient(x1, y1, 0, x1, y1, 150);
  grd.addColorStop(.75, "rgba(255,255,0,1)");
  grd.addColorStop(1, "rgba(255,255,0,0)");
  ctx.beginPath();
  ctx.fillStyle = grd;
  ctx.arc(x1, y1, 150, 0, Math.PI * 2, false)
  ctx.fill();
  // Circle two
  var grd = ctx.createRadialGradient(x2, y2, 0, x2, y2, 150);
  grd.addColorStop(.75, "rgba(255,255,255,1)");
  grd.addColorStop(1, "rgba(255,255,255,0)");
  ctx.beginPath();
  ctx.fillStyle = grd;
  ctx.arc(x2, y2, 150, 0, Math.PI * 2, false)
  ctx.fill();
  
  // Fill the white part with the background image.
  ctx.globalCompositeOperation = "source-atop";
  ctx.drawImage(bg, 0, 0, bg.width, bg.height);
  
  // Fill the transparent part with gray.
  ctx.globalCompositeOperation = "destination-atop"
  ctx.fillStyle = "rgba(63,63,63,1)";
  ctx.fillRect(0, 0, c.width, c.height);
  
  // clear the globalCompositeOperation
  ctx.restore();
  step1.x = x1 > c.width ? -1 : x1 < 0 ? 1 : step1.x;
  step1.y = y1 > c.height ? -1 : y1 < 0 ? 1 : step1.y;
  step2.x = x2 > c.width ? -1 : x2 < 0 ? 1 : step2.x;
  step2.y = y2 > c.height ? -1 : y2 < 0 ? 1 : step2.y;
  x1 += step1.x;
  y1 += step1.y;
  x2 += step2.x;
  y2 += step2.y;
  setTimeout(loop, 1000 / 60);
}
loop()
<canvas id="background" width="500" height="300" style='display:none'></canvas>
<canvas id="myCanvas" width="500" height="300"></canvas>