Первоначальная версия была очень глючной, поэтому, немного подумав и изучив использование css переменных и обнаружение этого , я изменил исходную версию и пришел к следующему, который, кажется, работает нормально (в Google Chrome в любом случае):
<html>
<head>
<title>Position square over canvas at cursor position</title>
<style>
:root{
/* set some initial values for the css variables */
--width:50px;
--px:0px;
--py:0px;
--bw:0px;
--display:block;
cursor:crosshair;
}
canvas{
width:300px;
height:300px;
border:var(--bw) solid black;
border-radius:0.5rem;
display:inline-block;
position:absolute;
margin:10rem;
}
#overlay{
position:absolute;
left:var(--px);
top:var(--py);
width:var(--width);
height:var(--width);
display:var(--display);
opacity:0.7;
background-color:red;
border:var(--bw) solid black;
border-radius:0.5rem;
cursor:crosshair;
}
</style>
<script>
document.addEventListener('DOMContentLoaded',()=>{
let canvas=document.querySelector('canvas');
let ctxt=canvas.getContext('2d');
ctxt.fillStyle = '#d1defa';
ctxt.fillRect( 0, 0, canvas.width, canvas.height );
let bounds=canvas.getBoundingClientRect();
const id='overlay';
const width=50;
const bw=2;
/* modify initial values of css variables */
let root=document.documentElement;
root.style.setProperty( '--width', width+'px' );
root.style.setProperty( '--px', bounds.left+'px' );
root.style.setProperty( '--py', bounds.top+'px' );
root.style.setProperty( '--bw', bw+'px' );
let img=new Image();
img.onload=()=>{
ctxt.drawImage( img, 0, 0, canvas.width, canvas.height );
}
img.src='https://cdn.pixabay.com/photo/2013/07/12/16/38/pumpkin-151302_960_720.png';
const createsquare=function(id){
let div=document.getElementById(id);
if( div ) return div;
else {
div=document.createElement('div');
div.id=id;
canvas.parentNode.appendChild( div );
return div;
}
};
/* create the overlay */
createsquare( id );
/* find the accurate position of the cursor */
const mousemovehandler=function( event ){
let e=event || window.event;
let d=( e.target && e.target.ownerDocument ) || document;
d=d.documentElement;
let b=d.body;
e.pageX=e.clientX + ( d + d.scrollLeft || b && b.scrollLeft || 0 ) - ( d && d.clientLeft || b && b.clientLeft || 0 );
e.pageY=e.clientY + ( d && d.scrollTop || b && b.scrollTop || 0 ) - ( d && d.clientTop || b && b.clientTop || 0 );
return {
x:e.pageX,
y:e.pageY
};
};
/* listen for mouse events */
root.addEventListener( 'mousemove',(e)=>{
let obj=mousemovehandler( e );
let px=obj.x - ( width / 2 ) - bw;
let py=obj.y - ( width / 2 ) - bw;
if(
( obj.x > bounds.left ) && ( obj.x - bw < bounds.right + bw )
&&
( obj.y + bw > bounds.top + bw ) && ( obj.y - bw < bounds.bottom + bw )
){
/* set the position of the overlay */
root.style.setProperty('--display', 'block');
root.style.setProperty('--px', px +'px');
root.style.setProperty('--py', py +'px');
} else {
/* hide the overlay */
root.style.setProperty('--display', 'none');
}
});
});
</script>
</head>
<body>
<canvas></canvas>
</body>
</html>