I have code I am running with PhantomJS, using FabricJS. It creates a HTML5 Canvas with elements, then creates an SVG
using that Canvas. This works well in all cases except when the Canvas uses a PNG
image. This issue does not exist if the Canvas is using an SVG
image. Instead of generating the correct SVG
output, it outputs an empty SVG
, like so.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="902" height="542" xml:space="preserve"><desc>Created with Fabric.js 1.5.0</desc><defs></defs></svg>
Expected is something along the lines of this
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="902" height="542" xml:space="preserve"><desc>Created with Fabric.js 1.5.0</desc><defs></defs><g transform="translate(451 271)">
<image xlink:href="http://test2.holmescp.com/media/pdp/images/filename1446564883.png" x="-451" y="-271" style="stroke: none; stroke-width: 1; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="902" height="542" preserveAspectRatio="none"></image></g></svg>
This is the most relevant parts of my code. I will post more if requested.
var pdc = PDC();
PDCExport = {
// Lots of functions removed here because of irrelevance to question
downloadSVG: function() {
var self = this,
canvasSvg = pdc.setCurrentCanvas(self.getActiveCanvas()).canvas.toSVG();
return canvasSvg;
}
}
// init function
PDCExport.init();
// Create SVG
console.log(PDCExport.downloadSVG());
If I paste that in Chrome Inspect Console, I get the empty SVG, but if I replace the last line with this.
setTimeout(function(){
console.log(PDCExport.downloadSVG());
}, 3000);
It outputs the full SVG, working in console, but still failing in PhantomJS.
I see from setTimeout in Phantom.js that setTimeout doesn't exactly work in PhantomJS, at leaste inside of page.evaluate, which I think is what I need here.phantomjs not waiting for "full" page load and Why PhantomJS render page use window.setTimeout seems to suggest PhantomJS should be able to handle setTimeout inside page.evaluate.
I've tried to use how we can use evaluateAsync in phantomjs but no success on a better result.
I have tried a separate evaluate as well, but seems that it doesn't retain memory of previous evaluation.
return setTimeout(function(){
return result = page.evaluate(function() {
return PDCExport.downloadSVG() + '|' + 'test';
});
}, 3000);
I have also attempted a manual setTimeout like so
var start_wait = new Date().getTime() / 1000;
var wait_time = 3;
var end_wait = start_wait + wait_time;
while (new Date().getTime() / 1000 < end_wait)
{
}
return PDCExport.downloadSVG() + '|' + 'test';
None of this has worked. I will give more of the code if required, but my question is essentially this.
How do I get PhantomJS to wait inside a page.evaluate
?