Html2canvas: Text tags in SVG overlap (duplicated / doubling)

Created on 19 Feb 2015  ·  24Comments  ·  Source: niklasvh/html2canvas

(Sorry, I am not good at english)

Hello,
I am using this awesome script to render SVG tags
There is some text overlapping when I render the text tag in SVG to canvas
Text tag be processed as a Text node and also SVG
You can see that easily with transform property
2015-02-19 15 08 29_2
Here is sample code (with html2canvas 0.5.0-alpha2)

<html>
<head>
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
  <script type="text/javascript" src="js/html2canvas.js"></script>
</head>
<body>
  <svg width="100" height="100">
    <g transform="translate(20,20)">
      <text dy=".45em" y="10" x="0" dx="-.8em" transform="translate(0,0) rotate(-70)" style="font-size:12px;">Text</text>
    </g>
  </svg>
  <script>
    $(document).ready(function() {
      html2canvas(document.body, {
        onrendered: function(canvas) {
          document.body.appendChild(canvas);
        }
      });
    })
  </script>
</body>
</html

And Here is my quick change

NodeParser.prototype.getChildren = function(parentContainer) {
    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
        var container = [node.nodeType === Node.TEXT_NODE && node.parentElement.tagName !== "text" ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
        return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
    }, this));
};

I hope this will help

Needs More Information

Most helpful comment

@hyojin
After test it on IE, your fix doesn't works because parentElement property is not populate on the current node. Use parentNode instead ! In any case, it will be more clear because we are into the NodeParser and it talk about node.

Otherwise, instead test on tag name, i change my code to test the instance of parentNode and process the current node has a TextContainer only if the parentNode isn't a SVGElement.

It works on chrome and ie11. on firefox i can't test it because of blank canvas bug !

My code

NodeParser.prototype.getChildren = function(parentContainer) {
    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
        var container = [node.nodeType === Node.TEXT_NODE && !(node.parentNode instanceof SVGElement) ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
        return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
    }, this));
};

I hope this helps.

All 24 comments

Thank you#Hyojin. That helps me.

Thanks ,help me a lot!

Thanks for your fix !

you can also check on tspan tagName :
node.nodeType === Node.TEXT_NODE && node.parentElement.tagName !== "text" && node.parentElement.tagName !== "tspan"

@ncoquelet I updated my code. Thanks!

@hyojin
After test it on IE, your fix doesn't works because parentElement property is not populate on the current node. Use parentNode instead ! In any case, it will be more clear because we are into the NodeParser and it talk about node.

Otherwise, instead test on tag name, i change my code to test the instance of parentNode and process the current node has a TextContainer only if the parentNode isn't a SVGElement.

It works on chrome and ie11. on firefox i can't test it because of blank canvas bug !

My code

NodeParser.prototype.getChildren = function(parentContainer) {
    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
        var container = [node.nodeType === Node.TEXT_NODE && !(node.parentNode instanceof SVGElement) ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
        return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
    }, this));
};

I hope this helps.

fix my firefox problem, works on ff too :-)

More clear!
I also checked that it works well on ff.
I merged your fix and pull request was updated. Thanks :)

@hyojin @ncoquelet thanks for the investigation into this and the fix. I ran into the exact same problem the other day and I wasn't entirely sure what was causing it.

I am not sure where I am getting confused here but I am getting the exception as "Uncaught ReferenceError: NodeParser is not defined"

@Suchetana10 When did you get the exception? in loading script?

@hyojin thank you.. worked for me

@hyojin thanks! works perfectly for me too

@vishwasvadavi @nugen I'm happy to hear that! :)

Some people still have the issue with text element, I change this issue opened and I will send PR again.

image

Does anyone have a build of the library with this fix in it that I can test? Seeing same issue on highcharts page..

Is this build available with the fix? I am still facing this issue with highcharts.

Is this fix available in build or we have to create an override ?

Is this still an issue with v1.0.0? If so, could you please share an example on jsfiddle.

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

Dear @niklasvh ,

Thank you for this amazing library. I am able to reproduce this issue with the latest version - v1.0.0-rc.3

I have created an example on CodePen here (Chrome only) where you will see that some of the text nodes (in the Graph title) are duplicated.

Steps to reproduce -

  1. Please open the CodePen link - https://codepen.io/karannagupta/pen/RXpddB in Chrome only
  2. Click on Copy to Clipboard button
  3. Wait for the animation to finish (or see console for copied message)
  4. Paste the graph in paint or a document (ctrl + v)

The graph titles are added on Line#193

@hyojin , would you please open the issue again?

Regards,
Karan



text-duplication

Hi @karannagupta
Could you try my branch to check whether it comes from the same reason?

Hi @hyojin

With your version of the library (v0.5.0-alpha2) it doesn't work. You can test your library on my Pen here

Also, I would like to use the latest version of html2canvas. I also don't need to use html2canvas.svg then.

Regards,
Karan

Turns out it is an issue with Unicode fonts

image

Was this page helpful?
0 / 5 - 0 ratings