Skip to content

Minor: ImageOverlay improvements? #2564

Closed
@urban-1

Description

Hi all,

First of all thanks for the awesome work you have done!

Now, I needed to have markers on the map that scale with the zoom level. For this I used ImageOverlay (which may be the wrong thing to do, let me know if there is another way). The full functionality of normal markers was needed, but it seems that ImageOverlay does not respond to mouse events. Additionally, the generated image has no "title" attribute (to be used on mouse over like tool tip). Finally, doing a W3C validation I saw that it complains about missing alt.

To handle the above I extended the ImageOverlay the following way (most of the code is copy/paste from the L.Marker class replacing _icon with _image + the last 2 lines of _initImage):

L.ImageOverlayResp = L.ImageOverlay.extend({

    options: {
      clickable: true // Add option clickable befault true
    },

    onAdd: function(map){
      L.ImageOverlay.prototype.onAdd.call(this, map);
      this._initInteraction();
    },

    _initInteraction: function () {

        if (!this.options.clickable) { return this; }

        L.DomUtil.addClass(this._image, 'leaflet-clickable');

        L.DomEvent.on(this._image, 
'click dblclick mousedown mouseup mouseover mouseout contextmenu keypress',
                this._fireMouseEvent, this);

        if (L.Handler.MarkerDrag) {
            this.dragging = new L.Handler.MarkerDrag(this);

            if (this.options.draggable) {
                this.dragging.enable();
            }
        }

        return this;
    },

    _fireMouseEvent: function (e, type) {
        // to prevent outline when clicking on keyboard-focusable marker
        if (e.type === 'mousedown') {
            L.DomEvent.preventDefault(e);
        }

        if (e.type === 'click' && this.dragging && this.dragging.moved()) { return; }

        if (e.type === 'keypress' && e.keyCode === 13) {
            type = 'click';
        }

        if (this._map) {
            this._map._fireMouseEvent(this, e, type, true, this._latlng);
        }
    },

    _initImage: function () {
        var img = this._image = L.DomUtil.create('img',
                'leaflet-image-layer ' + (this._zoomAnimated ? 'leaflet-zoom-animated' : ''));

        img.onselectstart = L.Util.falseFn;
        img.onmousemove = L.Util.falseFn;

        img.onload = L.bind(this.fire, this, 'load');
        img.src = this._url;

        // Urban extension
        img.alt=this.options.alt;
        img.title=this.options.title;
    }

});

/*
 * Popup extension to L.ImageOverlayResp, adding popup-related methods.
 */
L.ImageOverlayResp.include({

    // Location relative to the center of the overlay
    bindPopup: function (content, options) {
        var anchor = L.point(this.options.popupAnchor || [0, 0])
            .add(L.Popup.prototype.options.offset);

        options = L.extend({offset: anchor}, options);
        var c = this._bounds.getCenter();

        return L.Layer.prototype.bindPopup.call(this, content, options);
    },

    _openPopup: L.Layer.prototype.togglePopup,

    // Called from popup...
    getCenter: function(){
      return this._bounds.getCenter();
    }
});

L.imageOverlayResp = function (url, bounds, options) {
    return new L.ImageOverlayResp(url, bounds, options);
};

Sorry if I am posting to the wrong place (or if this exists somewhere and I missed it, seems related to #1727 ). I am using leaflet 0.8-dev.

I hope it helps somebody,
Thanks,

Andreas

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions