Move a div after touch event - javascript

I am trying to produce a movement on a circle of some rectangular divs. I want that if a div is dragged near another div, the second div move within the first one the user is dragging. Is there a plugin that do this or I need to produce something calculating the position of 2 divs. And, the rectangular divs can be also 10 divs not only 2.
Here my solution.
<html>
<head>
<style type="text/css">
div#dynamic-container{width:400px; height:400px; background-color: lightgoldenrodyellow; position:relative; border: 1px solid black;}
div#innerCircle{width: 380px; height: 380px; position: absolute; left: 10px; top:10px; background-color: lightcoral;
border-radius:190px; -moz-border-radius: 190px; -webkit-border-radius: 190px;}
div.marker{width: 20px; height:20px; background: black; position:absolute; left:195px; cursor: pointer;
-moz-transform:rotate(45deg);
-moz-transform-origin:5px 200px;
transform:rotate(45deg);
transform-origin:5px 200px;
-ms-transform:rotate(45deg);
-ms-transform-origin:5px 200px;
-webkit-transform:rotate(45deg);
-webkit-transform-origin:5px 200px;
z-index:17;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="/lib/jquery.overlaps.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
function rotateAnnotationCropper(offsetSelector, xCoordinate, yCoordinate, cropper){
//alert(offsetSelector.left);
var x = xCoordinate - offsetSelector.offset().left - offsetSelector.width()/2;
var y = -1*(yCoordinate - offsetSelector.offset().top - offsetSelector.height()/2);
var theta = Math.atan2(y,x)*(180/Math.PI);
var cssDegs = convertThetaToCssDegs(theta);
var rotate = 'rotate(' +cssDegs + 'deg)';
cropper.css({'-moz-transform': rotate, 'transform' : rotate, '-webkit-transform': rotate, '-ms-transform': rotate});
$('body').on('mouseup', function(event){ $('body').unbind('mousemove')});
}
function convertThetaToCssDegs(theta){
var cssDegs = 90 - theta;
return cssDegs;
}
$(document).ready(function(){
//$('.marker-1').draggable();
var items = $('#dynamic-container').find('.marker');
var i = 0;
var cssDegs = 15;
var rotate = 'rotate(' +cssDegs + 'deg)';
for (i; i<items.length; i++){
if(i == 0){
cssDegs = cssDegs*i;
}else{
cssDegs = cssDegs+20;
}
console.log("cssDegs: "+cssDegs);
rotate = 'rotate(' +cssDegs + 'deg)';
//Imposto i gradi a tutti i punti per differenziarli al document ready
$(items[i]).css({'-moz-transform': rotate, 'transform' : rotate, '-webkit-transform': rotate, '-ms-transform': rotate});
//items[i].css("background-color","blue");
}
console.log(items);
$('.marker').on('mousedown', function(){
$('body').on('mousemove', function(event){
//rotateAnnotationCropper($('#innerCircle').parent(), event.pageX,event.pageY, $('.marker'));
//rotateAnnotationCropper($('#innerCircle').parent(), event.pageX,event.pageY, $(event.target));
rotateAnnotationCropper($('#innerCircle').parent(), event.pageX,event.pageY, $(this).find('.marker-1'));
var markers = $(this).find('.marker');
var over = overlap(markers[0],$('#container'));
if(markers[0] != over){
console.log($(markers[0]));
console.log(over);
}else{
console.log('not over');
}
});
});
$('body').on('mouseup', function(event){ $('body').unbind('mousemove')});
});
function overlap (div1, div2){
var res = $(div1).overlaps($(div2));
return res;
}
</script>
</head>
<body>
<div id="container">
<div id ="dynamic-container">
<div class ="marker marker-1"></div>
<div class ="marker marker-2"></div>
<div id ="innerCircle"></div>
</div>
</div>
</body>
At the moment this snippet produce a circle with 2 divs. That can move on the circle border. I want that if the div the user drag a div when the dragged div touch the other, they move together.
I tried to use also jQuery Overlaps library to get if 2 divs are overlapped but I do something wrong.
Thanks in advance. Every library you can suggest are well accepted

EDIT:
A more complete example will be your example working:
Working JSFiddle:
https://jsfiddle.net/mcbo9bs3/
function rotateAnnotationCropper(offsetSelector, xCoordinate, yCoordinate, cropper){
//alert(offsetSelector.left);
var x = xCoordinate - offsetSelector.offset().left - offsetSelector.width()/2;
var y = -1*(yCoordinate - offsetSelector.offset().top - offsetSelector.height()/2);
var theta = Math.atan2(y,x)*(180/Math.PI);
var cssDegs = convertThetaToCssDegs(theta);
var rotate = 'rotate(' +cssDegs + 'deg)';
cropper.css({'-moz-transform': rotate, 'transform' : rotate, '-webkit-transform': rotate, '-ms-transform': rotate});
$('body').on('mouseup', function(event){ $('body').unbind('mousemove')});
}
function convertThetaToCssDegs(theta){
var cssDegs = 90 - theta;
return cssDegs;
}
$(document).ready(function(){
//$('.marker-1').draggable();
var items = $('#dynamic-container').find('.marker');
var i = 0;
var cssDegs = 15;
var rotate = 'rotate(' +cssDegs + 'deg)';
for (i; i<items.length; i++){
if(i == 0){
cssDegs = cssDegs*i;
}else{
cssDegs = cssDegs+20;
}
console.log("cssDegs: "+cssDegs);
rotate = 'rotate(' +cssDegs + 'deg)';
//Imposto i gradi a tutti i punti per differenziarli al document ready
$(items[i]).css({'-moz-transform': rotate, 'transform' : rotate, '-webkit-transform': rotate, '-ms-transform': rotate});
//items[i].css("background-color","blue");
}
console.log(items);
$('.marker').on('mousedown', function(){
$('body').on('mousemove', function(event){
//rotateAnnotationCropper($('#innerCircle').parent(), event.pageX,event.pageY, $('.marker'));
//rotateAnnotationCropper($('#innerCircle').parent(), event.pageX,event.pageY, $(event.target));
rotateAnnotationCropper($('#innerCircle').parent(), event.pageX,event.pageY, $(this).find('.marker-1'));
var markers = $(this).find('.marker');
});
});
$('body').on('mouseup', function(event){ $('body').unbind('mousemove')});
});
window.setInterval(function() {
$('#result').text(collision($('.marker-1'), $('.marker-2')));
}, 200);
function collision($div1, $div2) {
var x1 = $($div1).offset().left;
var y1 = $($div1).offset().top;
var h1 = $($div1).outerHeight(true);
var w1 = $($div1).outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $($div2).offset().left;
var y2 = $($div2).offset().top;
var h2 = $($div2).outerHeight(true);
var w2 = $($div2).outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
return true;
}
To detect overlapping this code should work:
function collision($div1, $div2) {
var x1 = $($div1).offset().left;
var y1 = $($div1).offset().top;
var h1 = $($div1).outerHeight(true);
var w1 = $($div1).outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $($div2).offset().left;
var y2 = $($div2).offset().top;
var h2 = $($div2).outerHeight(true);
var w2 = $($div2).outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
return true;
}
You can apply that to your code (replacing the overlap function).
Hope it helps!

Related

How is it that these squares only translate once instead of multiple times within the setInterval?

var initialCircle;
var i;
var randomXPos;
var randomYPos;
var colorArray;
var interval01;
var circleNodeList;
var circleNodeListIndividual;
var xDirection = 5;
var yDirection = 5;
var dX = xDirection + 5;
var dY = yDirection + 5;
colorArray = [
'aliceblue', 'lavender', 'powderblue', 'lightblue', 'lightskyblue', 'skyblue', 'deepskyblue', 'lightsteelblue', 'dodgerblue', 'cornflowerblue', 'steelblue', 'cadetblue', 'mediumslateblue', 'slateblue', 'darkslateblue', 'royalblue', 'blue', 'mediumblue', 'darkblue', 'navy', 'midnightblue', 'blueviolet', 'indigo'
];
var randomColor;
function startBouncingHoverCircles() {
interval01 = setInterval(function() {
randomXPos = Math.floor(Math.random() * 380) + 31;
randomYPos = Math.floor(Math.random() * 235) + 31;
randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
initialCircle = document.createElement('div');
document.querySelector("#container").appendChild(initialCircle);
initialCircle.className = "aces";
initialCircle.style = 'height:30px;width:30px;border-radius:50%;box-sizing:border-box;position:absolute;border:3px solid green;background-color:' + randomColor;
initialCircle.style.top = randomYPos + 'px';
initialCircle.style.left = randomXPos + 'px';
}, 1);
setTimeout(function() {
clearInterval(interval01);
movement()
}, 100)
}
function movement() {
setInterval(function() {
circleNodeList = document.querySelectorAll(".aces");
for (i = 0; i < circleNodeList.length; i++) {
circleNodeListIndividual = circleNodeList[i];
circleNodeListIndividual.style.transition = "transform 1s";
circleNodeListIndividual.style.transform = 'translate(' + dX + 'px' + ',' + dY + 'px' + ')'
}
}, 1500)
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/randomcolor/0.6.1/randomColor.min.js" integrity="sha512-vPeZ7JCboHcfpqSx5ZD+/jpEhS4JpXxfz9orSvAPPj0EKUVShU2tgy7XkU+oujBJKnWmu4hU7r9MMQNWPfXsYw==" crossorigin="anonymous"></script>
<style>
#container {
width: 450px;
height: 300px;
position: relative;
border: 1px solid black;
margin: auto;
}
</style>
</head>
<body>
<button onClick="startBouncingHoverCircles()">Start</button>
<div id="container"></div>
<script src="../Js/bouncingHoverCircles.js"></script>
</body>
</html>
I am trying to have these balls bounce off the walls and reverse direction when they hit a wall. the first step is setting up an interval for them to continue to animate across the screen. I am trying to accomplish this without the implementation of a canvas. Any help as to why the interval only runs one time would be awesome. Thanks
Your setInterval runs OK.
The problem is that you always put the circles again at the same point. When you do 'translate(' + dX + 'px' + ',' + dY + 'px' + ')' - The dX and dY are not added to the current location of the circle. They are used as the new location (which always stays 10px.)
2 options for solution:
Increase dX and dY every time you call movement().
Probably better solution: When you set the transform property in your element - Sum the current location with the dX and dY. Code to do that:
Add the next variable before you set the transform in the movement function:
const matrix = new WebKitCSSMatrix(circleNodeListIndividual.style.transform);
then use it in setting the transform:
circleNodeListIndividual.style.transform = 'translate(' + (matrix.m41 + dX) + 'px' + ',' + (matrix.m42 + dY) + 'px' + ')'

CircleType text remove whitespace after rotateY

I'm having this code:
<div id="curvy">
This is the curved text
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/circletype#2.2.0/dist/circletype.min.js"></script>
<script>
const circleType = new CircleType(document.getElementById('curvy'));
circleType.dir(-1).radius(1100);
$( document ).ready(function() {
var counter = 1;
var deg = -40;
$($($('#curvy div').find('span')).get().reverse()).each(function (index, value ) {
/* var css = $(this).css('transform');
css = css + ' rotateY(-50deg)'; */
if(counter > 5) {
var text = $(this).html();
$(this).html('');
$(this).css('display','flex');
$(this).css('vertical-align','top');
console.log(text);
//$(this).html('');
var newElem = $('<span></span>').append(text);
newElem.appendTo($(this));
/* newElem.css('position','relative');
newElem.css('z-index',counter); */
newElem.css('vertical-align','top');
newElem.css('transform','rotateY('+ deg +'deg)');
deg = deg - 2.5;
}
//console.log(value);
counter = counter + 1;
});
});
</script>
<style>
html, body {
font-size: 30px;
}
</style>
This is working fine but after I start rotating each letter using rotateY in its own span, the parent span seems to add a white space in between that I want to get rid of.
Check jsfiddle
Well I was approaching it totally incorrectly.
The issue wasnt the spans, the padding or any margins but the translateX or rotate value.
Since CircleType was using the initial size of the letter when rendering the effect, the manipulations that I did through jQuery later weren't taken into account by it.
I had to save the matrix and then decide if I would go for an increment on the rotate value or on the translateX value. I chose the latter because it felt less complicated to play with. Since I need that the rotation will begin after a specific amount of character, I use the appropriate checks.
<div id="curvy">
Curved text
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/circletype#2.2.0/dist/circletype.min.js"></script>
<script>
const circleType = new CircleType(document.getElementById('curvy'));
circleType.dir(-1).radius(900);
$( document ).ready(function() {
var counter = 1;
var deg = -40;
var padding = 0;
$($($('#curvy div').find('span')).get().reverse()).each(function (index, value ) {
var css = $(this).css('transform').replace(/[^0-9\-.,]/g, '').split(',');
var x = css[12] || css[4];
var y = css[13] || css[5];
var a = css[0];
var b = css[1];
var angle = Math.atan2(b, a) * (180/Math.PI);
if(counter > 5) {
if(counter >= 12) {
padding = padding + 6 ;
} else
padding = padding + 4 ;
var text = $(this).html();
$(this).html('');
$(this).css('display','flex');
x = parseFloat(x) + padding;
$(this).css('transform', 'translateX('+x+'px) rotate('+angle+'deg)');
var newElem = $('<span></span>').append(text);
newElem.appendTo($(this));
newElem.css('transform','rotateY('+ deg +'deg)');
deg = deg - 2.5;
}
counter = counter + 1;
});
});
</script>
<style>
html, body {
font-size: 30px;
top: 50%;
left: 50%;
position: absolute;
}
</style>
Updated jsFiddle

Jquery calculating bouding box of a rotated rectangle

I've already looked at some other posts about that but still can't figure out why the formula isn't working.
To calculate the bounding box of a rotated rectangle :
w' = sin(a)*h + cos(a)*w;
h' = sin(a)*w + cos(a)*h;
The problem is that I'm getting weird behaviours where w' and h' are not precise at all.
// calculate rotation angle of shape
function getRotationDegrees(obj) {
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
if (matrix !== 'none') {
var values = matrix.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
} else {
var angle = 0;
}
if (angle < 0) angle += 360;
return angle;
}
var shape = $('.shape'),
shapeLeft = shape.position().left,
shapeTop = shape.position().top,
shapeWidth = shape.width(),
shapeHeight = shape.height(),
angle = getRotationDegrees(shape),
// formula below
height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle)),
width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle));
$('#g1').css('width', width);
$('#g2').css('height', height);
.elements,
.element {
position: absolute
}
#s2 {
background: #333333;
top: 60px;
left: -25px;
width: 300px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="layout" style="position:relative; margin-top:50px; margin-left:70px;">
<div class="elements">
<div id="g1" class="element" style="background:red;left:-35px;top:-10px;height:2px;"></div>
<div id="g2" class="element" style="background:red;left:-35px;top:-10px;width:2px;"></div>
<div id="s2" class="element shape" style="transform: rotate(8deg);"></div>
</div>
</div>
What am I doing wrong ?
Two sources of error:
(Minor) Rounding of the angle. (Don't know what you meant by "already a round number")
(Major) You use the result of getRotationDegrees directly in Math.cos / sin. These functions require radians, i.e. the result directly returned by Math.atan2.
The snippet below adds the other two edges of the bounding box, and also the correct positional offset. I added a slider to change the rotation angle, in order to illustrate that this code is robust.
function getMatrix(obj) {
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
return (matrix == 'none') ? null : matrix.split('(')[1].split(')')[0].split(',');
}
// calculate rotation angle of shape
function getRotationRadians(matrix) {
var angle = matrix ? Math.atan2(matrix[1], matrix[0]) : 0;
if (angle < 0) angle += 2.0 * Math.PI;
return angle;
}
// calculate translation
function getTranslation(matrix) {
return matrix ? [matrix[4], matrix[5]] : [0, 0];
}
// calculate bounding box
function getBoundingBox(shape) {
var shapeLeft = shape.position().left,
shapeTop = shape.position().top,
shapeWidth = shape.width(),
shapeHeight = shape.height();
var matrix = getMatrix(shape);
var angle = getRotationRadians(matrix);
var height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle));
var width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle));
var trans = getTranslation(matrix);
var left = trans[0] - (width * 0.5);
var top = trans[1] - (height * 0.5);
return {'x': left, 'y': top, 'w': width, 'h': height};
}
formatBox($('.shape'));
function formatBox(shape) {
var box = getBoundingBox(shape);
var offx = 124, offy = 109;
var g1 = $('#g1'), g2 = $('#g2'), g3 = $('#g3'), g4 = $('#g4');
g1.css('width', box.w);
g2.css('height', box.h);
g3.css('width', box.w);
g4.css('height', box.h);
g1.css('left', offx + box.x);
g2.css('left', offx + box.x);
g3.css('left', offx + box.x);
g4.css('left', offx + box.x + box.w);
g1.css('top', offy + box.y);
g2.css('top', offy + box.y);
g3.css('top', offy + box.y + box.h);
g4.css('top', offy + box.y);
}
var angleInp = document.getElementById("angleInp");
angleInp.addEventListener("change", function() {
var shape = $('.shape');
shape.css('transform', 'rotate(' + angleInp.value + 'deg)');
formatBox(shape);
}, false);
.elements,
.element {
position: absolute
}
#s2 {
background: #333333;
top: 60px;
left: -25px;
width: 300px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slider">
<input class="bar" type="range" id="angleInp" min="0" max="360" value="15" onchange="angleInp.value=value"/>
</div>
<div class="layout" style="position:relative; margin-top:50px; margin-left:70px;">
<div class="elements">
<div id="g1" class="element" style="background:red;left:0px;top:0px;height:2px;"></div>
<div id="g2" class="element" style="background:red;left:0px;top:0px;width:2px;"></div>
<div id="g3" class="element" style="background:red;left:0px;top:0px;height:2px;"></div>
<div id="g4" class="element" style="background:red;left:0px;top:0px;width:2px;"></div>
<div id="s2" class="element shape" style="transform: rotate(15deg);"></div>
</div>
</div>

JavaScript function only affects first div with class

I have part of a game where the cursor is supposed to "slow down" when it passes over certain divs. I'm using a function that can detect a collision with the div. This works fine when the cursor meets the first div, but it doesn't work at all on the second div.
Check out this jsFiddle for a better idea of what I'm talking about. Pass the cursor over the first white block (class='thing') on the left and it slows down. Pass the cursor over the other block (also class='thing'), and nothing happens. I need this collision function to work on all divs where class='thing'.
HTML
<div id='cursor'>
</div>
<div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 350px; right: 800px; z-index: -1;'>
</div>
<div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 200px; right: 400px; z-index: -1;'>
</div>
JS
(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
var x1 = $cursor.offset().left;
var y1 = $cursor.offset().top;
var h1 = $cursor.outerHeight(true);
var w1 = $cursor.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $thing.offset().left;
var y2 = $thing.offset().top;
var h2 = $thing.outerHeight(true);
var w2 = $thing.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
// change 12 to alter damping higher is slower
var varies = 12;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
} else {
varies = 200;
console.log(varies);
}
$xp += (($mouseX - $xp)/varies);
$yp += (($mouseY - $yp)/varies);
$("#cursor").css({left:$xp +'px', top:$yp +'px'});
}
$(collision($('#cursor'), $('.thing')));
//$('.result').text(collision($('#cursor'), $('.thing')));
}, 20);
})();
$thing is a collection of elements, like you want, but the problem here is that you ask specific attributes from $thing like offset().left;, which can not return more than one number, therefor it just takes the first. What you should do instead is use an .each() function to loop over all the elements in $thing.
$thing.each( function( index, element ){
//your code for each thing here
});
When you are selecting element by class name(in your case using .thing) in jQuery you will get an array of elements and collision() function will take first element in an array. so to overcome this you need to uniquely select both the elements this can be done using id as a selector,You can change your code like below to work it as expected
<div id='track'>
<div class = 'container'>
<div id='cursor' class='cursor'>
</div>
<div class='thing' id="a1" style='width:70px; height:70px; background: #fff; position: absolute; bottom: 175px; right: 400px; z-index: -1;'>
</div>
<div class='thing' id="a2" style='width:70px; height:70px; background: #fff; position: absolute; bottom: 100px; right: 200px; z-index: -1;'>
</div>
</div>
</div>
(function cursorMapping(){
var $mouseX = 0, $mouseY = 0;
var $xp = 0, $yp =0;
$(document).mousemove(function(e){
$mouseX = e.pageX;
$mouseY = e.pageY;
});
function showCoords(event) {
var x = event.clientX;
var y = event.clientY;
var coor = "X: " + x + ", Y: " + y;
}
var timestamp = null;
var lastMouseX = null;
var lastMouseY = null;
var mrefreshinterval = 500; // update display every 500ms
var lastmousex=-1;
var lastmousey=-1;
var lastmousetime;
var mousetravel = 0;
var lastmousetravel = 0;
var speed;
var marker1 = 1;
var marker2 = 1;
var timer = setInterval(function(){
marker1;
marker2;
}, 20);
$(function() {
var $speedometer = $('#speed'),
_speed = 0;
$('#track').cursometer({
onUpdateSpeed: function thisSpeed(speed) {
_speed = speed;
$speedometer.text(Math.ceil(speed * 100)/100);
},
updateSpeedRate: 20
});
});
var thisInterval = setInterval(function FXInterval(){
speed = $('#speed').text();
$('#cursor').css({'background-color': '#CE7A7A'});
}, 20);
$('html').mousemove(function(e) {
var mousex = e.pageX;
var mousey = e.pageY;
if (lastmousex > -1)
mousetravel += Math.max( Math.abs(mousex-lastmousex), Math.abs(mousey-lastmousey) );
lastmousex = mousex;
lastmousey = mousey;
var speed = lastmousex + lastmousey;
setTimeout(function(){
lastmousetravel = mousetravel;
}, 20);
});
(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
var x1 = $cursor.offset().left;
var y1 = $cursor.offset().top;
var h1 = $cursor.outerHeight(true);
var w1 = $cursor.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $thing.offset().left;
var y2 = $thing.offset().top;
var h2 = $thing.outerHeight(true);
var w2 = $thing.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
// change 12 to alter damping higher is slower
var varies = 12;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
} else {
varies = 200;
console.log(varies);
}
$xp += (($mouseX - $xp)/varies);
$yp += (($mouseY - $yp)/varies);
$("#cursor").css({left:$xp +'px', top:$yp +'px'});
}
$(collision($('#cursor'), $('#a1')));
$(collision($('#cursor'), $('#a2')));
}, 20);
})();
})();

Display google map on hover link or text

http://coding.pressbin.com/18/Display-a-Google-Map-when-you-hover-over-location-text/ I am following this tutorial on how to display google map over a text. Yes it appears but in a wrong place. See, the map is displaying on the bottom of the page. When I hover the map image the div itself has no attributes compared to the working ones.
Working code:
<div style="position: absolute; left: 678px; top: 170px; z-index: 999; display: none; padding: 1px; margin-left: 5px; background-color: rgb(51, 51, 51); width: 302px; box-shadow: 0pt 1px 10px rgba(0, 0, 0, 0.5);">
<a target="new" href="http://maps.google.com/maps?q=Brookhaven, PA&z=11">
<img border="0" src="http://maps.google.com/maps/api/staticmap?center=Brookhaven, PA&zoom=12&size=300x300&sensor=false&format=png&markers=color:blue|Brookhaven, PA">
</a>
</div>
What's in my browser:
<div style="display: none;">
<a target="new" href="http://maps.google.com/maps?q=4417 Edgmont Avenue, 19015&z=11">
<img border="0" src="http://maps.google.com/maps/api/staticmap?center=4417 Edgmont Avenue, 19015&zoom=16&size=300x300&sensor=false&format=png&markers=color:blue|4417 Edgmont Avenue, 19015">
</a>
</div>
I'm lost on the div part.
Please help!
This is what works for me:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>jQuery Test Script</title>
</head>
<body>
<span class="mapThis" place="600 Forbes Ave, Pittsburgh, PA 15282" zoom="16">Duquesne University</span> is located in the great town of <span class="mapThis" place="Pittsburgh, PA" zoom="12">Pittsburgh</span> in the great state of <span class="mapThis" place="Pennsylvania" zoom="6">Pennsylvania</span>.
<script src="jquery-ui-1.8.16.custom/js/jquery-1.6.2.min.js"></script>
<script src="scripts/test_script.js"></script>
</body>
</html>
Here's the jQuery to make it happen:
// JavaScript Document
$(document).ready(function () {
var cursorX;
var cursorY;
if (window.Event) {
document.captureEvents(Event.MOUSEMOVE);
}
document.onmousemove = getCursorXY;
$(".mapThis").each(function() {
var dPlace = $(this).attr("place");
var dZoom = $(this).attr("zoom");
var dText = $(this).html();
$(this).html('<a onmouseover="mapThis.show(this);" style="text-decoration:none; border-bottom:1px dotted #999" href="http://maps.google.com/maps?q=' + dPlace + '&z=' + dZoom + '">' + dText + '</a>');
});
});
var mapThis=function(){
var tt;
var errorBox;
return{
show:function(v){
if (tt == null) {
var pNode = v.parentNode;
pPlace = $(pNode).attr("place");
pZoom = parseInt($(pNode).attr("zoom"));
pText = $(v).html();
tt = document.createElement('div');
$(tt).html('<img border=0 src="http://maps.google.com/maps/api/staticmap?center=' + pPlace + '&zoom=' + pZoom + '&size=300x300&sensor=false&format=png&markers=color:blue|' + pPlace + '">');
tt.addEventListener('mouseover', function() { mapHover = 1; }, true);
tt.addEventListener('mouseout', function() { mapHover = 0; }, true);
tt.addEventListener('mouseout', mapThis.hide, true);
document.body.appendChild(tt);
}
fromleft = cursorX;
fromtop = cursorY;
fromleft = fromleft - 25;
fromtop = fromtop - 25;
tt.style.cssText = "position:absolute; left:" + fromleft + "px; top:" + fromtop + "px; z-index:999; display:block; padding:1px; margin-left:5px; background-color:#333; width:302px; -moz-box-shadow:0 1px 10px rgba(0, 0, 0, 0.5);";
tt.style.display = 'block';
},
hide:function(){
tt.style.display = 'none';
tt = null;
}
};
}();
function getCursorXY(e) {
cursorX = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
cursorY = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
}
I know this post is old but I thought it might be useful if anyone stumbles upon this and is looking for a more updated example. Although the code in the answer works fine it is not written in a jQuery friendly format. I also found that the way the event listeners were configured made it's use a little difficult. Lastly, the fixed size of the map just does not work in today's responsive world. Hope this helps someone!
Add #mapHolder anywhere in your page and style it to your liking:
<div id='mapHolder' style='whatever you want'></div>
Place links anywhere in your page that you what to display a map when moused over:
<a class="mapthis" place="properly formatted address" zoom="12">MAP</a>
jQuery:
$(document).on("mouseenter", ".mapthis", function(e) {
var desiredMapWidthPercent = .8;
var mapWidth = Math.round($(window).width() * desiredMapWidthPercent);
var aspectRatio = mapWidth / $(window).height();
var mapHeight = Math.round($(window).height() * aspectRatio);
var boxWidth = mapWidth;
var boxHeight = mapHeight;
var scale = 1;
var pZoom = parseInt($(this).attr("zoom"));
var pPlace = $(this).attr("place");
if((mapHeight > 640) || (mapWidth > 640)){
mapHeight = Math.round(mapHeight / 3.5);
mapWidth = Math.round(mapWidth / 3.5);
scale = 2;
if(((mapHeight) > 1280) || ((mapWidth) > 1280)){
mapHeight = 640;
mapWidth = 640;
boxWidth = 1280;
boxHeight = 1280;
}else{
boxWidth = mapWidth * 2;
boxHeight = mapHeight * 2;
}
}
var fromleft = Math.max(0, ((($(window).width() - boxWidth) / 2) + $(window).scrollLeft()))+'px';
var fromtop = Math.max(0, ((($(window).height() - boxHeight) / 2) + $(window).scrollTop()))+'px';
var pText = $(this).html();
$('#mapHolder').html('<img border=0 src="https://maps.google.com/maps/api/staticmap?center=' + pPlace + '&zoom=' + pZoom + '&size='+mapWidth+'x'+mapHeight+'&scale='+scale+'&sensor=false&format=png&markers=color:blue|' + pPlace + '">');
$('#mapHolder').css({position:'absolute',top:fromtop,left:fromleft, width:boxWidth, z-index:'999'});
$('#mapHolder').show();
});
$(document).on("mouseleave", ".mapthis", function(e) {
if($(e.relatedTarget).closest('#mapHolder').length){
$("#mapHolder").on("mouseleave", function(e) {
$('#mapHolder').hide();
});
return;
}
$('#mapHolder').hide();
});

Categories