Getting wrong width value [2px extra] from getBoundingClientRect() - javascript

This is being weird. I am using getBoundingClientRect() to get the values to position my blue coloured div so that it can surround an element on mouseover.
It works great and is getting all the values correctly. See this for reference:
As you can see, the blue div here surrounded the password element on hover as it should! (I have used Bootstrap demo form from w3schools for this.)
However, the problem arises when I create a form page myself without using Bootstrap or any other framework.
It gets the top and left correctly, but width and height 2px more! See the extra spacing here:
I don't know what is causing this to output those 2px extra. Why it works perfectly with Bootstrap or W3.CSS like frameworks but spit out 2px more without any frameworks? What's the workaround for this?
Here's the code snippet:
document.addEventListener("mouseover", (e) => {
elem = e.target;
var rect = elem.getBoundingClientRect();
var x = rect.left;
var y = rect.top;
var w = rect.width;
var h = rect.height;
div.style.width = w + "px";
div.style.height = h + "px";
div.style.left = x + window.scrollX + "px";
div.style.top = y + window.scrollY + "px";
});

Related

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?
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.
I assume you want the circle being center of your mouse, right?
try do this
transform: `translate(calc(${mx}px - 50%), calc(${my}px - 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

Accurate jQuery x y mouse click on image

I have a div with a background image - the div is set to the exact size of the image and my pointer is set to a crosshair over the div.
I want to mark each click with its x and y positions in the div over the image background. This I can do but the mark on the div is always lower and to the left of the actual cursor why is this?
function showClick(x,y)
{
$('.clickable').append('<span id="'+x+y+'_span" style="position: absolute;top:'+y+'px;left:'+x+'px;" class="red">+</span>');
}
$('.clickable').bind('click', function (ev) {
var $div = $(ev.target);
var offset = $div.offset();
var xMargin = ($div.outerWidth() - $div.width()) / 2;
var yMargin = ($div.outerHeight() - $div.height()) / 2;
var x = (ev.pageX + xMargin) - offset.left;
var y = (ev.pageY + yMargin) - offset.top;
showClick(x,y);
});
working example: https://jsfiddle.net/b94ypmae/3/
You are not taking into account the size of the span (and the character inside it).
Your code is working properly, in that a span is being placed in your div at the position of your cursor, but that position is based on the upper left corner
If you put a border around your span you can see it is a perfect alignment of your upper left corner: JSFiddle showing border
You could fix this by taking into account the size of the placed span(if you know it will always be the same you could hard code it as well). Here's an example of getting the size of the placed span and moving it by half it's width and height: Fixed JSFiddle
var placedSpan = $("#" + x + y + "_span");
var width = placedSpan.width();
var height = placedSpan.height();
placedSpan.css('left', x - width / 2 + 'px');
placedSpan.css('top', y - height / 2 + 'px');

How to make an object move towards the mouse position?

I'm trying to make an object to move in an area when clicking the area with the left pointer.
Is this possible in javascript/jquery?
Can you please give me some examples if possible?
I'm aiming to do this in javascript/html/css
Here's an example of an object following the mouse click
You can do it like this (Working Demo in jsFiddle):
$(document).ready(function(){
$('#canvas').click(function(e){
var offset = $(this).offset();
$('#object').css({
'top': e.pageY-offset.top,
'left': e.pageX-offset.left
})
})
})
Whenever the click event happens, it's pageX and pageY values are taken using which the exact location of the click in the canvas object is found. This coords are then used in jQuery animate function to change the location of the object div in it.
It is possible, but your answer could range from moving an object towards the click position by setting its position to absolute in CSS and modifying its left and top position until it reaches the click area with a setInterval timer to elaborate A* path finding.
var mousePosition;
var div;
div = document.createElement("div");
div.style.position = "absolute";
div.style.left = "0px";
div.style.top = "0px";
div.style.width = "100px";
div.style.height = "100px";
div.style.backgroundColor = "red";
document.body.appendChild(div);
document.addEventListener('click', function(event) {
mousePosition = {
x : event.clientX,
y : event.clientY
};
div.style.left = (mousePosition.x-div.offsetWidth/2) + 'px';
div.style.top = (mousePosition.y-div.offsetHeight/2) + 'px';
}, true);

Hover div (with a border and padding) over the center of a canvas element?

I want the div to be exactly in the center horizontally. I've tried this:
var div = document.createElement();
div.textContent = 'Hello World!';
div.className = 'button';
div.style.position = 'absolute';
div.style.left = (0.5 * canvas.width) + canvas.offsetLeft + 'px';
The class button is defined as follows:
.button{
color : black;
padding : 10px;
border : solid black 3px;
border-radius : 10px;
overflow : none;
}
Obviously, there's a problem with defining the pixels it is from the left to be exactly half of the canvas: The text is of a variable width. If I could find the width of the text, I could just divide it by 2 and subtract it from what I'm currently assigning to the left property.
I've tried just making a div with an absolute position, which hovers right above the canvas and aligning all text to the center within that div, but that didn't work either.
First attempt
Second attempt
Please try to give your answers in Plain JavaScript, without using any library.
Use ctx.measureText, after setting ctx.font correctly: http://jsfiddle.net/SFR82/2/.
I also suggest using border in CSS correctly, like 3px solid black.
var ctx = canvas.getContext("2d");
ctx.font = "12pt Times New Roman"; // same as <div> font; this is default for me
var textSize = ctx.measureText(text);
...
div.style.left = 0.5 * canvas.offsetWidth // half canvas width
+ canvas.offsetLeft // plus left position
- (textSize.width / 2) // minus half of text width
- 10 // minus padding
- 3 // minus border size
+ 'px';
You can use this line
div.style.left = (0.5 * canvas.width + canvas.offsetLeft - (div.clientWidth / 2)) + 'px';
and the equivalent for height, but only after you've added the div to the DOM.
here is an example of how I would solve the problem..
var cvsHeight = cvs.height,
cvsWidth = cvs.width;
var foo = document.getElementById("foo");
var offsetX = cvs.offsetLeft,
offsetY = cvs.offsetTop;
foo.style.top = offsetY + (cvsHeight / 2) - (foo.offsetHeight / 2) + "px";
foo.style.left = offsetX + (cvsWidth / 2) - (foo.offsetWidth / 2) + "px";
basically you take half the height and width of the floating object and subtract that from half the height and width of the canvas... then add in the x and y offset (where the canvas sits on the page) and BAM your done!

Centering via offset math doesn't work in non-webkit browsers

The code: http://jsfiddle.net/LPF85/6/
In FF, IE7, and IE9 (the only browsers I've tested that don't run WebKit), it seems that the left attribute is either always set to 0, or, in IE's case, negative.
My positioning code is all based off the dimensions of the document.
function open_img_in_face_box(id, width){
max_width = $j(document).width();
max_height = $j(document).height();
padding = 150;
passed_width = width || (max_width - (2 * padding));
var img = $j('#' + id);
dom_img = document.getElementById(id);
$j(document).bind('reveal.facebox', function() {
$j("#facebox .image img").width(passed_width);
})
// display
jQuery.facebox({
image: img.attr('src')
});
// center and adjust size
var aspect_ratio = img.width() / img.height();
var img_width = passed_width;
var img_height = passed_width / aspect_ratio;
window_center_y = max_height / 2;
window_center_x = max_width / 2;
offset_y = window_center_y - (img_height / 2);
offset_x = window_center_x - (img_width / 2);
var fbx = $j('#facebox');
fbx.css('position', 'absolute');
fbx.css('left', offset_x + 'px !important');
fbx.css('top', offset_y + 'px !important');
fbx.css('margin-left', 'auto');
fbx.css('margin-right', 'auto');
}
margin-left and margin-right don't appear to do anything here, which I'm fine with, because the left math should work across all browsers, right? (It is just math)
The goal of the facebox / lightbox, is to be centered both horizontally and vertically.
Why would you even programatically calculate the position in the first place? What if the user resizes the page? This can easily be done in pure CSS.
I don't really understand your jsFiddle (or am I not seeing the same thing?) so I'll just give you this script: http://jsfiddle.net/minitech/8U4Ke/ that can be modified however you like. It's commented. ;)
Now it's easy to hide and show - to hide, fade out .overlay. To show, fade it in. To change the contents, replace the HTML in .popup. Add close boxes and whatnot liberally.

Categories

Resources