I’ve got some code which takes a drawing made on in SVG with Raphael (a 400×400 image loaded into the SVG with Raphael), converts it to a canvas with canvg, and should then take canvas.toDataURL and make it an image. All of this should happen when a button is pushed. The first two steps work, but the third is glitchy. The first time I press the button, a 300×150 blank image is placed in the final div instead of the 400×400 image. If I press the button again, the image shows up fine (correct size and everything). I’ve tried to use both img.onload and the jquery version $(img).load but neither seems to keep the problem from happening. Therefore, I feel like it’s an issue with the canvas having not been drawn completely yet but I can’t prove that and I can’t seem to make the code wait until it has been drawn. Below is all the code. I tried to make it a fiddle but I kept getting security errors with the image.
<!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>
It sounds like the canvas area is staying at the default 350 x 150. Try setting
before drawing (keep the inline CSS as-is).
To fix the actual rendering issue, you need to tell the canvg method to do the toDataURI stuff asyncronously, once the rendering has been complete: