views:

94

answers:

3

I have the following code:
http://www.project-vanquish.co.cc/gridtest/drag-grid.html

The plan is to allow the user to control that div (with the smiley face) in 3 ways:

1 - by the Cursor Keys on the keyboard
2 - by dragging the div
3 - by clicking on an area and the div will move to that position

The problem I have is that when I click the page the div seems slightly offset to what it should be :(

Also, the "click to move" method doesn't work at all in IE.

I thought I had cracked this last night, evidently not...

A: 

To solve the offset problem in your click method, try adjusting the top and left animation properties to compensate for the inline styling (top:200px; left:120px;) you've applied to the #character div. e.g:

Instead of this:

$('#character').animate({
    top:    mouseY,
    left:   mouseX
})

Try this:

$('#character').animate({
    top:    mouseY - 200,
    left:   mouseX - 120
})

To get it working in IE, try adding a semicolon at the end of the animate method:

$('#character').animate({
    top:    mouseY - 200,
    left:   mouseX - 120
});

(Both solutions untested.)

NickD
semi-colon insertion doesn't depend on browsers, it will happen anyway because this is part of the language specification. Yet it is highly recommended to use them because of the confusion and bugs they can cause sometimes.
galambalazs
@galambalazs, that's right-- but sometimes the JS engine for different browsers acts wonky. You run into them from time-to-time especially in DOM value work, and math-related features.
No it's the implementation of the DOM that acts differently not the language. There are differences but semi-colon insertion is not really one of them.
galambalazs
A: 

If there is some offSet, then you should catch it and add it (as Margin). To do that, use firebug and read the DOM (offSetX and offSetY). With jQuery get the according offSet and add it to the Margin (Top or Left).

I was in a similar situation few days ago, let me know if you didn't found out a way out. The solution proposed by NickD would probably solve the issue, but since the offSet can change from browser to other, or while doing improvement to the design, an automatic solution would be worth the effort.

Omar Abid
+3  A: 

You need to adjust the mouse coordinates because they are absolute (from the event object) but you have work to with relative on the map.

So you need the coordinates of the map and subtract them from the mouse click coordinates every time a click occures.

You also have to normalize the click coordinates to deal with the center of the character (instead of the top left corner). So you need to subtract the half of the character's width and height from the mouse coordinates.

[See it in action]

var mapTop     = $('#map').offset().top;
var mapLeft    = $('#map').offset().left;
var charWidth  = $('#character').outerWidth();
var charHeight = $('#character').outerHeight();

$('#map').click(function (e) {
    var mouseX = e.pageX - mapLeft - (charWidth / 2);  // convert absolute coords
    var mouseY = e.pageY - mapTop  - (charHeight / 2); // into relative ones...
    mouseX = Math.round(mouseX / 40) * 40;
    mouseY = Math.round(mouseY / 40) * 40;
    $('#character').animate({
        top: mouseY,
        left: mouseX
    })
});
galambalazs
You absolute star! +rep for you!
Neurofluxation
I'm glad I could help :)
galambalazs
This is interesting, but could we not grab window position, OR, use the "click here to start" button as a means of providing a delta/vector to all other objects?
there is no window position in my code, I don't get you I'm afraid.
galambalazs