Canvas toDataURL在第一次尝试时未返回完整的URL

3

我有一些代码,可以将使用Raphael绘制的SVG图形(一个加载到SVG中的400x400图像)转换为带有canvg的画布,然后应该使用canvas.toDataURL将其变成图像。所有这些都应该在按下按钮时发生。前两个步骤有效,但第三个步骤存在问题。第一次按下按钮时,在最终的div中放置了一个300x150的空白图像,而不是400x400的图像。如果我再次按下按钮,则图像会正确显示(大小和一切正常)。我尝试使用img.onload和jquery版本$(img).load,但似乎都无法解决问题。因此,我觉得这是画布还没有完全绘制的问题,但我无法证明,并且我似乎无法让代码等待它被绘制。以下是所有代码。我试图将其制作成fiddle,但我一直收到图像安全错误。

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
    <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script> 
    <script type="text/javascript" src="scripts/jquery.js"></script>
    <script type="text/javascript" src="scripts/raphael.js"></script>
    <script type="text/javascript" src="scripts/excanvas.compiled.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            var nowX, nowY, R = Raphael("svg_drawing", 400, 400);

            $($("svg").get(0)).attr("xmlns:xlink", "http://www.w3.org/1999/xlink");
            var templ = R.image("images/band_clutch.jpg", 0, 0, 400, 400);

        });

        function toImg(){
            var svg = $("#svg_drawing").html().replace(/>\s+/g, ">").replace(/\s+</g, "<");
            var canvas = $("#canvas")[0];
            canvg(canvas, svg);
            var imgData = canvas.toDataURL('image/jpg');
            var img = new Image();
            $(img).load(function(){
                $("#drawing_area").html("");
                $(img).appendTo("#drawing_area");
            });
            img.src = imgData;
        }

    </script>
    <title>Sandbox</title>
</head>
<body style="margin: 0; width:3000px">
    <div id="svg_drawing" style="background-color:white;display:inline-block;height:400px;width:400px;border:1px solid black;"></div>

    <canvas id="canvas" style="display:inline-block;height:400px;width:400px;border:1px solid red;"></canvas>

    <div id="drawing_area" style="background-color:white;display:inline-block;height:400px;width:400px;border:1px solid black;"></div>
            <button onclick="toImg()" style="display:inline-block;vertical-align:top;">Do it</button>
</body>
</html>
1个回答

5
听起来画布区域仍保持默认的350 x 150。尝试设置:

canvas width="desired width" height="desired height"

canvas.width = canvas.height = 400;

在绘制之前(保留内联CSS)。

要解决实际渲染问题,您需要告诉canvg方法在渲染完成后异步执行toDataURI操作:

function toImg(){
        var svg = $("#svg_drawing").html().replace(/>\s+/g, ">").replace(/\s+</g, "<");
        var canvas = $("#canvas")[0];
        canvg(canvas, svg, {
            renderCallback : function(){
                var imgData = canvas.toDataURL('image/jpg');
                var img = new Image();
                $(img).load(function(){
                    $("#drawing_area").html("");
                    $(img).appendTo("#drawing_area");
                });
                img.src = imgData;
                }
            });           
     }

这只解决了尺寸不正确的问题,而且那也不是真正的问题。第二次运行代码(无需重新加载页面),它就是正确的尺寸,并显示图片。我的问题是第一次运行时(当我希望它能正常工作时),它给我一个空白图片,甚至没有SVG的缩放副本。 - sparrow
好的 - 已经将解决方案添加到答案中。基本上,您只需要等待canvg完成渲染,然后再进行其他操作。 - Graham
做到了,谢谢你。我一直在忙着看没有回调函数的canvg示例,以至于不知道它的存在。 - sparrow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接