Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'SVGElement.offsetWidth' is deprecated and will be removed in M50, around April 2016 #846

Closed
alex-wdmg opened this issue Apr 9, 2016 · 26 comments

Comments

@alex-wdmg
Copy link

Google has refused to support "offsetWidth" for SVG.
There are ideas?

Doc: https://www.chromestatus.com/features/5724912467574784

@Dayjo
Copy link

Dayjo commented Apr 12, 2016

Was just about to raise this! Slightly concerned something will just stop working this month.

@alex-wdmg
Copy link
Author

Yes, apparently at the Opera 37 beta does not work. In addition, the latest version of the plug-in problems to display backgrounds and borders. I have one, they do not check?

In demo too, backgrounds and borders not show((

@MarcBalaban
Copy link

This is a big problem as our SVGs will no longer render.

The biggest culprit is within this function:

function offsetBounds(node) {
    var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};

    return {
        top: node.offsetTop + parent.top,
        bottom: node.offsetTop + node.offsetHeight + parent.top,
        right: node.offsetLeft + parent.left + node.offsetWidth,
        left: node.offsetLeft + parent.left,
        width: node.offsetWidth,
        height: node.offsetHeight
    };
}

lines 1887 - 1898 in html2canvas.js

All offsetTop, offsetLeft, offsetWidth, offsetHeight are now undefined for SVGs

The recommended solution is getBoundingClientRect(), but still can't get it working.

Does anyone have a solution for this?

@Dayjo
Copy link

Dayjo commented Apr 19, 2016

@MarcBalaban I haven't tried it yet, but would it not just be adding this to above the return in that function;

if ( node.tagName === 'SVG' ) {
    return node.getBoundingClientRect();
  }

@MarcBalaban
Copy link

@Dayjo unfortunately not, it's definitely on the right path, but this line

var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};

does not execute properly either either as offsetParent has also been depreciated:

@Dayjo
Copy link

Dayjo commented Apr 20, 2016

Hmm yeah, looking a little more into it, it may need to use something like the getBoundingBoxInArbitrarySpace function here; https://svn.apache.org/repos/asf/commons/sandbox/gsoc/2010/scxml-js/trunk/src/javascript/scxml/cgf/util/svg.js as per http://stackoverflow.com/questions/5996005/how-to-use-element-offsetparent-with-html-svg-elements#answers

Not had a chance to do any sort of testing yet though.

@chemitaxis
Copy link

Any news about this issue? Thanks!

@Dayjo
Copy link

Dayjo commented Jun 7, 2016

@chemitaxis - despite the warning, so far I've not had any problems with the result of html2canvas. However, who knows if / when this change will actually be implemented in Chrome

@Dayjo
Copy link

Dayjo commented Jun 28, 2016

Looks like this has now stopped working Chrome. SVGs seem to either be not rendered at all, incorrectly, or at the wrong scale / in the position in the canvas.

@niklasvh - any thoughts on this? If I had the time I would happily have a bash at a fix but i'm choca at the moment.

@Dayjo
Copy link

Dayjo commented Jun 28, 2016

I had a shot at this using https://svn.apache.org/repos/asf/commons/sandbox/gsoc/2010/scxml-js/trunk/src/javascript/scxml/cgf/util/svg.js

But wasn't sure where I needed to implement it, I tried in both the offsetBounds and getBounds function but to no avail. The X and Y coords seem to be correct, but the width and height are all wrong, not sure if this is because I'm using css to make the SVG 100% width of the container and auto height. Would need to do some more extensive testing.

I have a preliminary branch going on here (https://github.com/Dayjo/html2canvas/tree/issue-846), using the latest beta commit. if anyone wants to test, should be able to use the dist version, or just rebuild if you wish. No idea how well / if at all it will work.

@sumigoma
Copy link

@Dayjo Yes, I've noticed this too. SVGs are totally in the wrong position and are almost always off the screen now that all the offset*s evaluate to undefined. I also tried my hand at solving this using recursive getBoundingClientRect - but no luck :( I'll take a look at your branch.

@chemitaxis
Copy link

I have solved it... I will add the solution at the end of the week if I
have time. Sorry for the delay... It's working on FF, Safari and Chrome.
Best.
On Wed, 29 Jun 2016 at 19:00, Yuki K notifications@github.com wrote:

@Dayjo https://github.com/Dayjo Yes, I've noticed this too. SVGs are
totally in the wrong position and are almost always off the screen now that
all the offset*s evaluate to undefined. I also tried my hand at solving
this using recursive getBoundingClientRect - but no luck :( I'll take a
look at your branch.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#846 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABWsecUQ2l-rxisMZ4HCKu1nh-mbIMU1ks5qQqSQgaJpZM4IDr12
.

@sumigoma
Copy link

@chemitaxis Awesome! Looking forward to the fix.

@sumigoma
Copy link

sumigoma commented Jul 7, 2016

Hey @chemitaxis, can you create a PR or link to your fork if you have time?

@atdiff
Copy link

atdiff commented Jul 21, 2016

@chemitaxis any progress on this? I'm hoping to test the code out on a project I'm doing to see if it solves all of my SVG problems especially with IE.

@chemitaxis
Copy link

Hi @atdiff :) I have solved the problem using other libraries...

<script type="text/javascript" src=" https://gabelerner.github.io/canvg/rgbcolor.js"></script> <script type="text/javascript" src=" https://gabelerner.github.io/canvg/StackBlur.js"></script> <script type="text/javascript" src=" https://gabelerner.github.io/canvg/canvg.js"></script>

With this, I can convert SVG to Canvas, and them, export fine...

2016-07-21 20:36 GMT+02:00 atdiff notifications@github.com:

@chemitaxis https://github.com/chemitaxis any progress on this? I'm
hoping to test the code out on a project I'm doing to see if it solves all
of my SVG problems especially with IE.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#846 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABWseVDGMW_cSyV_ZMDkkUilXC5mK_Mrks5qX7wcgaJpZM4IDr12
.

@Dayjo
Copy link

Dayjo commented Jul 22, 2016

So @chemitaxis not fixed this issue, just found a workaround no longer using html2canvas?

@chemitaxis
Copy link

Yes, using a mixing... But I have totally integrated, I need to refactoring to integrate and do a pull request... But I dont have time... Sorry, I will upload an example ASAP. Best.

@sumigoma
Copy link

That's hardly a fix... It shouldn't be necessary to work around the problem like that using other libraries. The SVGs are just incorrectly laid out, and it should just be a matter of calculating the correct positions.

@Dayjo
Copy link

Dayjo commented Sep 13, 2016

Has anyone actually found a fix for this? SVGs seem to just not render anymore.

@jgunderson-IAS
Copy link

jgunderson-IAS commented Oct 20, 2016

It's not a fix but I did find a small workaround. I also could not get SVG to display properly in Chrome but it would display in Safari. All I did was add a width attribute to the SVG inline element. Even with an inaccurate width attribute it printed out like it should in both Chrome and Safari:

    var deferred = $q.defer();

    element.find('svg').attr('width', '100px');

    html2canvas(element, {
        background: '#eee',
        onrendered: function(canvas) {
            var a = document.createElement('a');
            a.href = canvas.toDataURL('image/jpeg', 1).replace('image/jpeg', 'image/octet-stream');
            a.download = fileName + '.jpg';
            a.click();
            deferred.resolve();
        }
    });

    return deferred.promise;

Edit: Something to add that isn't related but others may find useful when searching here. Firefox didn't seem to work with my above method. My SVG had # signs for the hex colors(ex: #ccc). Since these are reserved characters in URLs and Firefox is strict about it, the SVG did not appear. I replaced with rgb values instead and now Firefox displays correctly.

@Dayjo
Copy link

Dayjo commented Oct 21, 2016

@jgunderson-IAS thanks for this I shall try it as a quick workaround.

I'm hopefully going to get a chance to spend a day looking at this bug, well, maybe half a day on this, then half a day on what I'm using it for, but should give me an opportunity to possibly implement a real solution.

@niklasvh not sure if you've looked at this at all, or if you have any suggestions as to how best to implement a fix (see: #846 (comment))

@Dayjo
Copy link

Dayjo commented Oct 24, 2016

@jgunderson-IAS I have been explicitly setting the size of SVGs, and whilst this hacky approach does mean that they get rendered, it seems like the size is inconsistent, I'm setting both height and weight properties and yet they regularly appear 'squashed'. Unfortunately my pages rely on svg sizes being controlled by CSS and being 100% of their container, so whilst this is a stepping stone, I think I'm going to have to look at recoding the library to properly calculate the sizes

@Dayjo
Copy link

Dayjo commented Oct 24, 2016

Here's an example of how svgs are rendering now that I'm setting the width on the 'onClone' event based on the parent element width (all svgs are set to 100% width in css), height seems to mess it up even more;

html

image

canvas

image

I'm using;

onclone: function(doc){
    var w,h;
    var svgs = doc.querySelectorAll('svg');
    for ( var s = 0; s < svgs.length; ++s ) {
        w = svgs[s].parentElement.offsetWidth;
        svgs[s].setAttribute('width', w );
    }
}

It seems like it really depends on the svg itself as to how well it renders it's aspect ratio. For instance the first (leaf) svg, is squashed a lot more than the other two.

@Dayjo
Copy link

Dayjo commented Oct 24, 2016

Unfortunately I've had to abandon using html2canvas and use a server-side solution instead (wkhtmltoimage) specifically because it cannot render svgs accurately. I was unable to get it to work using getBoundingClientRect or getBBox etc

@niklasvh
Copy link
Owner

Fixed in 1.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants