Let's say I have a div that follows the mouse cursor on my screen. This is done by handling the document mousemove event and setting its left and top position based on the event data.
For this example let's say it has a width and height of 10.
It is desired for it to always be centered on the cursor. To make this happen the left and top need to be horizontally offset by half of div's width and vertically offset by half of the div's height. This allows it to be perfectly centered on the mouse cursor.
document.querySelector(".circle").style.left = e.x - (width / 2)
However, this is done in many places in the application and it seems cumbersome. Is it possible to instead set the origin such that when I set the left and top properties, I do not need to offset by half the width and height, since the origin would be at the center of the div?
The only thing I could find was the transform-origin property, but this seems to only apply to the transform CSS properties, and not properties like left, margin-left, etc.
Can this be done?
You could use:
transform: translate(-50%, -50%);
This calculates the percentage from the width and height of the element itself.
Example snippet:
const move = document.getElementById("move")
const mouseMoveHandler = e => {
move.style.left = e.pageX + 'px';
move.style.top = e.pageY + 'px';
}
window.addEventListener('mousemove', mouseMoveHandler)
#move {
position: absolute;
transform: translate(-50%, -50%);
}
<div id="move">I follow the cursor</div>
You can offset it absolutely relative to a parent who is 0x0 and positioned relatively, and further make the parent move with your mouse.
<!DOCTYPE html>
<html>
<head>
<style>
.origin {
position: relative;
width: 0px;
height: 0px;
}
.circle {
position: absolute;
top: -10px;
right: -10px;
width: 20px;
height: 20px;
border-radius: 50%;
border: 3px solid red;
}
</style>
</head>
<body>
<div class="origin">
<div class="circle"/>
</div>
</body>
</html>
See more details: https://www.w3schools.com/css/css_positioning.asp
Related
I have some very simple code but I encountered an issue. I have a background image which is zoomed in upon scroll. I would like to relatively position an element relative to the background image which takes up the full width and height of the screen. How could I do this? I thought it would be as simple as having relative and absolute containers. For better context here is the image (https://imgur.com/rc8Ia3d). I am attempting to place an element on the screen of the camera. Do I have to think of a more outside of the box approach? Thank you.
Here is some of the very simple code
<script type="text/javascript">
$(window).scroll(function() {
var scroll = $(window).scrollTop();
$(".hero-zoom img").css({
width: (100 + scroll/5) + "%",
top: -(scroll/10) + "%",
});
});
</script>
header img{
width: 100%;
max-width: none;
position: absolute;
top: 0%;
left: 50%;
transform: translateX(-50%);
}
I am trying to create an eye that follows cursor movement.
I got the horizontal and vertical coordinate of the mouse and the browser width and height.
Everything works perfectly. Except that I used rotate(45 deg) on the design of the eye so now the ball is not moving in the right position.
I was thinking about a math equation that finds the distance between the old and new coords, but I am not sure how to implement it.
Here is the full code:
https://jsfiddle.net/Mr_MeS/3ym6kuec/3/
so this is the .eye where its rotated
.eye {
width: 37.5px;
height: 37.5px;
background: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(45deg);
border-radius: 75% 0;
overflow: hidden;
cursor: pointer;
}
.ball {
width: 7.5px;
height: 7.5px;
background: #222f3e;
border-radius: 50%;
border: 5px solid #576574;
position: relative;
top: 50%;
left: 50%;
}
and here is the JS that does the work and needs to be edited.
var balls = document.getElementsByClassName("ball");
document.onmousemove = function () {
var x = event.clientX * 100 / window.innerWidth + "%";
var y = event.clientY * 100 / window.innerHeight + "%";
//event.clientX => get the horizontal coordinate of the mouse
//event.clientY => get the Vertical coordinate of the mouse
//window.innerWidth => get the browser width
//window.innerHeight => get the browser height
for (var i = 0; i < 2; i++) {
balls[0].style.left = x;
balls[0].style.top = y;
balls[0].style.transform = "translate(-" + x + ",-" + y + ")";
}
}
Now, if I remove the rotation from the .eye, it works perfectly, expect that the whole shape doesn't look to be in position.
If I keep the 45deg rotation, the shape is good, but the ball moves wrongly.
You could try to put the eye-background (the white part that needs to rotate 45 degrees) into a div (or pseudo-element) that's inside the .eye element. In that way you don't need to rotate the container element, so the coordination of the ball element stays the same.
Another point, why are you using that for-loop? I think running the code once will be sufficient :)
EDIT: I've been playing around with your example a bit and fixed it. What happens is that if you rotate an element, the direction in which things will transform (and top/left positioning) will also change. So moving the element 10px to the left, will go 10px to the left, under a 45 degree angle, because it's rotated 45 degrees.
What I did now was to put an element (.inner) inside the eye div, which I gave a counter-rotation of -45 degrees. In this way, the container element of the ball has the correct orientation again, which fixes the problem: https://jsfiddle.net/bxprjvgL/
HTML:
<div class="eye">
<div class="inner">
<div class="shut"><span></span></div>
<div class="ball"></div>
</div>
</div>
CSS:
.inner {
width: 100%;
height: 100%;
transform: rotate(-45deg);
}
I am trying to use the new top and left of the child div inside a rotated parent to limit the draggable area of the rotated parent. Im using jquery draggable for this.
EDIT :
Here is the jsfiddle . Im planning to use the red dot on the rotated div to use as marker to check if it collided with the boundaries of the container. I need to get the new position(top and left) of that red marker to make use of my ready made function to contain the draggable.
In order to calculate the top or left offset for any element, you need to use .getBoundingClientRect(), in addition to accounting for the window scroll.
This is also the case for rotated elements, as can be seen in the following example:
function findTopLeft(element) {
var rec = document.getElementById(element).getBoundingClientRect();
return {
top: rec.top + window.scrollY,
left: rec.left + window.scrollX
};
}
console.log(findTopLeft('inner'));
#outer {
position: absolute;
top: 25%;
left: 25%;
width: 100px;
height: 50px;
border: 1px solid black;
transform: rotate(90deg);
}
<div id="outer">
<div id="inner">Text</div>
</div>
Hope this helps! :)
I have html sturcture
<div id="bg" class="layer">
<img id="trackmap" src="images/back_2416.jpg" width="1208" height="768" class=" ui-draggable map-icon" usemap="#main-map" data-zoom-image="images/background_zoom.jpg" data-big="images/background_zoom.jpg" style="position: relative; left: -439px; top: -272.6px; margin: 0px; display: inline-block; height: 1327.2px; width: 2088px;">
<div id="nav-text">LOREM IPSUM.</div>
</div>
Jquery
var windowHeight = $("#trackmap").height();
var windowWidth = $("#trackmap").width();
var text_height=((windowHeight)-(100));
$("#nav-text").css("top",windowHeight);
Css
.layer {
position: absolute;
width: 1208px;
height: 768px;
}
#nav-text{
z-index: 200;
color: white;
position: absolute;
font-size: 10px;
margin-left: 715px;
width: 310px;
height: 10px;
position: fixed;
bottom: 5px;}
I just want to fix the nav-text to the bottom right whatsoever.. Now i problem i am facing is theres zoom function on the trackmap.. which increases the height and width of the image ..so the text comes in between of the image ..intereferring with the image.. I have tried taking the image width height using jquery ..but somehow its not working
I am not sure I am following your issue here, but it sounds like you are trying to get a div to be in the bottom-right of another div no matter what size it is. That can be done by setting the parent div position to relative which you have, and the child div position to absolute. You have that set but then override it by setting the position to fixed lower in the CSS. You will also want to set the bottom to 0 and the right to 0.
This will position the child div to the bottom right of the parent div. Then you can get rid of your jQuery. Hopefully this helps.
Ok.. I am in a hurry to catch the bus.. but here's a fiddle that illustrates the idea..
basically you will need to use the scrolltop and left parameters to do so:
$(".container").on("scroll", function() {
$(".nav-text").css("top", $(this).prop("scrollTop") + 130);
$(".nav-text").css("left", $(this).prop("scrollLeft") + 120);
});
but move the scrolls first.. sorry I need to go now..
You can achieve this by not fixing the .layer width and height, using display:inline-block; to prevent the div from filling the whole container width. At that point, the .layer size will match the image size whatever it is.
Finally you just need to set the text to absolute position and bottom and right properties too.
.parent{
display:inline-block;
position:relative;
}
.children{
position:absolute;
bottom:0;
right:0;
}
Here is the fiddle explaining
And here is the proof it works even if the image size is changed(click on the image).
Fiddle 2
I'm currently coding a simple game in javascript. The game takes place in a div, called #box. And the enemy is a div called #enemy .
<div id="box">
<div id="prepend">
<div id="hero"></div>
</div>
<div id="enemy"></div>
</div>
Inside this #box the #enemy will move about using a setInterval() function generating random numbers (animating to x, y) . However, when I do this, somehow the point of origin where the coordinates start is at top left hand corner of the window when it should be in the top left hand corner in the #box. This is how I have been trying to generate random numbers to keep the #enemy inside the #box
var test = Math.floor(Math.random() * (1500 - $("#box").offset().left) + 0),
test2 = Math.floor(Math.random() * (750 - $("#box").offset().top) + 0);
But the problem I obviously have is that it keeps animating outside the #box.
CSS :
#box{
width:640px;
height:400px;
float: left;
background:url(../png/space.jpg);
margin: 0 0 0 100px;
}
#enemy {
width: 69px;
height: 50px;
position: absolute;
margin: 100px 0 0 100px;
background:url(../png/target2.png);
z-index:2;
}
The container div needs to have position: relative. Otherwise the position of the window, or the closest parent element with a relative position will be used in determining the inner div's position. By making the parent have a relative position, the child div will position itself relative to its parent as opposed to relative to the window.
You need:
position: relative;
in your #box CSS, for the absolute position on your #enemy to be relative to the box.
Add position: relative; to #box to make #enemy position relative to #box.
To make #boxes children position relative to it, you can use any of the following depending on your requirements:
#box { position: absolute; }
#box { position: relative; }
#box { position: fixed; }