stowball / jQuery-rwdImageMaps

Responsive Image Maps jQuery Plugin
http://mattstow.com
MIT License
1.56k stars 712 forks source link

Maphilight + rwdImagemaps Dont work #39

Open dianhuro opened 10 years ago

dianhuro commented 10 years ago

Hi, i tried draw an areas in one map, and resize the map and areas location with this scripts. If the resize work the maphiligth doens show the areas, and if a can darw the areas dont resize the map, plz help me

and

(function ($) { var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area, canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;

has_canvas = !!document.createElement('canvas').getContext;

// VML: more complex
has_VML = (function() {
    var a = document.createElement('div');
    a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
    var b = a.firstChild;
    b.style.behavior = "url(#default#VML)";
    return b ? typeof b.adj == "object": true;
})();

if(!(has_canvas || has_VML)) {
    $.fn.maphilight = function() { return this; };
    return;
}

if(has_canvas) {
    hex_to_decimal = function(hex) {
        return Math.max(0, Math.min(parseInt(hex, 16), 255));
    };
    css3color = function(color, opacity) {
        return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
    };
    create_canvas_for = function(img) {
        var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
        c.getContext("2d").clearRect(0, 0, c.width, c.height);
        return c;
    };
    var draw_shape = function(context, shape, coords, x_shift, y_shift) {
        x_shift = x_shift || 0;
        y_shift = y_shift || 0;

        context.beginPath();
        if(shape == 'rect') {
            // x, y, width, height
            context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
        } else if(shape == 'poly') {
            context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
            for(i=2; i < coords.length; i+=2) {
                context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
            }
        } else if(shape == 'circ') {
            // x, y, radius, startAngle, endAngle, anticlockwise
            context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
        }
        context.closePath();
    }
    add_shape_to = function(canvas, shape, coords, options, name) {
        var i, context = canvas.getContext('2d');

        // Because I don't want to worry about setting things back to a base state

        // Shadow has to happen first, since it's on the bottom, and it does some clip /
        // fill operations which would interfere with what comes next.
        if(options.shadow) {
            context.save();
            if(options.shadowPosition == "inside") {
                // Cause the following stroke to only apply to the inside of the path
                draw_shape(context, shape, coords);
                context.clip();
            }

            // Redraw the shape shifted off the canvas massively so we can cast a shadow
            // onto the canvas without having to worry about the stroke or fill (which
            // cannot have 0 opacity or width, since they're what cast the shadow).
            var x_shift = canvas.width * 100;
            var y_shift = canvas.height * 100;
            draw_shape(context, shape, coords, x_shift, y_shift);

            context.shadowOffsetX = options.shadowX - x_shift;
            context.shadowOffsetY = options.shadowY - y_shift;
            context.shadowBlur = options.shadowRadius;
            context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);

            // Now, work out where to cast the shadow from! It looks better if it's cast
            // from a fill when it's an outside shadow or a stroke when it's an interior
            // shadow. Allow the user to override this if they need to.
            var shadowFrom = options.shadowFrom;
            if (!shadowFrom) {
                if (options.shadowPosition == 'outside') {
                    shadowFrom = 'fill';
                } else {
                    shadowFrom = 'stroke';
                }
            }
            if (shadowFrom == 'stroke') {
                context.strokeStyle = "rgba(0,0,0,1)";
                context.stroke();
            } else if (shadowFrom == 'fill') {
                context.fillStyle = "rgba(0,0,0,1)";
                context.fill();
            }
            context.restore();

            // and now we clean up
            if(options.shadowPosition == "outside") {
                context.save();
                // Clear out the center
                draw_shape(context, shape, coords);
                context.globalCompositeOperation = "destination-out";
                context.fillStyle = "rgba(0,0,0,1);";
                context.fill();
                context.restore();
            }
        }

        context.save();

        draw_shape(context, shape, coords);

        // fill has to come after shadow, otherwise the shadow will be drawn over the fill,
        // which mostly looks weird when the shadow has a high opacity
        if(options.fill) {
            context.fillStyle = css3color(options.fillColor, options.fillOpacity);
            context.fill();
        }
        // Likewise, stroke has to come at the very end, or it'll wind up under bits of the
        // shadow or the shadow-background if it's present.
        if(options.stroke) {
            context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
            context.lineWidth = options.strokeWidth;
            context.stroke();
        }

        context.restore();

        if(options.fade) {
            $(canvas).css('opacity', 0).animate({opacity: 1}, 100);
        }
    };
    clear_canvas = function(canvas) {
        canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
    };
} else {   // ie executes this code
    create_canvas_for = function(img) {
        return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
    };
    add_shape_to = function(canvas, shape, coords, options, name) {
        var fill, stroke, opacity, e;
        for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
        fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
        stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
        opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
        if(shape == 'rect') {
            e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
        } else if(shape == 'poly') {
            e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
        } else if(shape == 'circ') {
            e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
        }
        e.get(0).innerHTML = fill+opacity;
        $(canvas).append(e);
    };
    clear_canvas = function(canvas) {
        // jquery1.8 + ie7 
        var $html = $("<div>" + canvas.innerHTML + "</div>");
        $html.children('[name=highlighted]').remove();
        canvas.innerHTML = $html.html();
    };
}

shape_from_area = function(area) {
    var i, coords = area.getAttribute('coords').split(',');
    for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
    return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};

options_from_area = function(area, options) {
    var $area = $(area);
    return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};

is_image_loaded = function(img) {
    if(!img.complete) { return false; } // IE
    if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
    return true;
};

canvas_style = {
    position: 'absolute',
    left: 0,
    top: 0,
    padding: 0,
    border: 0
};

var ie_hax_done = false;
$.fn.maphilight = function(opts) {
    opts = $.extend({}, $.fn.maphilight.defaults, opts);

    if(!has_canvas && !ie_hax_done) {
        $(window).ready(function() {
            document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
            var style = document.createStyleSheet();
            var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
            $.each(shapes,
                function() {
                    style.addRule('v\\:' + this, "behavior: url(#default#VML); antialias:true");
                }
            );
        });
        ie_hax_done = true;
    }

    return this.each(function() {
        var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
        img = $(this);

        if(!is_image_loaded(this)) {
            // If the image isn't fully loaded, this won't work right.  Try again later.
            return window.setTimeout(function() {
                img.maphilight(opts);
            }, 200);
        }

        options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));

        // jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
        // So use raw getAttribute instead.
        usemap = img.get(0).getAttribute('usemap');

        if (!usemap) {
            return
        }

        map = $('map[name="'+usemap.substr(1)+'"]');

        if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
            return;
        }

        if(img.hasClass('maphilighted')) {
            // We're redrawing an old map, probably to pick up changes to the options.
            // Just clear out all the old stuff.
            var wrapper = img.parent();
            img.insertBefore(wrapper);
            wrapper.remove();
            $(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
        }

        wrap = $('<div></div>').css({
            display:'block',
            background: 'url("' + this.src + '")',
            backgroundSize: 'cover',
            position:'relative',
            padding:0,
            width:this.width,
            height:this.height
            });
        if(options.wrapClass) {
            if(options.wrapClass === true) {
                wrap.addClass($(this).attr('class'));
            } else {
                wrap.addClass(options.wrapClass);
            }
        }
        img.before(wrap).css('opacity', 0).css(canvas_style).remove();
        if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
        wrap.append(img);

        canvas = create_canvas_for(this);
        $(canvas).css(canvas_style);
        canvas.height = this.height;
        canvas.width = this.width;

        mouseover = function(e) {
            var shape, area_options;
            area_options = options_from_area(this, options);
            if(
                !area_options.neverOn
                &&
                !area_options.alwaysOn
            ) {
                shape = shape_from_area(this);
                add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
                if(area_options.groupBy) {
                    var areas;
                    // two ways groupBy might work; attribute and selector
                    if(/^[a-zA-Z][\-a-zA-Z]+$/.test(area_options.groupBy)) {
                        areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
                    } else {
                        areas = map.find(area_options.groupBy);
                    }
                    var first = this;
                    areas.each(function() {
                        if(this != first) {
                            var subarea_options = options_from_area(this, options);
                            if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
                                var shape = shape_from_area(this);
                                add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
                            }
                        }
                    });
                }
                // workaround for IE7, IE8 not rendering the final rectangle in a group
                if(!has_canvas) {
                    $(canvas).append('<v:rect></v:rect>');
                }
            }
        }

        $(map).bind('alwaysOn.maphilight', function() {
            // Check for areas with alwaysOn set. These are added to a *second* canvas,
            // which will get around flickering during fading.
            if(canvas_always) {
                clear_canvas(canvas_always);
            }
            if(!has_canvas) {
                $(canvas).empty();
            }
            $(map).find('area[coords]').each(function() {
                var shape, area_options;
                area_options = options_from_area(this, options);
                if(area_options.alwaysOn) {
                    if(!canvas_always && has_canvas) {
                        canvas_always = create_canvas_for(img[0]);
                        $(canvas_always).css(canvas_style);
                        canvas_always.width = img[0].width;
                        canvas_always.height = img[0].height;
                        img.before(canvas_always);
                    }
                    area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
                    shape = shape_from_area(this);
                    if (has_canvas) {
                        add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
                    } else {
                        add_shape_to(canvas, shape[0], shape[1], area_options, "");
                    }
                }
            });
        });

        $(map).trigger('alwaysOn.maphilight').find('area[coords]')
            .bind('mouseover.maphilight', mouseover)
            .bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });

        img.before(canvas); // if we put this after, the mouseover events wouldn't fire.

        img.addClass('maphilighted');
    });
};
$.fn.maphilight.defaults = {
    fill: true,
    fillColor: '000000',
    fillOpacity: 0.2,
    stroke: true,
    strokeColor: 'ff0000',
    strokeOpacity: 1,
    strokeWidth: 1,
    fade: true,
    alwaysOn: false,
    neverOn: false,
    groupBy: false,
    wrapClass: true,
    // plenty of shadow:
    shadow: false,
    shadowX: 0,
    shadowY: 0,
    shadowRadius: 6,
    shadowColor: '000000',
    shadowOpacity: 0.8,
    shadowPosition: 'outside',
    shadowFrom: false
};

})(jQuery);

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Reservas.aspx.vb" Inherits="Procesos_Reservas" %> <%@ Register TagPrefix="eo" Namespace="EO.Web" Assembly="EO.Web" %> <!doctype html>

Checkeate Roamer Mobile ``` ```
```
   
     
   
   
   
   
   
     
   
     


``` <%-- --%>
--%>
<%--
--%> <%--
--%> ```
<%--Octoface Octoface Octoface Octoface Octoface Octoface Octoface Octoface--%> <%--
   
   
<%----%>
```
odlex commented 10 years ago

(function($) { var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area, canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;

has_canvas = !!document.createElement('canvas').getContext;

// VML: more complex
has_VML = (function() {
    var a = document.createElement('div');
    a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
    var b = a.firstChild;
    b.style.behavior = "url(#default#VML)";
    return b ? typeof b.adj == "object": true;
})();

if(!(has_canvas || has_VML)) {
    $.fn.maphilight = function() { return this; };
    return;
}

if(has_canvas) {
    hex_to_decimal = function(hex) {
        return Math.max(0, Math.min(parseInt(hex, 16), 255));
    };
    css3color = function(color, opacity) {
        return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
    };
    create_canvas_for = function(img) {
        var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
        c.getContext("2d").clearRect(0, 0, c.width, c.height);
        return c;
    };
    var draw_shape = function(context, shape, coords, x_shift, y_shift) {
        x_shift = x_shift || 0;
        y_shift = y_shift || 0;

        context.beginPath();
        if(shape == 'rect') {
            // x, y, width, height
            context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
        } else if(shape == 'poly') {
            context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
            for(i=2; i < coords.length; i+=2) {
                context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
            }
        } else if(shape == 'circ') {
            // x, y, radius, startAngle, endAngle, anticlockwise
            context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
        }
        context.closePath();
    }
    add_shape_to = function(canvas, shape, coords, options, name) {
        var i, context = canvas.getContext('2d');

        // Because I don't want to worry about setting things back to a base state

        // Shadow has to happen first, since it's on the bottom, and it does some clip /
        // fill operations which would interfere with what comes next.
        if(options.shadow) {
            context.save();
            if(options.shadowPosition == "inside") {
                // Cause the following stroke to only apply to the inside of the path
                draw_shape(context, shape, coords);
                context.clip();
            }

            // Redraw the shape shifted off the canvas massively so we can cast a shadow
            // onto the canvas without having to worry about the stroke or fill (which
            // cannot have 0 opacity or width, since they're what cast the shadow).
            var x_shift = canvas.width * 100;
            var y_shift = canvas.height * 100;
            draw_shape(context, shape, coords, x_shift, y_shift);

            context.shadowOffsetX = options.shadowX - x_shift;
            context.shadowOffsetY = options.shadowY - y_shift;
            context.shadowBlur = options.shadowRadius;
            context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);

            // Now, work out where to cast the shadow from! It looks better if it's cast
            // from a fill when it's an outside shadow or a stroke when it's an interior
            // shadow. Allow the user to override this if they need to.
            var shadowFrom = options.shadowFrom;
            if (!shadowFrom) {
                if (options.shadowPosition == 'outside') {
                    shadowFrom = 'fill';
                } else {
                    shadowFrom = 'stroke';
                }
            }
            if (shadowFrom == 'stroke') {
                context.strokeStyle = "rgba(0,0,0,1)";
                context.stroke();
            } else if (shadowFrom == 'fill') {
                context.fillStyle = "rgba(0,0,0,1)";
                context.fill();
            }
            context.restore();

            // and now we clean up
            if(options.shadowPosition == "outside") {
                context.save();
                // Clear out the center
                draw_shape(context, shape, coords);
                context.globalCompositeOperation = "destination-out";
                context.fillStyle = "rgba(0,0,0,1);";
                context.fill();
                context.restore();
            }
        }

        context.save();

        draw_shape(context, shape, coords);

        // fill has to come after shadow, otherwise the shadow will be drawn over the fill,
        // which mostly looks weird when the shadow has a high opacity
        if(options.fill) {
            context.fillStyle = css3color(options.fillColor, options.fillOpacity);
            context.fill();
        }
        // Likewise, stroke has to come at the very end, or it'll wind up under bits of the
        // shadow or the shadow-background if it's present.
        if(options.stroke) {
            context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
            context.lineWidth = options.strokeWidth;
            context.stroke();
        }

        context.restore();

        if(options.fade) {
            $(canvas).css('opacity', 0).animate({opacity: 1}, 100);
        }
    };
    clear_canvas = function(canvas) {
        canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
    };
} else {   // ie executes this code
    create_canvas_for = function(img) {
        return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
    };
    add_shape_to = function(canvas, shape, coords, options, name) {
        var fill, stroke, opacity, e;
        for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
        fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
        stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
        opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
        if(shape == 'rect') {
            e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
        } else if(shape == 'poly') {
            e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
        } else if(shape == 'circ') {
            e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
        }
        e.get(0).innerHTML = fill+opacity;
        $(canvas).append(e);
    };
    clear_canvas = function(canvas) {
        // jquery1.8 + ie7 
        var $html = $("<div>" + canvas.innerHTML + "</div>");
        $html.children('[name=highlighted]').remove();
        canvas.innerHTML = $html.html();
    };
}

shape_from_area = function(area) {
    var i, coords = area.getAttribute('coords').split(',');
    for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
    return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};

options_from_area = function(area, options) {
    var $area = $(area);
    return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};

is_image_loaded = function(img) {
    if(!img.complete) { return false; } // IE
    if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
    return true;
};

canvas_style = {
    position: 'absolute',
    left: 0,
    top: 0,
    padding: 0,
    border: 0
};

var ie_hax_done = false;
$.fn.maphilight = function(opts) {
    opts = $.extend({}, $.fn.maphilight.defaults, opts);

    if(!has_canvas && !ie_hax_done) {
        $(window).ready(function() {
            document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
            var style = document.createStyleSheet();
            var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
            $.each(shapes,
                function() {
                    style.addRule('v\\:' + this, "behavior: url(#default#VML); antialias:true");
                }
            );
        });
        ie_hax_done = true;
    }

    return this.each(function() {
        var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
        img = $(this);

        if(!is_image_loaded(this)) {
            // If the image isn't fully loaded, this won't work right.  Try again later.
            return window.setTimeout(function() {
                img.maphilight(opts);
            }, 200);
        }

        options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));

        // jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
        // So use raw getAttribute instead.
        usemap = img.get(0).getAttribute('usemap');

        if (!usemap) {
            return
        }

        map = $('map[name="'+usemap.substr(1)+'"]');

        if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
            return;
        }

        if(img.hasClass('maphilighted')) {
            // We're redrawing an old map, probably to pick up changes to the options.
            // Just clear out all the old stuff.
            var wrapper = img.parent();
            img.insertBefore(wrapper);
            wrapper.remove();
            $(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
        }

        wrap = $('<div></div>').css({
            display:'block',
            // background:'url("'+this.src+'")',
            position:'relative',
            padding:0,
            width:this.width,
            height:this.height
            });
        if(options.wrapClass) {
            if(options.wrapClass === true) {
                wrap.addClass($(this).attr('class'));
            } else {
                wrap.addClass(options.wrapClass);
            }
        }
        img.before(wrap).css('opacity', 0).css(canvas_style).remove();
        if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
        wrap.append(img);

        canvas = create_canvas_for(this);
        $(canvas).css(canvas_style);
        canvas.height = this.height;
        canvas.width = this.width;

        mouseover = function(e) {
            var shape, area_options;
            area_options = options_from_area(this, options);
            if(
                !area_options.neverOn
                &&
                !area_options.alwaysOn
            ) {
                shape = shape_from_area(this);
                add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
                if(area_options.groupBy) {
                    var areas;
                    // two ways groupBy might work; attribute and selector
                    if(/^[a-zA-Z][\-a-zA-Z]+$/.test(area_options.groupBy)) {
                        areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
                    } else {
                        areas = map.find(area_options.groupBy);
                    }
                    var first = this;
                    areas.each(function() {
                        if(this != first) {
                            var subarea_options = options_from_area(this, options);
                            if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
                                var shape = shape_from_area(this);
                                add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
                            }
                        }
                    });
                }
                // workaround for IE7, IE8 not rendering the final rectangle in a group
                if(!has_canvas) {
                    $(canvas).append('<v:rect></v:rect>');
                }
            }
        }

        $(map).bind('alwaysOn.maphilight', function() {
            // Check for areas with alwaysOn set. These are added to a *second* canvas,
            // which will get around flickering during fading.
            if(canvas_always) {
                clear_canvas(canvas_always);
            }
            if(!has_canvas) {
                $(canvas).empty();
            }
            $(map).find('area[coords]').each(function() {
                var shape, area_options;
                area_options = options_from_area(this, options);
                if(area_options.alwaysOn) {
                    if(!canvas_always && has_canvas) {
                        canvas_always = create_canvas_for(img[0]);
                        $(canvas_always).css(canvas_style);
                        canvas_always.width = img[0].width;
                        canvas_always.height = img[0].height;
                        img.before(canvas_always);
                    }
                    area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
                    shape = shape_from_area(this);
                    if (has_canvas) {
                        add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
                    } else {
                        add_shape_to(canvas, shape[0], shape[1], area_options, "");
                    }
                }
            });
        });

        $(map).trigger('alwaysOn.maphilight').find('area[coords]')
            .bind('mouseover.maphilight', mouseover)
            .bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });

        img.before(canvas); // if we put this after, the mouseover events wouldn't fire.
        wrap.prepend(img.clone().css('opacity', 1));
        img.addClass('maphilighted');
    });
};
$.fn.maphilight.defaults = {
    fill: true,
    fillColor: '000000',
    fillOpacity: 0.2,
    stroke: true,
    strokeColor: 'ff0000',
    strokeOpacity: 1,
    strokeWidth: 1,
    fade: true,
    alwaysOn: false,
    neverOn: false,
    groupBy: false,
    wrapClass: true,
    // plenty of shadow:
    shadow: false,
    shadowX: 0,
    shadowY: 0,
    shadowRadius: 6,
    shadowColor: '000000',
    shadowOpacity: 0.8,
    shadowPosition: 'outside',
    shadowFrom: false
};

})(jQuery);

it seems better to prepend the clone of the image rather than make it a background image !

cf: wrap.prepend(img.clone().css('opacity', 1));