I want that the div I created will move when the mouse is getting near to him.
Here is the fiddle link: http://jsfiddle.net/jLAq3/2/
Basic starting code (because I don't have a clue how to do it):
$('#leaf').();
Bind a function to the movement of the mouse. As the mouse moves:
Get the coordinates of the element.
Get the coordinates of the cursor.
Compare cursor coordinates with element coordinates.
If cursor is near element, move element - else do nothing.
Easy stuff.
This is a start. Every time the mouse is moving outside the leaf then a message appears.
$('body').mousemove(function(e){
var w = $('#leaf').outerWidth(),
h = $('#leaf').outerHeight(),
x = e.pageX,
y = e.pageY;
if(x > w && y > h)
{
console.log("The leaf is moving");
}
})
Furthermore you can apply some css with js to the leaf for movement etc. In a more complex example you have to spot more carefully the position and not simply rely on the width and the height of the image.
Here is a start.
http://jsfiddle.net/Lpg8x/80/
$( 'body' ).mousemove( function( event ) {
if( isNear( $( '#near' ), 20, event ) ) {
$( '#near' ).html( 'is near!' );
} else {
$( '#near' ).empty();
};
} );
function isNear( $element, distance, event ) {
var left = $element.offset().left - distance,
top = $element.offset().top - distance,
right = left + $element.width() + ( 2 * distance ),
bottom = top + $element.height() + ( 2 * distance ),
x = event.pageX,
y = event.pageY;
return ( x > left && x < right && y > top && y < bottom );
};
Have fun!
Here is a basic working example of how you actually would do all that
http://jsfiddle.net/jLAq3/10/
var leafX = 0, leafY = 0;
$('#leaf').css({position: 'relative'});
$(document).mousemove(function(e){
var offset = $('#leaf').offset()
,x1 = offset.left - 20
,x2 = offset.left + $('#leaf').width() + 20
,y1 = offset.top
,y2 = offset.top + $('#leaf').height() + 20
,center, mousePos
;
if(e.pageX > x1 && e.pageX < x2 && e.pageY > y1 && e.pageY < y2) {
center = (x2 - x1) / 2;
mousePos = e.pageX - x1;
if(mousePos < center) {
leafX += 20;
} else {
leafX -= 20;
}
center = (y2 - y1) / 2;
mousePos = e.pageY - y1;
if(mousePos < center) {
leafY += 20;
} else {
leafY -= 20;
}
}
$('#leaf').css({ top : leafY + 'px', left : leafX + 'px'});
});
But you should really learn the basics of DHTML before jumping into things, for example the difference between position absolute and relative, how to actually move HTML elements, layering, event binding etc.
Here are couple of good resources:
http://www.quirksmode.org/sitemap.html
http://www.w3schools.com/
Related
I need a popup to open from a mouse click's position. From a usability view, when the click's happen near the edges of window, I'm adjusting the position[to the right/ left of click & top/bottom of the click] of popup in JS as below:
function myfunc(e) {
let ele = document.getElementById('my-dialog');
ele.style["left"] =
(window.innerWidth - e.pageX) < ele.offsetWidth ? e.pageX - ele.offsetWidth : e.pageX;
ele.style["top"] =
(window.innerHeight - e.pageY) < ele.offsetHeight ? e.pageY - ele.offsetHeight : e.pageY; }
Is there a way this can be achieved using just CSS(or is there a better JS solution to the problem.)
Minimal working code example here.
See a working demo: https://jsfiddle.net/drumperl/ce532rnf/
To get this working, I changed the left and top style settings to add 'px'. According to the spec, a length setting requires a relative or absolute unit of measurement like 'px', '%' or 'em'.
https://developer.mozilla.org/en-US/docs/Web/CSS/length
function myfunc(e) {
let ele = document.getElementById('my-dialog');
var newLeft = (window.innerWidth - e.pageX) < ele.offsetWidth ? e.pageX - ele.offsetWidth : e.pageX;
ele.style.left = newLeft + 'px';
var newTop = (window.innerHeight - e.pageY) < ele.offsetHeight ? e.pageY - ele.offsetHeight : e.pageY;
ele.style.top = newTop + 'px';
}
document.onclick = myfunc;
Hope this helps.
I have a webpage with tree of icons drawn on a canvas:
http://seznamka.moxo.cz/
You can move with the icons. My idea what I want to do is to center the view area of the window to the position of the icon.
For example, let's click and drag icon "Gothic" which is in the lower right corner when I open the page:
The scroll should be made so, that the icon will be in the middle of screen but it should stay on its original position. So just the window should be moved to that location.
Here is the event which contains the windowScrollTo().
jQuery(canvas).mousemove(function(e) {
var canvasPosition = jQuery(this).offset();
var p = fromScreen({x: e.pageX - canvasPosition.left, y: e.pageY - canvasPosition.top});
nearest = layout.nearest(p);
if (nearest.node.visible)
{
var s = toScreen(nearest.point.p);
var h = e.pageX-canvasPosition.left > s.x ? e.pageX-canvasPosition.left - s.x : s.x - e.pageX-canvasPosition.left;
var v = e.pageY-canvasPosition.top > s.y ? e.pageY-canvasPosition.top - s.y : s.y - e.pageY-canvasPosition.top;
var distance = Math.sqrt(h*h + v*v);
underMouseEvent = distance <= iconRadius ? true : false;
}
else
underMouseEvent = false;
if (underMouseEvent )
highlighted = nearest;
if (dragged !== null && dragged.node !== null) {
dragged.point.p.x = p.x;
dragged.point.p.y = p.y;
window.scrollTo(
s.x
// window.innerWidth/2
,
s.y
// window.innerHeight/2
);
}
renderer.start();
});
I tried to just two variations s.x, s.y (coordinates of the icon which is dragged) and window.innerWidth/2,window.innerHeight/2 but not good result. How calculate the correct x and y position?
Edit
I have made change according suggestion. Now I add new version which includes condition to prevent annoying repeating when the icon is dragged. This way it will be called only once during drag. But another problem I found it that if I open pan(el) e.g Developers tools on side of brownser so there is some problem to center. I tried to correct the condition with left and right variables which should reflect the offset of current scroll but this is not fully working. Yet any ideas how to correct the calculation with scroll?
jQuery(canvas).mousemove(function(e) {
var canvasPosition = jQuery(this).offset();
var p = fromScreen({x: e.pageX - canvasPosition.left, y: e.pageY - canvasPosition.top});
nearest = layout.nearest(p);
if (nearest.node.visible)
{
var s = toScreen(nearest.point.p);
var h = e.pageX-canvasPosition.left > s.x ? e.pageX-canvasPosition.left - s.x : s.x - e.pageX-canvasPosition.left;
var v = e.pageY-canvasPosition.top > s.y ? e.pageY-canvasPosition.top - s.y : s.y - e.pageY-canvasPosition.top;
var distance = Math.sqrt(h*h + v*v);
underMouseEvent = distance <= iconRadius ? true : false;
}
else
underMouseEvent = false;
if (underMouseEvent )
highlighted = nearest;
if (dragged !== null && dragged.node !== null) {
dragged.point.p.x = p.x;
dragged.point.p.y = p.y;
if (typeof s != 'undefined')
{
**var left = document.body.scrollLeft || window.pageXOffset;
var top = document.body.scrollTop || window.pageYOffset;**
if ( releasedAfterDrag &&
(
s.x>window.innerWidth/2-**left** ||
s.y>window.innerHeight/2-**top**
)
)
{
window.scrollTo(
s.x-window.innerWidth/2,
s.y-window.innerHeight/2
);
console.log("dragging: " + releasedAfterDrag);
}
if (releasedAfterDrag)
releasedAfterDrag = false;
}
}
renderer.start();
});
jQuery(window).bind('mouseup',function(e) {
dragged = null;
releasedAfterDrag = true;
});
It seems to me that the new condition works correct only for the second half of the (inner) window (when the side panel is opened). So if the icon is in the top or right half the window is not centered.
You need to do this calculation to find its coordinates:
x: icon.x-window.innerWidth/2
y: icon.y-window.innerHeight/2
I made a carousel using 2 divs named "left" and "right" putting mousemove events on them. I wanted to make it go up and down as well so I created a "top" and "bottom" and noticed that I couldn't make them combine to go the way the cursor goes.
I thus thought of targeting a specific area in the container (i.e top half of my container div) instead of creating divs inside triggering a specific direction, this way (I think) I can trigger all these event altogether. However after now hours of research I couldn't find a way to do so.
How should I proceed ? here is the code : http://jsfiddle.net/pool4/vL5g3/3/
var x=0,
y=0,
rateX=0,
rateY=0,
maxspeed=10;
var backdrop = $('.backdrop');
$('.directionx', backdrop).mousemove(function(e){
var $this = $(this);
var left = $this.is('.left');
var right = $this.is('.right');
if (left){
var w = $this.width();
rateX = (w - e.pageX - $this.offset().left + 1)/w;
}
else if (right){
var w = $this.width();
rateX = -(e.pageX - $this.offset().left + 1)/w;
}
});
$('.directiony', backdrop).mousemove(function(e){
var $this = $(this);
var top = $this.is('.top');
var bottom = $this.is('.bottom');
if (top){
var h = $this.height();
rateY = (h - e.pageY - $this.offset().top + 1)/h;
}
else if (bottom) {
var h = $this.height();
rateY = -(e.pageY - $this.offset().top + 1)/h;
}
});
backdrop.hover(
function(){
var scroller = setInterval( moveBackdrop, 30 );
$(this).data('scroller', scroller);
},
function(){
var scroller = $(this).data('scroller');
clearInterval( scroller );
}
);
function moveBackdrop(){
x += maxspeed * rateX;
y += maxspeed * rateY;
var newpos = x+'px '+y+'px';
backdrop.css('background-position',newpos);
}
Your problem is that the divs that control movement up and down are placed over the ones that control left and right, so the latter do not receive the mousemove event ever. Mouse events do not propagate through layers, even if they're transparent. I changed your code and CSS, so each div is in one of the corners. To make things easier, I've used data-* attributes so the direction controlled by each div is set in a declarative way, without the need to change the code. You'll see that the code is much simpler (and it could be simplified even more).
By the way, you could achieve this witout extra divs, just controlling where the cursor is (to the top, right, left or bottom of the center of the div).
backdrop.on('mousemove', '.dir', function(e){
var $this = $(this);
var direction = $(e.target).attr('data-direction');
var left = direction.indexOf('left') > - 1;
var right = direction.indexOf('right') > - 1;
var top = direction.indexOf('up') > - 1;
var bottom = direction.indexOf('down') > - 1;
if (left){
var w = $this.width();
rateX = (w - e.pageX - $this.offset().left + 1)/w;
}
else if (right){
var w = $this.width();
rateX = -(e.pageX - $this.offset().left + 1)/w;
}
if (top){
var h = $this.height();
rateY = (h - e.pageY - $this.offset().top + 1)/h;
}
else if (bottom) {
var h = $this.height();
rateY = -(e.pageY - $this.offset().top + 1)/h;
}
});
I've updated your fiddle.
EDIT In this new fiddle I do it without extra divs:
var w = backdrop.width() / 2;
var h = backdrop.height() / 2;
var center = {
x: backdrop.offset().left + backdrop.width() / 2,
y: backdrop.offset().top + backdrop.height() / 2
};
backdrop.on('mousemove', function(e){
var offsetX = e.pageX - center.x;
var offsetY = e.pageY - center.y;
rateX = -offsetX / w;
rateY = -offsetY / h;
});
backdrop.hover(
function(){
var scroller = $(this).data('scroller');
if (!scroller) {
scroller = setInterval( moveBackdrop, 30 );
$(this).data('scroller', scroller);
}
},
function(){
var scroller = $(this).data('scroller');
if (scroller) {
clearInterval( scroller );
$(this).data('scroller', null);
}
}
);
As you see, the mousmove handler is considerably simpler.
To avoid issue of children losing event could use just the one.
First HTML from 4 child divs to just one
<div class="backdrop">
<div class="direction"></div>
</div>
<div id="pos"></div>
Next Inside the mousemove find your relative position
//Get Relative Position
var relX = e.pageX - $this.offset().left;
var relY = e.pageY - $this.offset().top;
Get Relative Position as a percentage of width and put 50% of it in negative for direction
var w = $this.width();
rateX = ((relX / w) - 0.5) * -1;
var h = $this.height();
rateY = ((relY / h) - 0.5) * -1;
Fiddle
I am trying to have a div in a container which when the user clicks and drags somewhere in the document area, the .room element pans around inside the .viewport element by holding down the middle click button.
Here is the issue: (Hold right click for this one, middle click didn't work for some reason)
http://jsfiddle.net/JeZj5/2/
JS
var mouseX = 0;
var mouseY = 0;
var scale = 1.0;
$(document).mousemove(function (e) {
var offset = $('.room').offset();
//relative mouse x,y
mouseX = parseFloat((e.pageX - offset.left) / scale, 2);
mouseY = parseFloat((e.pageY - offset.top) / scale, 2);
//absolute mouse x,y
mouseXRaw = e.pageX;
mouseYRaw = e.pageY;
$(".room").html(mouseX + ', ' + mouseY + '<br />Right click document and pan');
switch (e.which) {
case 3:
$('.room').css({
left: mouseX,
top: mouseY
});
break;
}
return true;
});
$(document).on('contextmenu', function () {
return false;
});
This should be more along the lines of what you're looking for. Key change:
delta.x = e.pageX - drag.x;
delta.y = e.pageY - drag.y;
Using the delta to change the position. The .room's position should be moving with respect to it's current location, minus the mouse drag position (not the other way around).
http://jsfiddle.net/X2PZP/3/
Hi Friends i am very very new to javascript and and J Query . now i want to create virtual mouse pad . i am created two div's one for mouse pad and second one is container in container i am taken another div for act as a cursor(class name is follower) .
in mouse pad div when ever mouse move follower div moving relative to the mouse position. now i want to generate click event using virtual cursor means click the buttons using follower.
Button1
Button2
MousePad
this is my js code
var mouseX = 0, mouseY = 0, limitX = 150-15, limitY = 150-15;
$('.container1').mousemove(function(e){
var offset = $('.container1').offset();
mouseX = Math.min(e.pageX - offset.left, limitX);
mouseY = Math.min(e.pageY - offset.top, limitY);
mouseX=mouseX*3;
mouseY=mouseY*3;
if (mouseX < 0) mouseX = 0;
if (mouseY < 0) mouseY = 0;
});
// cache the selector
var follower = $("#follower");
var xp = 0, yp = 0;
var loop = setInterval(function(){
// change 12 to alter damping higher is slower
xp += (mouseX - xp);
yp += (mouseY - yp) ;
follower.css({left:xp, top:yp});
}, 30);
$('.buttons span').bind('click',function(){
alert($(this).attr('title'));
});
JSbin Link
http://jsbin.com/AGAquhej/2/edit for code
http://jsbin.com/AGAquhej/1 Demo
i want generate click event using follower(moving in mouse pad)
can any one solve the problem how to generate fake click events
Thanks in advance
Using the some collision detection code from this SO answer https://stackoverflow.com/a/12180865/1481489 the following may work (untested, description is in the comments):
var overlaps = (function () { // this is the collision detection code
function getPositions( elem ) {
var pos, width, height;
pos = $( elem ).position();
width = $( elem ).width();
height = $( elem ).height();
return [ [ pos.left, pos.left + width ], [ pos.top, pos.top + height ] ];
}
function comparePositions( p1, p2 ) {
var r1, r2;
r1 = p1[0] < p2[0] ? p1 : p2;
r2 = p1[0] < p2[0] ? p2 : p1;
return r1[1] > r2[0] || r1[0] === r2[0];
}
return function ( a, b ) {
var pos1 = getPositions( a ),
pos2 = getPositions( b );
return comparePositions( pos1[0], pos2[0] ) && comparePositions( pos1[1], pos2[1] );
};
})();
$('.container1').mousemove(function(e){
var offset = $('.container1').offset();
mouseX = Math.min(e.pageX - offset.left, limitX);
mouseY = Math.min(e.pageY - offset.top, limitY);
mouseX=mouseX*3;
mouseY=mouseY*3;
if (mouseX < 0) mouseX = 0;
if (mouseY < 0) mouseY = 0;
});
$('.container1').click(function(){
proxyTriggerEvent('click');
});
function proxyTriggerEvent(eventName) {
$('.container').find('a,input,.buttons span')
.each(function() { // and loop through them all for testing
if ( overlaps(follower,this) ) { // collision detection for each item
$(this).trigger(eventName); // click the specific element
return false; // break out of the loop
}
});
}
Update:
Fixed a bug where the selector was not targeting the buttons. I misread the tag as <span class="button1"> but it is really <span title="button1">. The selector is now .buttons span instead of .button1,.button2.
Removed the unnecessary filtering of follower with .not('#follower')
Moved the hit detection to the click handler of .container - this way it isn't being run on every single interval frame, only when it really counts.
Moved the event trigger proxy out of the click call, now any event can be triggered, and it can be called as a regular function, e.g.: proxyTriggerEvent('mouseup'); or proxyTriggerEvent('click');