Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery image hover effect

I'm trying to achieve this effect with jQuery.

I wrote some of the code, but it's buggy (move to the bottom-right corder and you'll see).
check it out

Basically, if there's an already-built jQuery plugin that you know of that does this, I'd be very happy using it, if not, any help with my formula would be appreciated. This is what I get for not paying attention in Maths classes :)

Thanks in advance.

Maikel

like image 499
Maikel Avatar asked Nov 12 '10 02:11

Maikel


2 Answers

Overall I think this is what you're looking for:

$.fn.sexyImageHover = function() { 
    var p = this, // parent
        i = this.children('img'); // image

    i.load(function(){
        // get image and parent width/height info
        var pw = p.width(),
            ph = p.height(),
            w = i.width(),
            h = i.height();

        // check if the image is actually larger than the parent
        if (w > pw || h > ph) {
            var w_offset = w - pw,
                h_offset = h - ph;

            // center the image in the view by default
            i.css({ 'margin-top':(h_offset / 2) * -1, 'margin-left':(w_offset / 2) * -1 });

            p.mousemove(function(e){
                var new_x = 0 - w_offset * e.offsetX / w,
                    new_y = 0 - h_offset * e.offsetY / h;

                i.css({ 'margin-top':new_y, 'margin-left':new_x });
            });
        }
    });
}

You can test it here.

Notable changes:

  • new_x and new_y should be divided by the images height/width, not the container's height/width, which is wider.
  • this is already a jQuery object in a $.fn.plugin function, no need to wrap it.
    • i and p were also jQuery objects, no need to keep wrapping them
  • no need to bind mousemove on mouseenter (which rebinds) the mousemove will only occur when you're inside anyway.
like image 118
Nick Craver Avatar answered Oct 01 '22 07:10

Nick Craver


Nick Craver beat me to an answer by about 10 minutes, but this is my code for this, using background-image to position the image instead of an actual image.

var img = $('#outer'),
    imgWidth = 1600,
    imgHeight = 1200,
    eleWidth = img.width(),
    eleHeight = img.height(),
    offsetX = img.offset().left,
    offsetY = img.offset().top,
    moveRatioX = imgWidth / eleWidth - 1,
    moveRatioY = imgHeight / eleHeight - 1;


img.mousemove(function(e){
    var x = imgWidth - ((e.pageX - offsetX) * moveRatioX),
        y = imgHeight - ((e.pageY - offsetY) * moveRatioY);
    this.style.backgroundPosition =  x + 'px ' + y + 'px';
});

The huge amount of variables are there because the mousemove event handler has to be as efficient as possible. It's slightly more restrictive, because you need to know the dimensions, but I think the code can be easily altered to work with imgs for which the size can be calculated easily.

A simple demo of this: http://www.jsfiddle.net/yijiang/fq2te/1/

like image 41
Yi Jiang Avatar answered Oct 01 '22 08:10

Yi Jiang