waynegm / imgViewer2

Extensible and responsive jQuery plugin to zoom and pan images based on the Leaflet mapping library
MIT License
60 stars 34 forks source link

Whole Div Crosshair #1

Closed grubbychicken closed 7 years ago

grubbychicken commented 7 years ago

Hi Wayne,

Great plugin! Thanks very much! I am wondering if it is possible to add a div wide crosshair, like I have done in this fiddle?

I have kind of got this working using your imgViewer(1) but the crosshair-v keeps getting hidden behind the viewport. Would you be able to help me implement this please?

I think I'll use this imgViewer2 moving forward as I want to allow my users to drop a mini crosshair on a given co-ordinate. I assume I can do this with markers? Would you agree imgViewer2 is the best version to use for this functionality.

Thanks again!

waynegm commented 7 years ago

Hi, The original imgViewer plugin overlays a div (the view) on the target image and displays a scaled and translated copy of the image in the div. If you attach your crosshair code to the original image it is hidden by the elements inserted by the plugin. Instead you need to attach your crosshair code to the elements inserted by the plugin. These elements can be obtained like this:

var $img = $("#image").imgViewer();
var $widg = $img.data().wgmImgViewer();
$view = $widg.view;
$zimg = $widg.zimg;

Then you can use some jQuery to insert your crosshairs into $view (the viewport div).

My main motivation in creating imgViewer2 was to find a way to better support both desktop and mobile. The event library I use in imgViewer doesn't seem to be getting a lot of updates while the Leaflet mapping widget used in imgViewer2 seems to be more actively maintained. Another advantage of imgViewer2 is that you can use Leaflet plugins. For the case of crosshairs there is already a plugin Leaflet.Crosshairs which you should be able to use like this (warning untested):

var $img = $("#image").imgViewer2();
var map = $img.imgViewer2("getMap");
L.crosshairs().addTo(map);
grubbychicken commented 7 years ago

Thanks Wayne that's a big help. Although I'm struggling to get the crosshair to work using the original imgViewer and your first example.

var $widg = $img.data().wgmImgViewer();

Keeps throwing the error: $img.data(...).wgmImgViewer is not a function

Currently my code looks like this:

;(function($) {
    $(document).ready(function() {
        var $img = $(".image1").imgViewer({
            zoomable: true,
            draggable: true,
            zoomMax: 3,
            onClick: function( e ) {
                var pos = this.cursorToImg( e.pageX, e.pageY);
                var imgpos = this.relposToImage(pos);
                $("#c1").html("Selected: X: " + imgpos.x + " Y: " + imgpos.y);
            }
        });
    var $widg = $img.data().wgmImgViewer();
    $view = $widg.view;
    $zimg = $widg.zimg;
    $($view).append('<div class="hair" id="crossv"></div>');
    $($view).append('<div class="hair" id="crosshair-h"></div>');
    var cH = $('#crosshair-h');
    var cV = $('#crossv');
    $($view).on('mousemove',function( e ){
            cH.css('top', e.pageY),
            cV.css('left', e.pageX);
    });

    });
})(jQuery);

Any ideas?

waynegm commented 7 years ago

My bad - there shouldn't be brackets after wgmImgViewer, i.e.:

var $widg = $img.data().wgmImgViewer;

Also you don't have to use the jQuery slector '$' as $view should already be a jQuery object so $view.append and $view.on should be enough.

grubbychicken commented 7 years ago

Ah yes, thanks Wayne! As you can probably tell, I'm a JS amateur, but trying to learn.

I'm now facing the same trouble I had before where the vertical crosshair is hidden behind the view. I know this is probably to do with the way I have implemented the crosshair solution and not a problem with your plugin, but I was wondering if you had any ideas of why this might be happening?

Screenshot included for clarity

screen shot 2017-03-27 at 08 41 48

.

Thanks!

waynegm commented 7 years ago

I think you'll find that the cV crosshair is on the page below the image not actually behind it. In your mousemove event handler try this:

var elem = e.target;
cH.css({
   top: e.pageY,
   left: elem.offsetLeft,
  width:elem.width
});
cV.css({
   top: elem.offsetTop,
   left: e.pageX,
   height: elem.height
});

Here e.target is the viewport div and I am ensuring the crosshair extents and position are restricted to the div which I presume is what you want.

grubbychicken commented 7 years ago

Perfect! Thanks so much for you help Wayne! I really appreciate it!