2

I want to attach to cursor an element(blue circle) and leave ability to click on that circle. To display this circle correctly - cursor is always in center of circle - I disabled events using pointer-events: none. As a result it blocks ability to click on that circle. Is it possible to block mousemove events, but leave click events?

const CURSOR_SIZE = 30;

const field = document.querySelector('#field');
const cursor = document.querySelector('#cursor');

field.onmousemove = (event) => {
    const { offsetX, offsetY } = event;
  
    const shiftX = offsetX - CURSOR_SIZE;
    const shiftY = offsetY - CURSOR_SIZE;
  
    updateCursorPosition(shiftX, shiftY);
}

function updateCursorPosition(x, y) {
  cursor.style.top = `${y}px`;
  cursor.style.left = `${x}px`;
}

cursor.onclick = () => {
  console.log('handle click')
}
body {
  margin: 0;
  background-color: #e6ffff;
}

#field {
  position: relative;
  width: 100vw;
  height: 100vh;
}

#cursor {
  position: absolute;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: solid 2px #00cccc;
  background-color: #00ffff;
  pointer-events: none;
}
<div id="field">
  <div id="cursor"></div>
<div>

1 Answers1

0

I don't think offsetX/Y is really appropriate for your use case. As you've seen, it returns the position relative to the target node, so you have to make some hack using pointer-events.

This anwser by Atrahasis provides a function to get a mouse event's position relative to a given element. You can use it like this:

const { x, y } = getRelativeCoordinates(event, field);

Applied to your code:

const CURSOR_SIZE = 30;

const field = document.querySelector('#field');
const cursor = document.querySelector('#cursor');

// By Atrahasis, full version here: https://stackoverflow.com/a/36860652/1913729
function getRelativeCoordinates(t,e){const f=t.pageX,o=t.pageY,s={left:e.offsetLeft,top:e.offsetTop};let n=e.offsetParent;for(;n;)s.left+=n.offsetLeft,s.top+=n.offsetTop,n=n.offsetParent;return{x:f-s.left,y:o-s.top}}

field.addEventListener('mousemove', (event) => {
    const { x, y } = getRelativeCoordinates(event, field);
  
    const shiftX = x - CURSOR_SIZE;
    const shiftY = y - CURSOR_SIZE;
  
    updateCursorPosition(shiftX, shiftY);
});

function updateCursorPosition(x, y) {
  cursor.style.top = `${y}px`;
  cursor.style.left = `${x}px`;
}

cursor.addEventListener('click', () => {
  console.log('handle click')
});
body {
  margin: 0;
  background-color: #e6ffff;
}

#field {
  position: relative;
  width: 100vw;
  height: 100vh;
}

#cursor {
  position: absolute;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: solid 2px #00cccc;
  background-color: #00ffff;
}
<div id="field">
  <div id="cursor"></div>
<div>
blex
  • 24,941
  • 5
  • 39
  • 72