Теперь свет можно отдельно использовать:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="400" height="250" style="border: 1px solid red"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
class Light {
constructor(x, y, power, degree0 = 0, degree1 = 360, color0 = 'rgba(255,255,255,0.75)', color1 = 'rgba(255,255,255,0)') {
this.x = x;
this.y = y;
this.radius0 = power * 50;
this.radius1 = power * 100;
let degree = Math.PI / 180;
this.angle0 = degree0 * degree;
this.angle1 = degree1 * degree;
this.color0 = color0;
this.color1 = color1;
}
draw(ctx) {
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.arc(this.x, this.y, this.radius1, this.angle0, this.angle1);
let grd = ctx.createRadialGradient(this.x, this.y, this.radius0, this.x, this.y, this.radius1);
grd.addColorStop(0, this.color0);
grd.addColorStop(1, this.color1);
ctx.fillStyle = grd;
ctx.fill();
}
}
class Dark {
constructor(width, height, color = 'rgba(0,0,0,0.75)') {
let offscreen = document.createElement('canvas');
this.ctx = offscreen.getContext('2d');
this.width = offscreen.width = width;
this.height = offscreen.height = height;
this.lights = [];
this.color = color;
}
draw(ctx) {
this.ctx.clearRect(0, 0, this.width, this.height);
this.ctx.globalCompositeOperation = 'source-over';
this.ctx.fillStyle = this.color;
this.ctx.fillRect(0, 0, this.width, this.height);
this.ctx.globalCompositeOperation = 'destination-out';
for (let light of this.lights) light.draw(this.ctx);
ctx.drawImage(this.ctx.canvas, 0, 0);
}
}
let dark = new Dark(100, 250);
dark.lights.push(new Light(50, 50, 0.3));
dark.lights.push(new Light(100, 160, 0.7, 90, 270));
let light = new Light(100, 160, 0.7, -90, 90);
let sun = new Light(350, 50, 0.5, 0, 360, 'rgba(255, 255, 0, 1)', 'rgba(255, 0, 0, 0.1)');
let img = new Image;
img.onload = function() {
ctx.drawImage(img, 660, 290, 400, 250, 0, 0, 400, 250);
dark.draw(ctx);
light.draw(ctx);
sun.draw(ctx);
};
img.src = 'https://javascript.ru/forum/attachments/misc/3976d1534094922-igra-na-js-ehffekt-nochi-game-3-jpg';
</script>
</body>
</html>