Detect from which side the mouse left a div - javascript

I modified the code of the best answer of another question (which aimed to detect from which side the mouse entered a div) in order to make it detect from which side the mouse left a div.
Here is the my code. I changed the log to display in the console. But somehow the results are always being "right" or "bottom" and no "top" or "left".
Any advise, please?

I've been working a bit on the code and I've modified some stuff.
Since you're positioning your div with absolute position, you need to check the position on a different way.
First, I'm using getBoundingClientRect() which returns the position of the element (left, top, right and bottom).
Then I get the mouse coordinates and I calculate from which edge is closest.
You can see an example of my code here:
document.querySelector('#content').onmouseleave = function(mouse) {
var edge = closestEdge(mouse, this);
console.log(edge);
}
function closestEdge(mouse, elem) {
var elemBounding = elem.getBoundingClientRect();
var elementLeftEdge = elemBounding.left;
var elementTopEdge = elemBounding.top;
var elementRightEdge = elemBounding.right;
var elementBottomEdge = elemBounding.bottom;
var mouseX = mouse.pageX;
var mouseY = mouse.pageY;
var topEdgeDist = Math.abs(elementTopEdge - mouseY);
var bottomEdgeDist = Math.abs(elementBottomEdge - mouseY);
var leftEdgeDist = Math.abs(elementLeftEdge - mouseX);
var rightEdgeDist = Math.abs(elementRightEdge - mouseX);
var min = Math.min(topEdgeDist,bottomEdgeDist,leftEdgeDist,rightEdgeDist);
switch (min) {
case leftEdgeDist:
return "left";
case rightEdgeDist:
return "right";
case topEdgeDist:
return "top";
case bottomEdgeDist:
return "bottom";
}
}
#content {
width: 100px;
height: 100px;
background: lightblue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div id="content"></div>
I hope that helps you.
Cheers!

Related

Prevent overlap of randomly placed elements

$(this).css({
position: 'absolute',
left: Math.random() * ($('.parentcontainer').width() - $(this).width()),
top: Math.random() * ($('.parentcontainer').height() - $(this).height())
});
I got this each loop that will randomly place elements within a div. The problem with this is that the elements will overlap each other sometimes because they are absolute positioned. Is there anyway to go around this in js to check position? or maybe rewrite this with margin values? Thanks a ton!
There's a few different ways you can do to achieve this. I find it easiest to try to define the problem in one sentence:
New square's position must be at least X distance from current square positions
Using this sentence, we can make some simple theories as to how the code will work.
Assuming all squares are 50x50 pixels, we can write some checks.
Here are some pseudo code steps we could follow:
Generate a random position for newSquare
Compare the x and y positions of newSquare to all existing squares
If either of the x and y positions of newSquare are further away from the other squares, newSquare can be placed
Otherwise, try again
var container = $('#container');
var squareSize = 50;
var containerSize = 500;
for (var i = 0; i < 20; i++) {
var foundSpace = false;
while (!foundSpace) {
// Generate random X and Y
var randX = Math.floor(Math.random() * (containerSize - squareSize));
var randY = Math.floor(Math.random() * (containerSize - squareSize));
var hitsSquare = false;
var squares = container.children();
squares.each(function(index, square) {
var square = $(square);
// parseInt() because .css() returns a string
var left = parseInt(square.css('left'));
var top = parseInt(square.css('top'));
// Check boundaries
var hitsSquareX = Math.abs(left - randX) < squareSize;
var hitsSquareY = Math.abs(top - randY) < squareSize;
// Will overlap a square
if (hitsSquareX && hitsSquareY) {
hitsSquare = true;
// jQuery break .each()
return false;
}
});
// If doesn't overlap any square
if (!hitsSquare) {
foundSpace = true;
var newSquare = $('<div class="square">');
newSquare.offset({
left: randX,
top: randY
});
container.append(newSquare);
}
}
}
#container {
position: relative;
}
.square {
position: absolute;
background-color: red;
width: 48px;
/* border adds 2px */
height: 48px;
/* border adds 2px */
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
You should look for collision detection.
In my opinion this is a great tutorial: https://www.youtube.com/watch?v=XYzA_kPWyJ8, but there are several other great ones out there.
Good luck :)

how can i measure cursor position in a div..?

i don't know what should be the question title..sorry for this.
but i explain that what i want to do.
i have a div with class name "scroll-inner-container" this div height is 70vh.
when my mouse hover into this div from top to 10% (this is the mouse hover area 0% to 10% in this div) and bottom to 10% then a function will start.
How can I measure this area into this div by using js...?
My html code looks like:
<div class="scroll-inner-container">
<div class="paragraph-space content">
<h1>top position</h1>
<p>Lorem ipsum dolor...</p>
<h1>end position</h1>
</div>
my css code here for this div:
.scroll-inner-container{
height: -moz-calc(70vh + 0px);
height: -webkit-calc(70vh + 0px);
height: calc(70vh + 0px);
overflow: auto;
object-fit: cover;
background-color: yellow;
position: relative;
}
I've previously used code similar to this for a project, copied from a previous question How to get mouse position - relative to element
var x,y;
$("#div1").mousemove(function(event) {
var offset = $(this).offset();
x = event.pageX- offset.left;
y = event.pageY- offset.top;
$("#div1").html("(X: "+x+", Y: "+y+")");
});
Once the mouse goes past a specified point on the Y axis, you can execute your code.
I think this code segment will help you. It will check the mouse position with your parent container, You can call your function inside the if condition.
var obj = $('.scroll-inner-container');
var top, left, bottom, right;
var excldH,objHeight,objWidth;
getPos(obj)
//Calls fuction on mouse over
obj.mousemove(function(e) {
handleMouseMove(e)
});
//Get position of mouse pointer
function handleMouseMove(e) {
var posX = e.clientX;
var posY = e.clientY;
if(posY > top+excldH && posY < bottom - excldH){
//Here your stuffs go
console.log(posX)
console.log(posY)
}
}
// Get position of the div 'scroll-inner-container'
function getPos(obj) {
var offsets = obj.offset();
objHeight = obj.height();
objWidth = obj.width();
excldH = objHeight/10; //Caculating 10% height
top = offsets.top,
// left = offsets.left,
bottom = top+objHeight,
// right = left+objWidth
}
Here is a jsfiddle for that
I tried to add here as snippet, but didn't worked. You can inspect the result on console.

Keep aware of transform and transform-origin anchor point on rotated container

I'm trying to rotate a container with javascript and css property transform and transform-origin, the idea is to rotate it around certain coordinates (For example a pinch gesture center between the two fingers), I'm using this simple code (snippet attached) right now to rotate the container and using the onclick event to capture the anchor point. It is working properly as long as you keep clicking without moving the cursor to a different position on the container. There's an issue when you change the click position once the container has been rotated, the expected behavior is to keep track of the transformation and start rotating for that new point, however right now the container is doing an odd jump. I think that some x,y translation need to be added to the container, but i can figure out what's the correct factor to add to the container.
I'm not sure if I've illustrated well the expected behavior, to make sure here's and example: Imagine you pin a note to a surface at certain position, then, you start rotating the note, having the pin as anchor point. Now, after rotating the note a little, you put out the pin (Keeping the note at the same place), then you place the pin on a different position on the note and rotate again with that new anchor point. That's the expected behavior, hope i have explained myself well.
Here's a snippet to show it better, also available on codepen, cheers.
http://codepen.io/vasilycrespo/pen/GZeYpB
var angle = 15,
scale = 1,
origin = { x: 0, y: 0};
var transform = function (e) {
var map = document.getElementById("map");
angle += 15;
map.style.transformOrigin = e.pageX + "px " + e.pageY + "px";
map.style.transform = "rotate("+angle+"deg) scale("+ scale +")";
};
.content{
position: fixed;
top: 0px;
left: 0px;
margin-top:0;
margin-left:0;
background-color: #ccc;
width: 100%;
height: 100%;
}
.square{
position: absolute;
width: 400px;
height: 400px;
background-image: url(http://www.pnas.org/site/misc/images/15-02545.500.jpg);
background-size: cover;
}
<div class="content" onclick="transform(event)">
<div class="square" id="map"></div>
</div>
The problem is that every time you click, the div changes position based on where you click. After the first click, you should save e.pageX and e.pageY, and in the next clicks you should use the saved values. You can change your transform function to this:
var transform = (function () {
var pageX, pageY;
return function(e) {
if (typeof pageX === "undefined") {
pageX = e.pageX
pageY = e.pageY
}
var map = document.getElementById("map"), xr;
angle += 15;
map.style.transformOrigin = pageX + "px " + pageY + "px";
map.style.transform = "rotate("+angle+"deg) scale("+ scale +")";
}
}())
See updated Code Pen.

How to correctly resize an element by dragging?

I have two divs serving as two panels one to the left and one to the right.
They take 70% and 30% of the area.
I have a separator between them.
When I drag the separator to the left or right, I want that to remain as the position of the separator. i.e., I should be able to dynamically resize the left and right divs by dragging.
Here is the code I have:
http://jsbin.com/witicozi/1/edit
HTML:
<!DOCTYPE html>
<html>
<head>
<body>
<div style='height: 100px'>
<div id='left'>...</div>
<div id='separator'></div>
<div id='right'>...</div>
</div>
</body>
</html>
CSS:
#left {
float: left;
width: 70%;
height: 100%;
overflow: auto;
}
#separator {
float: left;
width: 3px;
height: 100%;
background-color: gray;
cursor: col-resize;
}
#right {
height: 100%;
overflow: auto;
}
JavaScript:
document.querySelector('#separator').addEventListener('drag', function (event) {
var newX = event.clientX;
var totalWidth = document.querySelector('#left').offsetWidth;
document.querySelector('#left').style.width = ((newX / totalWidth) * 100) + '%';
});
The problems:
The resizing happens, but the separator jumps around randomly. It even falls down many times. I have no idea what's happening.
The mouse cursor changes to a hand when the dragging begins. I want it to remain a col-resize.
It is very hard to drag.
No JQuery please.
If you use console.log(event), it shows that event.clientX doesn't return exactly what you are looking for. The following JavaScript worked for me in chrome.
document.getElementById('separator').addEventListener('drag', function(event) {
var left = document.getElementById('left');
var newX = event.offsetX + left.offsetWidth;
left.style.width = newX + 'px';
});
The event.offsetX value that it is returning is the location (in px) of the upper left hand corner of the left div. This will give you the same result but using percentages so that when the resize the window the columns adjust:
document.getElementById('separator').addEventListener('drag', function(event) {
var left = document.getElementById('left');
var newX = event.offsetX + left.offsetWidth;
left.style.width = (newX / window.innerWidth * 100) + '%';
});
Taking a bit of a different approach: rather than using the drag and drop functionality, I used some coupled mouse down and mouse up listeners. This has better cross-browser compatibility (at least as far as my testing goes) and it has the added benefit of being able to easily control the cursor.
var resize = function(event) {
var newX = event.clientX;
document.getElementById('left').style.width = (newX / window.innerWidth * 100) + '%';
};
document.getElementById('separator').addEventListener('mousedown', function(event) {
document.addEventListener('mousemove', resize);
document.body.style.cursor = 'col-resize';
});
document.addEventListener('mouseup', function(event) {
document.removeEventListener('mousemove', resize);
document.body.style.cursor = '';
});

How can I animate DIVs moving from a central point to off-screen?

Is it possible to have divs located around a central point and then on hover for them to whisk off screen and return when the mouse is gone?
This what the layout:
http://pena-alcantara.com/aramael/wp-content/uploads/2010/04/Paper-Browser.8.5x11.Horizontal3.jpg
is looking like, the idea is for the green "leaves" to whisk off to show the branches and the menus. Would this be possible with JavaScript and PHP?
Any chance I could convince you to not design a site this way?
I suppose not, so the answer is to use jQuery. Here is the jQuery reference for animation, which you'll need to study carefully.
You are going to need to combine a few jQuery features.
The animation feature at: http://api.jquery.com/animate/
The mouse over feature: http://api.jquery.com/mouseover/
The mouse out feature: http://api.jquery.com/mouseout/
Have "dummy divs" where the mouse over is detected that move their ID's real div out of view using animate it, and bring it back with mouseout
I found this interesting so coded it for myself... I did it as below:
<style type="text/css">
body {
overflow:hidden;
}
.leaf {
position:relative;
background-color:#0F0;
height: 100px;
width: 100px;
}
.branch {
display:inline-block;
background-color:#F00;
height: 100px;
width: 100px;
}
</style>
<script type="text/javascript">
$(function(){
var w = $(document).width();
var h = $(document).height();
var r = 250;
$(".branch").hover(function() {
var rand = Math.random();
var x,y;
if(rand<0.25) {
x = w;
y = h*Math.random();
} else if(rand<0.5) {
x = -w;
y = h*Math.random();
} else if(rand<0.75) {
x = w*Math.random();
y = h;
} else {
x = w*Math.random();
y = -h;
}
$(this).children().animate({left: x, top: y});
}, function () {
$(this).children().animate({left: '0', top: '0'});
})
});
</script>
<div class="wrap">
<div class="branch"><div class="leaf"></div></div><!-- etc -->
</div>

Categories

Resources