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

Created on 9 Apr 2016  ·  26Comments  ·  Source: niklasvh/html2canvas

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

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

Most helpful comment

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 [email protected] 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
https://github.com/niklasvh/html2canvas/issues/846#issuecomment-229420457,
or mute the thread
https://github.com/notifications/unsubscribe/ABWsecUQ2l-rxisMZ4HCKu1nh-mbIMU1ks5qQqSQgaJpZM4IDr12
.

All 26 comments

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

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((

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?

@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();
  }

@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:

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.

Any news about this issue? Thanks!

@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

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.

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.

@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.

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 [email protected] 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
https://github.com/niklasvh/html2canvas/issues/846#issuecomment-229420457,
or mute the thread
https://github.com/notifications/unsubscribe/ABWsecUQ2l-rxisMZ4HCKu1nh-mbIMU1ks5qQqSQgaJpZM4IDr12
.

@chemitaxis Awesome! Looking forward to the fix.

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

@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.

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

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

2016-07-21 20:36 GMT+02:00 atdiff [email protected]:

@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
https://github.com/niklasvh/html2canvas/issues/846#issuecomment-234343779,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABWseVDGMW_cSyV_ZMDkkUilXC5mK_Mrks5qX7wcgaJpZM4IDr12
.

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

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.

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.

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

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.

@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: https://github.com/niklasvh/html2canvas/issues/846#issuecomment-229035694)

@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

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.

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

Fixed in 1.0.0

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tjchambers32 picture tjchambers32  ·  3Comments

wbarrantes picture wbarrantes  ·  3Comments

diego-rey picture diego-rey  ·  3Comments

koreanman picture koreanman  ·  4Comments

yasergh picture yasergh  ·  5Comments