在画布上绘制灯光

时间:2015-10-26 16:42:12

标签: javascript canvas

嗨,我正试图在这样的画布上画灯:

<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>

我需要灯光聚集而不重叠  我还需要在画布下面看到一个图像 我该怎么解决?

that's the effect i'm looking for

我使用了2个画布,1个用于风景,1个用于灯光

这几乎就是我正在寻找的东西,但它仍然有点'偏暗,灯光重叠,每个灯光中心的光线太少,看起来像白光而不是黄灯 http://jsfiddle.net/vgmc4m87/

由于

3 个答案:

答案 0 :(得分:1)

如果你真的想重叠这两个渐变,我会提出一些建议,

  • 摆脱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/。我没有保留颜色,但它应该让你知道如何继续。

答案 1 :(得分:0)

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

&#13;
&#13;
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()
&#13;
<canvas id="background" width="500" height="300" style='display:none'></canvas>
<canvas id="myCanvas" width="500" height="300"></canvas>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

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();
};