John Bale
John Bale

Reputation: 179

Scrolling large image inside a div

I have an large image inside a small div. Inside that div there are 4 arrows to control the movement, right, bottom, left and top. The arrows are used to move the image inside that smaller div.

This is the JS code

$('.slide-right').click(function() {
    $('.inner img').animate({ "right": "+=50px" }, "slow" );
});
$('.slide-bottom').click(function() {
    $('.inner img').animate({ "bottom": "+=50px" }, "slow" );
});
$('.slide-left').click(function() {
    $('.inner img').animate({ "left": "+=50px" }, "slow" );
});
$('.slide-top').click(function() {
    $('.inner img').animate({ "top": "+=50px" }, "slow" );
});

And this is the html:

<div id="content">
    <div class="image-box">
        <div class="inner"><img alt="" src="http://s15.postimg.org/5phzr2off/img.jpg" id="image" /></div>
        <div id="arrow-up"><a href="javascript:void(0);" class="slide-top"><img alt="" src="http://s24.postimg.org/gr2uv14d1/arrow_top.png" /></a></div>
        <div id="arrow-right"><a href="javascript:void(0);" class="slide-right"><img alt="" src="http://s24.postimg.org/ruda95avp/arrow_right.png" /></a></div>
        <div id="arrow-bottom"><a href="javascript:void(0);" class="slide-bottom"><img alt="" src="http://s10.postimg.org/n8hv0166x/arrow_bottom.png" /></a></div>
        <div id="arrow-left"><a href="javascript:void(0);" class="slide-left"><img alt="" src="http://s2.postimg.org/qrpm662u1/arrow_left.png" /></a></div>
    </div>
</div>

Demo: http://jsfiddle.net/john_bale96/C26rV/

I would like to make the animation to stop when the edge of the image is reached. Can someone give me some clues on how to do this ?

Upvotes: 4

Views: 2211

Answers (4)

SubjectCurio
SubjectCurio

Reputation: 4872

Don't change all 4 top right bottom left, as you'll end up with stuff like right:1000px; left:1000px; etc... and it'll probably break the thing.

Focus on using just 2 of them instead, i'd recommend just using top and left

So to go right, you'd do left += 50px to go left you'd do left -= 50px

A simple way to resolve this solution would be to simply manually plot the contraints like this:

$('.slide-right').click(function() {      
    if (parseInt($('.inner img').css('left')) >= -700) {
        $('.inner img').finish().animate({ "left": "-=50px" }, "slow" );
    }
});

$('.slide-bottom').click(function() {
    if (parseInt($('.inner img').css('top')) >= -249) {
        $('.inner img').finish().animate({ "top": "-=50px" }, "slow" );
    }
});

$('.slide-left').click(function() {
    if (parseInt($('.inner img').css('left')) < -49) {
        $('.inner img').finish().animate({ "left": "+=50px" }, "slow" );
    }
});

$('.slide-top').click(function() {
    if (parseInt($('.inner img').css('top')) < -49) {
        $('.inner img').finish().animate({ "top": "+=50px" }, "slow" );
    }
});

http://jsfiddle.net/C26rV/4/

But ideally you could do something better which would determine the dimensions of the image itself allowing it to work with any image size automatically.

Edit:

Just as a side note (It doesn't have constraints) you can use considerably less jQuery by handling sliding like this:

$('.slide').click(function () {
    var sliding = {}
    sliding[$(this).data('direction')] = $(this).data('movement');
    $('.inner img').animate(sliding,"slow");
});

http://jsfiddle.net/C26rV/2/

Upvotes: 1

Trace
Trace

Reputation: 18869

Another suggestion, using jQuery UI draggable.

http://jqueryui.com/draggable/

http://jsfiddle.net/kimgysen/3twxS/1/

$("#inner").draggable({
    containment: $('#content')
});

Upvotes: 1

Lars H&#246;ppner
Lars H&#246;ppner

Reputation: 18402

The basic approach would be to compare the image position with the containing div position:

    var inner = $(".inner").first();
    var divTop = inner.offset().top;
    var divLeft = inner.offset().left;
    var divRight = divLeft + inner.width();
    var divBottom = divTop + inner.height();

    function getImagePosition() {
        var image = $("#image");
        var imageTop = image.offset().top;
        var imageLeft = image.offset().left;

        return {
            top: imageTop,
            left: imageLeft,
            right: imageLeft + image.width(),
            bottom: imageTop + image.height()
        }
    }

    function scrollTop() {
        var imagePosition = getImagePosition();

        var nextImageTop = imagePosition.top + 50;
        if (nextImageTop <= divTop) {
            $('.slide-top').off("click");

            $('.inner img').animate({
                "top": "+=50px"
            }, "slow", function () {
                $('.slide-top').click(scrollTop);
            });
        }
    }

    $('.slide-top').click(scrollTop);

You should also unbind the arrow scrolling events while the animation happens, otherwise if the user clicks multiple times while the animation is happening, it can still scroll the image outside of the div constraints.

See this fiddle (I only implemented the rebinding for top):

http://jsfiddle.net/lhoeppner/puLDd/

Upvotes: 1

EdenSource
EdenSource

Reputation: 3387

You have to consider that, at the beginning, your image is left:0px and top:0px. So you already have your left and top limite.

$('.slide-left').click(function () {
    if ($('.inner img').position().left + 50 < 0) {
        $('.inner img').animate({
            "left": "+=50px"
        }, "slow");
    } 
});

$('.slide-top').click(function () {
    if ($('.inner img').position().top + 50 < 0) {
        $('.inner img').animate({
            "top": "+=50px"
        }, "slow");
    } 
});

Then, you can get the right and bottom limite. This is your image size.

var limiteRight = 0 - $('.inner img').width() + $('.image-box').width();
var limiteBottom = 0 - $('.inner img').height() + $('.image-box').height();


$('.slide-right').click(function () {
    if ($('.inner img').position().left - 50 > limiteRight) {
        $('.inner img').animate({
            "left": "-=50px"
        }, "slow");
    }
});

$('.slide-bottom').click(function () {
    if ($('.inner img').position().top - 50 > limiteBottom) {
        $('.inner img').animate({
            "top": "-=50px"
        }, "slow");
    }
});

And you finnaly have to check if your desired new position is within this container. If not, just go to the limite.

$('.slide-right').click(function () {
    if ($('.inner img').position().left - 50 > limiteRight) {
        $('.inner img').animate({
            "left": "-=50px"
        }, "slow");
    } else {
        $('.inner img').animate({
            "left": limiteRight
        }, "slow");
    }
});

FIDDLE with full exemple.

Upvotes: 1

Related Questions