Forum Moderators: open

Message Too Old, No Replies

Looking for script to enlarge image during hover

         

FlyingsCool

3:08 am on Apr 18, 2011 (gmt 0)

10+ Year Member



Hi,
I know almost nothing about javascript or jQuery. I am looking for a script which will enlarge an image when the mouse is hovering over it. I found a script over at dynamicdrive that was meant to enlarge an image (animate it) when you click on it. Problem is, it works when you click, and it doesn't stay open, it collapses immediately.

I was able to change it so it kind of works, but it's very unstable. In IE, when the mouse is over the center of the image, the image will enlarge and collapse over and over. In chrome, the image will mostly shake, but if you put the mouse just right over the image, the image stays open till I move the mouse. In Firefox, the image just shakes when I hover over it.

I wouldn't really know how to create a minimal test case as I don't know what is the important code, so I'll post the script, and then post how I edited it and what I know.

Function Call:

<script type="text/javascript">

jQuery(document).ready(function($){
$('img.imagewarp').imageWarp() //apply warp effect to images with CSS class "imagewarp"
})

</script>



Script:

/* imageWarp jQuery plugin v1.01
* Last updated: June 29th, 2009. This notice must stay intact for usage
* Author: Dynamic Drive at dynamicdrive
* Visit dynamicdrive for full source code
*/

jQuery.noConflict()

jQuery.imageWarp={
dsettings: {
warpfactor: 1.5, //default increase factor of enlarged image
duration: 1000, //default duration of animation, in millisec
imgopacity: [0.5, 1],
warpopacity: [0.1, 0.5]
},
warpshells: [],

refreshoffsets:function($target, warpshell){
var $offsets=$target.offset()
warpshell.attrs.x=$offsets.left //update x position of original image relative to page
warpshell.attrs.y=$offsets.top
warpshell.newattrs.x=warpshell.attrs.x-((warpshell.newattrs.w-warpshell.attrs.w)/2) //update x position of final warped image relative to page
warpshell.newattrs.y=warpshell.attrs.y-((warpshell.newattrs.h-warpshell.attrs.h)/2)
},

addEffect:function($, $target, options){
var setting={} //create blank object to store combined settings
var setting=jQuery.extend(setting, this.dsettings, options)
var effectpos=this.warpshells.length
var attrs={w:$target.outerWidth(), h:$target.outerHeight()}
var newattrs={w:Math.round(attrs.w*setting.warpfactor), h:Math.round(attrs.h*setting.warpfactor)}
var $clone=$target.clone().css({position:'absolute', left:0, top:0, visibility:'hidden', border:'1px solid gray'}).appendTo(document.body)
$target.add($clone).data('pos', effectpos) //save position of image
var $targetlink=$target.parents('a').eq(0)
this.warpshells.push({$clone:$clone, attrs:attrs, newattrs:newattrs, $link:($targetlink.length==1)? $targetlink : null}) //remember info about this warp image instance
$target.click(function(e){
var $this=$(this).css({opacity:setting.imgopacity[0]})
var imageinfo=jQuery.imageWarp.warpshells[$(this).data('pos')]
jQuery.imageWarp.refreshoffsets($this, imageinfo) //refresh offset positions of original and warped images
if (imageinfo.$link){
e.preventDefault()
}
var $clone=imageinfo.$clone
$clone.stop().css({left:imageinfo.attrs.x, top:imageinfo.attrs.y, width:imageinfo.attrs.w, height:imageinfo.attrs.h, opacity:setting.warpopacity[0], visibility:'visible'})
.animate({opacity:setting.warpopacity[1], left:imageinfo.newattrs.x, top:imageinfo.newattrs.y, width:imageinfo.newattrs.w, height:imageinfo.newattrs.h}, setting.duration,
function(){ //callback function after warping is complete
$clone.css({left:0, top:0, visibility:'hidden'})
$this.css({opacity:setting.imgopacity[1]})
if (imageinfo.$link){
window.location=imageinfo.$link.attr('href')
}
}) //end animate
}) //end click
}
};

jQuery.fn.imageWarp=function(options){
var $=jQuery
return this.each(function(){ //return jQuery obj
var $imgref=$(this)
if (this.tagName!="IMG")
return true //skip to next matched element
if (parseInt($imgref.css('width'))>0 && parseInt($imgref.css('height'))>0){ //if image has explicit width/height attrs defined
jQuery.imageWarp.addEffect($, $imgref, options)
}
else if (this.complete){ //account for IE not firing image.onload
jQuery.imageWarp.addEffect($, $imgref, options)
}
else{
$(this).bind('load', function(){
jQuery.imageWarp.addEffect($, $imgref, options)
})
}
})
};


I basically took the target.click function and duplicated it into mouseenter and mouseleave functions as best I could. I could get the mousenter code to work, but when I add the mouseleave function, it gets unstable. If I comment out the jQuery.imageWarp.refreshoffsets function, it gets stable, but of course now it doesn't know where the image should go. I tried modifying the two functions into a single target.hover function, but that worked exactly the same.

$target.mouseenter(function(e){
var $this=$(this).css({opacity:setting.imgopacity[0]})
var imageinfo=jQuery.imageWarp.warpshells[$(this).data('pos')]
jQuery.imageWarp.refreshoffsets($this, imageinfo) //refresh offset positions of original and warped images
var $clone=imageinfo.$clone
$clone.stop(true,true).css({left:imageinfo.attrs.x, top:imageinfo.attrs.y, width:imageinfo.attrs.w, height:imageinfo.attrs.h, opacity:setting.warpopacity[1], visibility:'visible'})
.animate({left:imageinfo.newattrs.x, top:imageinfo.newattrs.y, width:imageinfo.newattrs.w, height:imageinfo.newattrs.h}, setting.duration,
function(){ //callback function after warping is complete
$clone.css({left:imageinfo.newattrs.x, top:imageinfo.newattrs.y, opacity:setting.imgopacity[1], visibility:'visible'})
$this.css({opacity:setting.imgopacity[1]})
}) //end animate
}) //end mouseover

$target.mouseleave(function(e){
var $this=$(this).css({opacity:setting.imgopacity[0]})
var imageinfo=jQuery.imageWarp.warpshells[$(this).data('pos')]
jQuery.imageWarp.refreshoffsets($this, imageinfo) //refresh offset positions of original and warped images
var $clone=imageinfo.$clone
$clone.stop(true,true).css({left:imageinfo.attrs.x, top:imageinfo.attrs.y, width:imageinfo.attrs.w, height:imageinfo.attrs.h, opacity:setting.warpopacity[1], visibility:'hidden'})
.animate({left:imageinfo.attrs.x, top:imageinfo.attrs.y, width:imageinfo.attrs.w, height:imageinfo.attrs.h}, setting.duration,
function(){ //callback function after warping is complete
$clone.css({left:0, top:0, visibility:'hidden'})
$this.css({opacity:setting.imgopacity[0]})
}) //end animate
}) //end mouseover


I hope posting like this is ok. Sorry the code format removes the extra spaces making it harder to read. Any hints would be appreciated. I haven't gotten any response in three days over at DD's forum.

The aspect I liked about this code is that it is image size and placement independent, it figures out the information it needs on the fly. Most of the scripts I've found need the programmer to enter all that information and order the images in a list.

JAB Creations

4:57 pm on Apr 21, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



First don't use jQuery or other frameworks, they aren't cross-browser compatible, rely on junk like innerHTML and will lead you in to poor coding habits.

Secondly just use CSS. Set the image as a background-image and then on the element's hover change the background-image to the larger picture.

- John