简体   繁体   中英

How to position the center of a div to the center of the mouse cursor on mouse movement with JS?

I'm trying to position the center of a div element to the center of the mouse cursor, that will follow along its movements.

Already I came up with the code below, but the problem with this one is, that the following div is not positioned at the center of my cursor, but with some offset off the cursor.

WORKFLOW

The basic idea behind my code is, when the mouse enters the .post-entry div element, the .pointer within the current item should be displayed and follow the cursor of the mouse. When the mouse leaves the div it should be hidden.

CODE

HTML post item:

<article class="col-md-4 col-sm-6 post-entry">
    <a href="#" title="">
        <figure class="post-thumb">
            <img src="http://placehold.it/300x300" alt="">
            <div class="pointer" style="background: red;"></div>
        </figure><!-- End figure.post-thumb -->
    </a>
</article><!-- End article.col-md-4 post-entry -->

JS:

$('.entry .post-entry').each(function() {
  $(this).on("mouseenter", mouseEnter);
  $(this).on("mousemove", mouseMove);
  $(this).on("mouseleave", mouseLeave);
});


function mouseEnter(event) {

  console.log('enter');

  var target = $(this);
  var dot = target.find('.pointer');

  var mX = (event.clientX);
  var mY = (event.clientY);

  set(
    dot, {
      x: mX,
      y: mY,
      force3D: !0
    }
  );

};


function mouseMove(event) {

  console.log('move');

  var target = $(this);
  var dot = target.find('.pointer');

  // var offset = target.offset();
  // var width = target.width();
  // var height = target.height();
  // var top = offset.top;
  // var left = offset.left;

  var mX = (event.clientX);
  var mY = (event.clientY);

  $(dot).css('-webkit-transform', 'translate3d(' + mX + 'px, ' + mY + 'px, 0)');

};

function mouseLeave(event) {

  console.log('leave');

    var target = $(this);
    var dot = target.find('.pointer');

    $(dot).css('-webkit-transform', 'translate3d(0, 0, 0) scale(0, 0)');


};

function onClick(event) {
  event.preventDefault();
  console.log('click');
};

function set(el, obj) {
  var dot = $(el).css('-webkit-transform', 'translate3d(' + obj.x + 'px, ' + obj.y + 'px, 0px)');
  return dot;
};

PROBLEM / DEMO

As mentioned before, the span is following the mouse cursor, only the span is not positioned to the center of the cursor. It will be offset the mouse. See live demo here

I tried already something like this for the mX and mY variables, but with no succes:

var mX = (event.clientX - $(this).offset().left) / $(this).width() * $(this).width() - .125 * $(this).width();
var mY = (event.clientY - $(this).offsetTop) / $(this).height() * $(this).height() - .125 * $(this).width();

Also the answer from @hiEven doesn't work and will let me with the same issue:

transform: calc(mX - 50%, mY - 50%)

I know I should do something with dividing the .pointer by half, but how I should implement that in the code is a big question mark for me.

UPDATE

I created two new Codepen projects:

Use without images: http://codepen.io/anon/pen/GqGOLv . When you hover over the first item you will see that the brown pointer is correctly following your mouse cursor - what I am looking for. But when hovering over the second one, you will see the red pointer, only when you are at the very left side of the item.

When I use images: http://codepen.io/anon/pen/QExOkx . The problem by this example is that when you at the very top of the first column, you will see the brown pointer. When hover at the top left corner of the second item you will see a little piece of the red pointer, the same as the example without images.

Both pointer should follow the mouse cursor correctly. And I am searching for a solution that works with the use of an image.

Beside these two examples, when I add to the first one, an extra margin-left to the first item, the brown pointer will not be in the center of the mouse cursor, only when it's set to margin-left zero.

So I don't know what's missing and why it only works with the first example (without images) and only for the first item?

I assume you want the circle being center of your mouse, right?

try do this transform: calc(mx - 50%, my - 50%)

here is the demo

Based on my latest update, I did not conform to the correct formula that is needed to center the element .pointer to the mouse.

In order to use the following calculation within mouseMove:

var mX = (event.clientX);
var mY = (event.clientY);

Should be changed to this:

var height = dot.height();
var width = dot.width();

var offset = target.offset();
var w = target.width();
var h = target.height();
var top = offset.top;
var left = offset.left;

var mX = (event.clientX - left) - width / 2 - 15; // 15 = padding
var mY = (event.clientY - top) - height / 2;

So this formule is considering that the following DOM element .pointer will follow the mouse movements of the user. I don't know exactly why this working, but the offset from the previous item will be decreased from the current clientX coordinates, so the position of the second item is reset to zero, so the pointer will start at the left side of each item.

Here is a working demo of above code: http://codepen.io/anon/pen/AXdxZO?editors=0110

Try the code below

<html>
  <head>
    <style>
          #mouse_div{
            position: absolute;
            background-color: black;
          }
    </style>
    <script>
          var div_width = 100;
          var div_height = 100;
          var div_x, div_y;
          function mouse_position(event){
            var mouse_x = event.clientX;
            var mouse_y = event.clientY;
            document.getElementById("mouse_div").style.width = div_width + "px";
            document.getElementById("mouse_div").style.height = div_height + "px";
            div_x = mouse_x - (div_width / 2);
            div_y = mouse_y - (div_height / 2);
            document.getElementById("mouse_div").style.left = div_x + "px";
            document.getElementById("mouse_div").style.top = div_y + "px";
          }
    </script>
  </head>
  <body onmousemove="mouse_position(event)" onload="mouse_position(event)">
    <div id="mouse_div"></div>
  </body>
</html>

This program gets the position of your mouse, the width, and the height of the div . Then, it takes the x and subtracts the div's width divided by two from it (this centres the div's x position on your mouse). The program then does the same thing for the mouse y. Once all of the variables are defined, I use JavaScript to access the CSS of the div to place the div where it needs to be.

Note: you must make sure that the position of the div is set to absolute or the program will not work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM