javascript - Canvg | Converting SVG to Canvas to output as image - Stack Overflow

I have a plex interactive graphic within an SVG. I want to turn the SVG into a hidden canvas so I can a

I have a plex interactive graphic within an SVG. I want to turn the SVG into a hidden canvas so I can allow the user to output as png/pdf.

test111.js creates div#forSVG and then svg#svg within it (plus circles, paths, text).

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="sql.css">
        <script type="text/javascript" src="d3.v3.js"></script> 


        <script type="text/javascript">
            function start() {

                var canvas = document.getElementById("canvas");

                var svg = document.getElementById("forSVG");
                var svgWider = svg.outerHTML;

                console.log(svg);

                canvg(canvas, svg);

            }
        </script>           




    </head>
    <body onload="start()">
        <script type="text/javascript" src="test111.js"></script>

<script type="text/javascript" src="rgbcolor.js"></script> 
<script type="text/javascript" src="StackBlur.js"></script>
<script type="text/javascript" src="canvg.js"></script>


<canvas id="canvas" width="100%" height="600px"></canvas> 

</body>     

I've tried using svg#svg, div#forSVG and div.outerHTML as an input to canvg function but I constantly get an error such as:

TypeError: undefined is not a function (evaluating 's.substr(0,1)')

There are different errors but they are all around line 50 of canvg.js and I suspect they all concern the s variable being undefined. EDIT 1640: The relevant line of canvg.js telling us what s is:

this.canvg = function (target, s, opts) {

So when I call canvg(canvas, svg) I think s is the svg variable I entered (opts being optional). Console.logging (typeof svg) returns object.

First 60 lines of canvg.js:

/*
 * canvg.js - Javascript SVG parser and renderer on Canvas
 * MIT Licensed
 * Gabe Lerner ([email protected])
 * /
 *
 * Requires: rgbcolor.js - /
 */
(function(){
    // canvg(target, s)
    // empty parameters: replace all 'svg' elements on page with 'canvas' elements
    // target: canvas element or the id of a canvas element
    // s: svg string, url to svg file, or xml document
    // opts: optional hash of options
    //       ignoreMouse: true => ignore mouse events
    //       ignoreAnimation: true => ignore animations
    //       ignoreDimensions: true => does not try to resize canvas
    //       ignoreClear: true => does not clear canvas
    //       offsetX: int => draws at a x offset
    //       offsetY: int => draws at a y offset
    //       scaleWidth: int => scales horizontally to width
    //       scaleHeight: int => scales vertically to height
    //       renderCallback: function => will call the function after the first render is pleted
    //       forceRedraw: function => will call the function on every frame, if it returns true, will redraw
    this.canvg = function (target, s, opts) {
        // no parameters
        if (target == null && s == null && opts == null) {
            var svgTags = document.querySelectorAll('svg');
            for (var i=0; i<svgTags.length; i++) {
                var svgTag = svgTags[i];
                var c = document.createElement('canvas');
                c.width = svgTag.clientWidth;
                c.height = svgTag.clientHeight;
                svgTag.parentNode.insertBefore(c, svgTag);
                svgTag.parentNode.removeChild(svgTag);
                var div = document.createElement('div');
                div.appendChild(svgTag);
                canvg(c, div.innerHTML);
            }
            return;
        }

        if (typeof target == 'string') {
            target = document.getElementById(target);
        }

        // store class on canvas
        if (target.svg != null) target.svg.stop();
        var svg = build(opts || {});
        // on i.e. 8 for flash canvas, we can't assign the property so check for it
        if (!(target.childNodes.length == 1 && target.childNodes[0].nodeName == 'OBJECT')) target.svg = svg;

        var ctx = target.getContext('2d');
        if (typeof(s.documentElement) != 'undefined') {
            // load from xml doc
            svg.loadXmlDoc(ctx, s);
        }
        else if (s.substr(0,1) == '<') {
            // load from xml string
            svg.loadXml(ctx, s);
        }
        else {
            // load from url
            svg.load(ctx, s);
        }
    }

END OF EDIT

Can anyone spot what I've done wrong? the variable svg is not having any trouble finding the div and svg that have been dynamically created (they are logging to console correctly). Thanks

I have a plex interactive graphic within an SVG. I want to turn the SVG into a hidden canvas so I can allow the user to output as png/pdf.

test111.js creates div#forSVG and then svg#svg within it (plus circles, paths, text).

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="sql.css">
        <script type="text/javascript" src="d3.v3.js"></script> 


        <script type="text/javascript">
            function start() {

                var canvas = document.getElementById("canvas");

                var svg = document.getElementById("forSVG");
                var svgWider = svg.outerHTML;

                console.log(svg);

                canvg(canvas, svg);

            }
        </script>           




    </head>
    <body onload="start()">
        <script type="text/javascript" src="test111.js"></script>

<script type="text/javascript" src="rgbcolor.js"></script> 
<script type="text/javascript" src="StackBlur.js"></script>
<script type="text/javascript" src="canvg.js"></script>


<canvas id="canvas" width="100%" height="600px"></canvas> 

</body>     

I've tried using svg#svg, div#forSVG and div.outerHTML as an input to canvg function but I constantly get an error such as:

TypeError: undefined is not a function (evaluating 's.substr(0,1)')

There are different errors but they are all around line 50 of canvg.js and I suspect they all concern the s variable being undefined. EDIT 1640: The relevant line of canvg.js telling us what s is:

this.canvg = function (target, s, opts) {

So when I call canvg(canvas, svg) I think s is the svg variable I entered (opts being optional). Console.logging (typeof svg) returns object.

First 60 lines of canvg.js:

/*
 * canvg.js - Javascript SVG parser and renderer on Canvas
 * MIT Licensed
 * Gabe Lerner ([email protected])
 * http://code.google./p/canvg/
 *
 * Requires: rgbcolor.js - http://www.phpied./rgb-color-parser-in-javascript/
 */
(function(){
    // canvg(target, s)
    // empty parameters: replace all 'svg' elements on page with 'canvas' elements
    // target: canvas element or the id of a canvas element
    // s: svg string, url to svg file, or xml document
    // opts: optional hash of options
    //       ignoreMouse: true => ignore mouse events
    //       ignoreAnimation: true => ignore animations
    //       ignoreDimensions: true => does not try to resize canvas
    //       ignoreClear: true => does not clear canvas
    //       offsetX: int => draws at a x offset
    //       offsetY: int => draws at a y offset
    //       scaleWidth: int => scales horizontally to width
    //       scaleHeight: int => scales vertically to height
    //       renderCallback: function => will call the function after the first render is pleted
    //       forceRedraw: function => will call the function on every frame, if it returns true, will redraw
    this.canvg = function (target, s, opts) {
        // no parameters
        if (target == null && s == null && opts == null) {
            var svgTags = document.querySelectorAll('svg');
            for (var i=0; i<svgTags.length; i++) {
                var svgTag = svgTags[i];
                var c = document.createElement('canvas');
                c.width = svgTag.clientWidth;
                c.height = svgTag.clientHeight;
                svgTag.parentNode.insertBefore(c, svgTag);
                svgTag.parentNode.removeChild(svgTag);
                var div = document.createElement('div');
                div.appendChild(svgTag);
                canvg(c, div.innerHTML);
            }
            return;
        }

        if (typeof target == 'string') {
            target = document.getElementById(target);
        }

        // store class on canvas
        if (target.svg != null) target.svg.stop();
        var svg = build(opts || {});
        // on i.e. 8 for flash canvas, we can't assign the property so check for it
        if (!(target.childNodes.length == 1 && target.childNodes[0].nodeName == 'OBJECT')) target.svg = svg;

        var ctx = target.getContext('2d');
        if (typeof(s.documentElement) != 'undefined') {
            // load from xml doc
            svg.loadXmlDoc(ctx, s);
        }
        else if (s.substr(0,1) == '<') {
            // load from xml string
            svg.loadXml(ctx, s);
        }
        else {
            // load from url
            svg.load(ctx, s);
        }
    }

END OF EDIT

Can anyone spot what I've done wrong? the variable svg is not having any trouble finding the div and svg that have been dynamically created (they are logging to console correctly). Thanks

Share Improve this question edited Dec 2, 2015 at 16:41 emma asked Dec 2, 2015 at 16:14 emmaemma 8043 gold badges10 silver badges25 bronze badges 1
  • If the problem is occurring around canvg.js:50, then I suggest posting canvg.js. Hard to help diagnose the problem when there's nothing to look at. – Teeeeeeeeeeeeeeeeeeeeeeeeeeeej Commented Dec 2, 2015 at 16:31
Add a ment  | 

2 Answers 2

Reset to default 2

Thanks TJ - your point helped me to the right direction.

Canvg seems to need a string or html input, not an object. So this worked:

            var canvas = document.getElementById("canvas");

            var svg = document.getElementById("div#forSVG");
            var svgWider = svg.innerHTML;
            canvg(canvas, svgWider);

Off the top of my head, I'd suggest checking what "s" is. It might not actually be a string, so doing "s.substr(0,1)" will be the "undefined" referenced in your error.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745357817a4624221.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信