I'm trying to make a whiteboard in body tag with canvas but can't pass event to input tag under canvas.
Is it possible to pass a mouse click event to the input tag under canvas tag without change order of tag or z-index?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
position: relative;
}
canvas {
position: absolute;
top: 0;
left: 0;
background: rgba(255, 0, 0, 0.5);
}
input {
/* position: absolute;
top: 100px;
left: 60px; */
color: #000;
border: 1px solid #000;
}
</style>
<script>
window.onload = function () {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
MARGIN = 35,
RADIUS = canvas.width / 2 - MARGIN;
context.beginPath();
context.arc(
canvas.width / 2,
canvas.height / 2,
RADIUS,
0,
Math.PI * 2,
true
);
context.stroke();
};
</script>
</head>
<body>
<div>
<input type="text" placeholder="input tag" />
<canvas id="canvas" width="500" height="500">
Canvas not supported
</canvas>
</div>
</body>
</html>
You can set the CSS pointer-events property on the canvas to none.
Original example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
position: relative;
}
canvas {
position: absolute;
top: 0;
left: 0;
background: rgba(255, 0, 0, 0.5);
pointer-events: none;
}
input {
/* position: absolute;
top: 100px;
left: 60px; */
color: #000;
border: 1px solid #000;
}
</style>
<script>
window.onload = function () {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
MARGIN = 35,
RADIUS = canvas.width / 2 - MARGIN;
context.beginPath();
context.arc(
canvas.width / 2,
canvas.height / 2,
RADIUS,
0,
Math.PI * 2,
true
);
context.stroke();
};
</script>
</head>
<body>
<div>
<input type="text" placeholder="input tag" />
<canvas id="canvas" width="500" height="500">
Canvas not supported
</canvas>
</div>
</body>
</html>
The events that are related to the canvas (click, mousedown, mousemove ect.) are not related to or specific for the canvas element. If you can track the mouse or a pointer device over the same area, that is fine. So, here I have the event listeners on the parent <div>
for the canvas. The <div>
contains the canvas and has the same coordinate point in the upper left corner. So, the canvas can still have the property pointer-events set to none, and you can use the <div>
for tracking the position of the mouse/pointer device.
I changed the CSS position properties to a grid layout, where the input element and the canvas are placed in the same grid area, and therefore still overlapping. A kind of modern version of the position property...
const canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
container = document.getElementById("container");
var MARGIN = 35,
RADIUS = canvas.width / 2 - MARGIN;
container.mousedown = false;
context.beginPath();
context.arc(
canvas.width / 2,
canvas.height / 2,
RADIUS,
0,
Math.PI * 2,
true
);
context.stroke();
container.addEventListener('mousedown', e => {
let container = e.target.closest('#container');
container.mousedown = true;
});
document.addEventListener('mouseup', e => {
container.mousedown = false;
});
container.addEventListener('mousemove', e => {
let container = e.target.closest('#container');
let canvasX = e.clientX - container.offsetLeft;
let canvasY = e.clientY - container.offsetTop;
if (container.mousedown) draw(canvasX, canvasY);
});
function draw(x, y) {
context.beginPath();
context.arc(x, y, 5, 0, Math.PI * 2, true);
context.fill();
}
body {
margin: 10px 0 0 50px;
}
div#container {
display: grid;
}
canvas {
background: rgba(255, 0, 0, 0.5);
pointer-events: none;
grid-column: 1;
grid-row: 1;
}
input {
grid-row: 1;
grid-column: 1;
place-self: start;
color: #000;
border: 1px solid #000;
}
<div id="container">
<input type="text" placeholder="input tag" />
<canvas id="canvas" width="500" height="500">
Canvas not supported
</canvas>
</div>