Cameron C
Cameron C

Reputation: 123

JavaScript: Is it possible to cut a shape out of a rectangle to make a transparent hole in it?

I am trying to make a 2d top-down game in Javascript at the moment. I've currently got a day/night system working where a black rectangle gradually becomes more opaque (as the day goes on) before it finally is fully opaque, simulating the peak of the night where the player can not see.

I want to implement an artificial light system, where the player could use a torch that will illuminate a small area in-front of them. However, my problem is that I don't seem to be able to find a way to 'cut out' a shape from my opaque rectangle. By cutting out a shape, it would look like the player has a torch.

Please find an example mock-up image I made below to show what I mean. https://i.sstatic.net/OnBlJ.png Obviously the shape shouldn't be as roughly drawn as that :)

Thanks for your time, Cam

EDIT: The code used to draw the rectangle is as follows:

context.fillStyle = "#000033";
    context.globalAlpha = checkLight(gameData.worldData.time);
    context.fillRect(0, 0, 512, 480);
    //This is where you have to add the cut out triangles for light!
    context.stroke();

Upvotes: 1

Views: 1638

Answers (2)

markE
markE

Reputation: 105015

One way is to use declare a triangular clipping area and draw your revealed scene. The scene would display only inside the defined clipping area.

Example code and a Demo:

  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var x = canvas.width / 2;
  var y = canvas.height / 2;
  var radius = 75;
  var offset = 50;

  var img = new Image();
  img.onload = function() {
 knockoutAndRefill(50,100,300,50,75,350);
  };
  img.src = 'http://guideimg.alibaba.com/images/trip/1/03/18/7/landscape-arch_68367.jpg';


function knockoutAndRefill(x0,y0,x1,y1,x2,y2){
  context.save();
  context.fillStyle='black';
  context.fillRect(0,0,canvas.width,canvas.height);
  context.beginPath();
  context.moveTo(x0,y0);
  context.lineTo(x1,y1);
  context.lineTo(x2,y2);
  context.closePath();
  context.clip();
  context.drawImage(img,0,0);
  context.restore();
}
<canvas id=myCanvas width=500 height=400>

Upvotes: 0

Chaz
Chaz

Reputation: 339

Instead of drawing a rectangle over the scene to darken it when the "light" is on, instead draw an image with the "lit" area completely transparent and the rest of the "dark" area more opaque.

Upvotes: 1

Related Questions