openseadragon / svg-overlay

An OpenSeadragon plugin that adds SVG overlay capability.
BSD 3-Clause "New" or "Revised" License
58 stars 28 forks source link

Options when doing extreme zooming #15

Open friarpat opened 8 years ago

friarpat commented 8 years ago

Using OpenSeadragon (latest version 2.1.0) to display a hierarchy of images. I'm using svg-overlay to provide a highlight around the image currently being hovered over. All works well at reasonable zoom levels. The hierarchy of images can be quite deep, requiring some very high zoom levels. OpenSeadragon is handling the imaging correctly, but when I get to some extreme zooming, the border around the image becomes flakey. At some point, IE just refuses to draw the highlight at times or maybe just portions of the highlight. FF and Chrome work better, but more often than not, the border is no longer around the image.

See the two captures below of the HTML that is being created by svg-overlay for the transform on the SVG that is being attempted. I've tried resizing the svg by capturing a mouseMove event after the zooming is complete. (Scroll the mouse, then move it slightly.) Doesn't make any difference.

Are there any options between OpenSeadragon and svg-overlay to correct this highlight at high zoom levels?

Here are the two captures showing the transform calculations. Mouse wheel scroll in. SVG outline is transformed too far to the left. `

</svg`

One mouse wheel scroll out. SVG outline is transformed to far to the right. `

`

friarpat commented 8 years ago

A bit of additional information. I added a console.log message to the svg-overlay code in the resize function to present the p.x/y, scale, and zoom values. While those log messages stream out, the overlay is positioned properly. Once those stop streaming out, there is a short delay, (1/2 second?), and then the overlay repositions to the wrong location. Is that the browser digesting something, or is OpenSeadragon doing some final drawing that repositions the image that is being highlighted wrong? How can I tell the difference?

I am currently doing this with the latest version of FF.

iangilman commented 8 years ago

Interesting. I imagine it has to do with the extreme scale being applied to the SVG. I wonder if changing the coordinate system would help. If your images are 10 viewport coordinates across, try making them 10,000 instead or 0.0001. I believe that should change the SVG scale as well.

As for that delay, I don't know...perhaps it's the browser trying to deal with the extreme values?

friarpat commented 8 years ago

WOW! Did THAT help! The overlay now works with zooming at that level now. Don't know if I had this problem before since things weren't working in the first place, but now I can drag the image a fair distance before the svg is updated - maybe a 1/3 of the image. Is there some threshold that I need to adjust to cause the overlay to adjust sooner? I've tried various levels of the coordinate scaling - didn't seem to make a difference.

friarpat commented 8 years ago

I have the drag issue resolved. It's not pretty, but it works! It turns out, the drag issue was only happening with IE. As usual, a search for something similar led me to:

http://stackoverflow.com/questions/15693178/svg-line-markers-not-updating-when-line-moves-in-ie10

Adding the following line:

this._svg.parentNode.insertBefore(this._svg, this._svg);

after the, this._node.setAttribute that sets the transform in svg-overlay.js, resolved the problem. I can now drag the image around and the overlay follows properly. No flickering. Doesn't seem to affect performance from what I can tell. I would like to limit it to IE only, but there's not always a clean way of detecting that.

If there is a reason NOT to do this, please advise!

As usual, thanks for your help and quick, detailed, and accurate responses on these and all the questions that hit this and OpenSeadragon.

iangilman commented 8 years ago

Interesting! Seems fair to do a little browser sniffing for that, but yeah, seems like a reasonable fix, if it works. Do you think this is the sort of general issue that we should include a fix for in the plug-in?

Also, sounds like maybe we should update the Readme to suggest keeping the viewport coordinate system in big numbers.

Would you be up for making a patch around either of these issues?

friarpat commented 8 years ago

Sorry for the delay. I would like to make these updates, but oddly enough, I need to get legal to give me permission to make these updates. I have verbal permission…awaiting it in written form.

iangilman commented 8 years ago

Cool... thank you for pursuing it!

hamza-arshad commented 8 years ago

We are also facing the extreme zoom level issue on safari, when we zoom to the max level of the slide our svg disappears, I am sharing the link below you can check it in safari and firefox too. It is also not working on safari, firefox, chrome on iOS 8 or later. Can you guess the issue and suggest a solution?

Go to the following link, after it loads, press the overlay button on right top and select "granule cells" from the heirarchy, it will not appear on safari but it will appear on any other browser. Also try "dentate-layers" it will appear, disappears partially on the zoom-in/zoom-out on safari but not on any other browser. http://thevisiblebrain.com/#/slide/1249/overlay

Your help will be highly appreciated, Thank you in advance.

iangilman commented 8 years ago

Have you tried changing the scale of your scene as suggested above? It may be the same issue.

hamza-arshad commented 8 years ago

Can you explain it a little? I haven't understood it completely by reading the above comments.

iangilman commented 8 years ago

It's possible the issue you're seeing has to do with the precision of the SVG coordinates. By default OSD uses a coordinate system that goes from 0 on the left to 1 on the right (so 0.5 is the middle), but that means you can dealing with very small numbers, and it seems that this causes trouble with SVG sometimes.

To fix, create your viewer with a bigger coordinate system. For instance:

var viewer = OpenSeadragon({
  ...,
  tileSources: [{
    width: 1000,
    tileSource: tileSource
  }]
});

... and then multiply all of your overlay coordinates by 1000 as well to match.

detarmstrong commented 8 years ago

I tried implementing a bigger coordinate system in this fiddle but I must be off. Any hint in the right direction is appreciated!

avandecreme commented 8 years ago

I am not sure how OSD was interpreting your code but here is the proper syntax:

var viewer = OpenSeadragon({
  id: 'container',
  tileSources: [{
  width: 10000,
  tileSource:{
    Image: {
      xmlns: 'http://schemas.microsoft.com/deepzoom/2009',
      Url: 'https://s3-us-west-2.amazonaws.com/thewaves/hotel_room_final_files/',
      TileSize: 254,
      Overlap: 1,
      Format: 'jpg',
      Size: {
        Width: 30000,
        Height: 31252
      }
    }
  }}],
  visibilityRatio: 1.0,
  maxZoomPixelRatio: 5,
  immediateRender: true,
  showNavigationControl: false
});
detarmstrong commented 8 years ago

Thank you @iangilman and @avandecreme, that works beautifully.

klineberry commented 7 years ago

@iangilman - I followed this same tip, and it does fix the problem with the svg not displaying properly. The problem is the viewport now only wants to show a max of 'width' of the image. For example, if width is set to 4, the most the viewport shows is one quarter of the image. I assume there is some way to instruct the viewport that it should now span 4 units across?

iangilman commented 7 years ago

@klineberry Are you setting these variables when you create the viewer or afterwards? If afterwards, you may need to zoom back out or something (e.g. viewer.viewport.goHome()). If you're setting them up when you create the viewer, can you share your settings here?

klineberry commented 7 years ago

@iangilman I'm calling view.open() after OpenSeadragon has been initialized. Calling goHome() has no effect, since its already initially at 'home'.

            var image = {
                width: result.width,
                height: result.height,
                tileSize: result.tileSize,
                overlap: result.overlap,
                minLevel: result.minLevel,
                maxLevel: result.maxLevel,
                getTileUrl: function (level, x, y) {
                    return base_url + '/' + image_id + '-dzi-tileset/image_files/' + Math.max(0, level) + '/' + x + '_' + y + '.' + result.format
                }
            }

            var options = {
                width: 4,
                tileSource: image
            }

            self.viewer.open(options)
klineberry commented 7 years ago

And sorry - you asked for the initial settings. Here they are:

        this.viewer = window.OpenSeadragon({
            id: 'osd-view',
            autoResize: true,
            visibilityRatio: 1.0,
            constrainDuringPan: false,
            defaultZoomLevel: 1,
            minZoomLevel: 0,
            maxZoomLevel: 10,
            zoomInButton: 'zoom-in',
            zoomOutButton: 'zoom-out',
            homeButton: 'reset',
            fullPageButton: 'full-page',
            nextButton: 'next',
            previousButton: 'previous',
            showNavigator: true,
            navigatorId: 'navigator',
            crossOriginPolicy: 'Anonymous',
        })

        var overlay = this.viewer.svgOverlay();
        $(window).resize(function () {
            overlay.resize();
        });
klineberry commented 7 years ago

OK, I don't have an explanation for this, but setting the defaultZoomLevel to 0 fixes the issue. The initial display now properly exposes the entire image. And the bounding area of the viewport now properly encompasses the entire image. I'm guessing I misunderstood the meaning of defaultZoomLevel.

iangilman commented 7 years ago

Yeah, I believe defaultZoomLevel is based on a width of 1. With a width of 4, you'd need to set it to 0.25. Anyway, better to just leave it off and let OSD take care of it.

Glad you got it sorted out :)