bumbu / svg-pan-zoom

JavaScript library that enables panning and zooming of an SVG in an HTML document, with mouse events or custom JavaScript hooks
https://github.com/ariutta/svg-pan-zoom#demos
BSD 2-Clause "Simplified" License
1.76k stars 388 forks source link

IonicV4 - inline SVG image disappears #353

Open slclark opened 5 years ago

slclark commented 5 years ago

Bug report

I am upgrading an application from Ionic-v3 to Ionic-v4. My app has an inline SVG image and is very simply setup.

Expected behaviour

Simple inline SVG image will display and pan/zoom while using IonicV4.

Actual behaviour

It works great in V3 but in V4, upon setting up the library to connect to the SVG, the SVG image disappears.

Steps to reproduce the behaviour

I forked a rough Ionic V4 boilerplate at the following URL. It gives some TypeErrors upon changing code - but that is not the issue. You can just refresh to get rid of those.

https://stackblitz.com/edit/ionic-v4-angular-tabs-svgpanzoom

Tab one has the full setup while tab 2 has svgPanZoom(elm, options) commented out.

In Tab 1, the SVG image no longer displays and interacting with the screen throws errors (ERROR Error: Failed to execute 'inverse' on 'SVGMatrix': The matrix is not invertible).

In Tab 2, the SVG still displays because it hasn't been setup.

The only difference between the two tabs is the svgPanZoom init.

Configuration

bsbechtel commented 5 years ago

@slclark I'm seeing this same issue. Did you figure out a work around?

slclark commented 5 years ago

@bsbechtel No, not yet.

bsbechtel commented 5 years ago

@slclark This is a roadblock for something I'm working on, so I'll probably be focusing on it quite a bit over the next few days. @ariutta Do you happen to have any ideas on what might be causing this?

To add a little more detail to the discussion, the graphic element transform matrix has a bunch of NaN values in it when it is instantiated:

image
FrankBuchholz commented 5 years ago

...

I'm not sure if this is the real live example as this page shows quite different svg-content on both tabs:

1st tab, no svg shown:

<svg _ngcontent-itp-c2="" id="map" style="overflow: hidden; display: inline; width: inherit; min-width: inherit; max-width: inherit; height: inherit; min-height: inherit; max-height: inherit; " version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events">
    <g id="viewport-20191023145915309" class="svg-pan-zoom_viewport" transform="matrix(0,0,0,0,0,0)" style="transform: matrix(0, 0, 0, 0, 0, 0);">
        <circle _ngcontent-itp-c2="" cx="500" cy="500" r="50"/>
    </g>
[...]

2nd tab, svg is visible:

<svg _ngcontent-itp-c3="" id="map" style="display: inline; width: inherit; min-width: inherit; max-width: inherit; height: inherit; min-height: inherit; max-height: inherit; " version="1.1" viewBox="0 0 900 900" xmlns="http://www.w3.org/2000/svg">
    <circle _ngcontent-itp-c3="" cx="500" cy="500" r="50"/>
[...]

On the 1st tab there is no viewBox element, but you have an additional group with strange command transform="matrix(0,0,0,0,0,0)". If I take this transform statement away, the dot becomes visible.

bsbechtel commented 5 years ago

So I have a project that works on the web, and the implementation is exactly the same as the Ionic implementation, and I'm seeing the same issue with the graphic element being added improperly.

I've done a little digging, and with Ionic, so far from what I can tell the getBoundingClientRectNormalized method in svg-utilities is returning 0 values for all properties in Ionic. Not sure what's causing this yet, but that appears to be the root cause of the issue.

image

Edit: The web project uses Angular 8, so that helps narrow the issue to Ionic, as the implementations are otherwise identical.

bsbechtel commented 5 years ago

So I figured out what's going on here. See this issue. Basically your svg dimensions are not known when the component is initialized, as is the same with all ionic components, because they are based on web components. The easy fix is to wrap your zvg-pan-zoom initializer in a setTimeout function. The right and hard way to do it is to hook into your ionic lifecycle methods or wait for the web component to fire a ready event.