Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Layering two Canvas' on top of each other + click event

I want to layer two Canvas' elements on top of each other. They are used for a game, where the lower Canvas will display a hexgrid while the upper Canvas is meant to display issues/orders (basicly arrows or hex-highlighting - i dont want to redraw a massive hexgrid a zillion times) given by the player.

The Canvas's are layered by zIndex 1/2.

However, the problem is: The orders which are displayed on the top Canvas are supposed to be drawn in response to "click" and "mousemove" events to the bottom Canvas.

Obviously, by layering the "orders" Canvas on top of the "hexgrid" canvas, any mousemove and click events will not be triggered by the "hexgrid" canvas anymore, since it doesnt receive the events anymore.

Is there a way to "forward", i.e. propagate events from one element to another element or what would be another smart way to solve my problem ?

like image 706
Christian F Avatar asked Oct 06 '15 06:10

Christian F


People also ask

Can you put a canvas on top of a canvas?

No, however, you could layer multiple <canvas> elements on top of each other and accomplish something similar. Draw your first layer on the layer1 canvas, and the second layer on the layer2 canvas. Then when you clearRect on the top layer, whatever's on the lower canvas will show through.


2 Answers

May be you need to listen event on root element of canvases? And after in event you will collect data from both of them and process it?

<div onclick="...">
     <canvas>
     <canvas>
</div>

Have experience with such situations, canvases took all the space of the root and coordinates inside div are same for canvas.

like image 141
Anton M. Avatar answered Oct 05 '22 05:10

Anton M.


I wold propagate the event to next canvas, if canvases are overlapped the coordinates will be the same. There can be created a trigger for objects defined inside covered canvas.

var Game = {canvas1: undefined, canvas2: undefined};

Game.canvas1 = document.getElementById('canvas1');
Game.canvas1.addEventListener('click', on_canvas_click1, false);

Game.canvas2 = document.getElementById('canvas2');
Game.canvas2.addEventListener('click', on_canvas_click2, false);

function on_canvas_click1(ev) {
    //do your stuff
    on_canvas_click2(ev);
}

function on_canvas_click2(ev) {
   
	 var mousePos = getMousePos(Game.canvas2, ev);
    
        var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y + "  target: " + mousePos.target + " Id: " +  mousePos.target.getAttribute("id");;
        writeMessage(Game.canvas2, message);   
}


function writeMessage(canvas, message) {
        var context = canvas.getContext('2d');
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.font = '8pt Calibri';
        context.fillStyle = 'black';
        context.fillText(message, 10, 25);
      }
function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top,
          target: evt.target 
        };
      }
<canvas id="canvas1" width="400" height="400" style="border: 1px solid black"></canvas>

<canvas id="canvas2" width="400" height="400" style="border: 1px solid black"></canvas>
like image 45
SilentTremor Avatar answered Oct 05 '22 05:10

SilentTremor