html2canvas does not print jsPlumb Connectors

1.3k views Asked by At

How to print SVG elements that are built by jsPlumb.

Known that getting all SVG Elements drawen by jsPlumb is retrieved by this code :

var uiJsPlumbConnectors=jsPlumb.getAllConnections().map(function(conn){return conn.canvas;}) 

All connectors are SVG elements :

Using html2canvas to print all connectors (SVG), it does not work :

html2canvas(uiJsPlumbConnectors).then(function(c){

     window.open(c.toDataURL('image/png'))

});

An image has been generated , however, it is an emply image .

FIDDLE

It seems that html2canvas does not support yet multi-elements drawing ?

3

There are 3 answers

0
David Nguyen On BEST ANSWER

Last time I checked html2canvas was not able to convert SVGs, you will need another script to handle that.

The steps:

  • transfer html elements to canvas
  • transfer svg elements to canvas
  • export canvas

I used https://code.google.com/p/canvg/ to export to the same canvas after using html2canvas. Hope that helps you.

0
Abelini On

Its a old question, but, this helped me. Mode details.

$clone.find('.jtk-connector').each(function () {
      // for every SVG element created by JsPlumb for connections...
      var left = parseInt(this.style.left, 10) + 'px';
      var top = parseInt(this.style.top, 10) + 'px';
      this.removeAttribute('style');
      this.removeAttribute('position');
      this.setAttribute('width', parseInt(this.getAttribute('width'), 10)  + 'px');
      this.setAttribute('height', parseInt(this.getAttribute('height'), 10) + 'px');
      this.setAttribute('preserveAspectRatio', 'xMidYMid meet');
      this.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
      // this.children[0] is the path for connection line
      // this.children[1] is the path for connection arrow shape
      this.children[0].setAttribute('xmlns', 'http://www.w3.org/2000/svg'); 
      this.children[1].setAttribute('xmlns', 'http://www.w3.org/2000/svg');
      this.setAttribute('viewbox', '0 0 ' + parseInt(this.getAttribute('width'), 10) + ' ' + parseInt(this.getAttribute('height'), 10));
      this.children[0].setAttribute('stroke-width', '2px');
      this.children[0].setAttribute('stroke', '#c9c9c9');
      this.children[1].setAttribute('fill', '#c9c9c9');
      this.children[1].setAttribute('stroke', '#c9c9c9');
      $clone.find(this).wrap('<span style="position: absolute; left: ' + left + '; top: ' + top + ';"></span>');
    });
0
patrick On

I just implemented this

<%--stuff for printing--%>
<script type="text/javascript" src="../../../../Scripts/Print/html2canvas.js"></script>
<script src="<%=AdminPath%>Scripts/canvg/rgbcolor.js" type="text/javascript"></script>
<script src="<%=AdminPath%>Scripts/canvg/StackBlur.js" type="text/javascript"></script>
<script src="<%=AdminPath%>Scripts/canvg/canvg.js" type="text/javascript"></script>

jsplumb div

<div class="demo statemachine-demo" id="statemachine-demo" style="margin: 0px;">
            </div>

hidden div for printing

            <div id="canvasDiv" style='visibility:hidden;' >
            </div>


function renderImage()
{
    var statemachinediv = document.getElementById('statemachine-demo'); 

    html2canvas([statemachinediv], {
        onrendered: function (canvas) {

            document.getElementById('canvasDiv').appendChild(canvas);
            var svgList = $(statemachinediv).find( "svg" );

            svgList.each(function(index, value) { 

                try 
                {
                    var svgExample = this; 

                    var serializer = new XMLSerializer();
                    var svgMarkup = serializer.serializeToString(svgExample);

                    if(svgMarkup.indexOf("_jsPlumb_connector") > -1)
                    {
                        var leftIndex = svgMarkup.indexOf("left: "); 
                        var endOfLeft = svgMarkup.indexOf("px", leftIndex);
                        var leftPosition = svgMarkup.substring(leftIndex+6, endOfLeft );
                        var left = parseInt(leftPosition); 

                        var topIndex = svgMarkup.indexOf("top: "); 
                        var endOfTop = svgMarkup.indexOf("px", topIndex);
                        var topPosition = svgMarkup.substring(topIndex+5, endOfTop );
                        var top = parseInt(topPosition); 

                        svgMarkup = svgMarkup.replace('xmlns="http://www.w3.org/2000/svg"',''); 

                        var connectorCanvas = document.createElement('canvas');
                        canvg(connectorCanvas, svgMarkup); //add connector to canvas

                        var context = canvas.getContext('2d');
                        context.drawImage(connectorCanvas, left, top);
                    }
                }
                catch(err)
                {
                    showBalloon('error in print'); 
                }
            });


            var stateMachineName =     $("#stateMachineDropDown option:selected").text();

            var data = canvas.toDataURL('image/png');

            var mywindow = window.open('', 'my div', 'height=400,width=600');

            mywindow.document.write('<html><head><title>' + stateMachineName + '</title>');
            mywindow.document.write('</head><body ><table><tr><td>');
            mywindow.document.write('</td></tr></table><img src="' + data + '" />');
            mywindow.document.write('</body></html>');

            mywindow.print();




        }
    });

    return false; 

}