Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Draggable() and keyboard control

Hey there, I have a page with the jQuery Draggable() enabled on #person and that #person is constrained to #map.

(link to plugin: http://docs.jquery.com/UI/Draggables/draggable )

However, I have also added control with the Arrow keys on the keyboard. Now, they all play well together until I get to the edge of the constrained area (the edge of #map).

If I am dragging, then the #person gets constrained to the #map - if I use the arrow keys, the #person can go beyond the edge of #map.

How can I constrain the arrow keys as well as the draggable?

My code for the keyboard control:

$(document).bind('keydown',function(e){ //set the keydown function as...
        switch(e.which) {
            case 37:    $(characterName).animate({
                            left:   '-=40'
                        }, 250, function() {

                        });
                        break;
                            }
});

****phew**** cheers.

[EDIT] Please anyone? [/EDIT]

like image 951
Barrie Reader Avatar asked Jul 19 '10 15:07

Barrie Reader


2 Answers

If someone feels a bit lazy, this is what I just coded (simplified):

$('body').on('keypress', handleKeys);

function handleKeys(e) {
    var position, 
        draggable = $('#draggable'),
        container = $('#container'),
        distance = 1; // Distance in pixels the draggable should be moved

    position = draggable.position();

    // Reposition if one of the directional keys is pressed
    switch (e.keyCode) {
        case 37: position.left -= distance; break; // Left
        case 38: position.top  -= distance; break; // Up
        case 39: position.left += distance; break; // Right
        case 40: position.top  += distance; break; // Down
        default: return true; // Exit and bubble
    }

    // Keep draggable within container
    if (position.left >= 0 && position.top >= 0 &&
        position.left + draggable.width() <= container.width() &&
        position.top + draggable.height() <= container.height()) {
        draggable.css(position);
    }

    // Don't scroll page
    e.preventDefault();
}
like image 185
Blaise Avatar answered Oct 26 '22 05:10

Blaise


Unfortunately, jQuery UI Draggable doesn't expose any methods to manually change the element's position. You will have to track the #person's position manually when moving it with the keyboard, and stop moving it when it is about to exceed the bounds of the #map.

You can use jQuery methods such as .offset() and .position() methods to find reliable positions for elements.

For instance:

$(document).bind(
    'keydown',
    function(event) {

        switch(event.which) {
            case 37: {

                var character = $(characterName);
                var map = $('#map');

                if((character.offset().left - 40) >  map.offset().left) {
                    character.animate(
                        {
                            left: '-=40'
                        },
                        250,
                        function(){}
                    );
                }

                break;
            }
        }
    }
);
like image 32
cdata Avatar answered Oct 26 '22 04:10

cdata