Setting width and height as floats throws t.
Fufs opened this issue · 2 comments
Describe the bug
When adding the svg to the doc with width and height options (might also affect x and y) being a float, I get an error t.toFixed is not a function
. Works fine with ints or no options set.
What version are you using (exact version of svg2pdf.js and jspdf)?
- jspdf@2.5.1 (jspdf.umd.min.js)
- svg2pdf.js@2.2.1 (svg2pdf.umd.min.js)
To Reproduce
Code:
function splitDimension(dimension) {
return dimension.match(/-?\d+(\.\d*)?|[A-Za-z]+/g);
}
function convertUnitsFromValue(num, fromUnits, toUnits) {
let numInMM = NaN;
// Convert from fromUnits to mm
if(fromUnits == "mm") numInMM = num;
if(fromUnits == "cm") numInMM = num*10;
if(fromUnits == "Q") numInMM = num*0.25;
if(fromUnits == "in") numInMM = num*25.4;
if(fromUnits == "pc") numInMM = num*4.2333;
if(fromUnits == "pt") numInMM = num*0.3528;
if(fromUnits == "px") numInMM = num*0.2646;
// convert from mm to toUnits
if(toUnits == "mm") return numInMM;
if(toUnits == "cm") return numInMM/10;
if(toUnits == "Q") return numInMM/0.25;
if(toUnits == "in") return numInMM/25.4;
if(toUnits == "pc") return numInMM/4.2333;
if(toUnits == "pt") return numInMM/0.3528;
if(toUnits == "px") return numInMM/0.2646;
// Return NaN if an error occurs
return numInMM;
}
function convertUnitsFromDimension(dimension, toUnits) {
let dimArray = splitDimension(dimension);
return dimArray.length === 2 ? convertUnitsFromValue(dimArray[0], dimArray[1], toUnits) : NaN;
}
async function generatePDF(svg) {
const format = [parseFloat(convertUnitsFromDimension(svg.width.baseVal.valueAsString, "mm")).toFixed(2), parseFloat(convertUnitsFromDimension(svg.height.baseVal.valueAsString, "mm")).toFixed(2)]
const doc = new jspdf.jsPDF({unit: "mm", format: format, orientation: format[0] > format[1] ? "l" : "p"});
await doc.svg(svg, {x: 0, y: 0}); // Doesn't throw Error
// await doc.svg(svg, {x: 0, y: 0, width: format[0], height: format[1]}); // Throws Error
return await doc.output('datauristring');
}
SVG I was testing with:
<svg width="514.48mm" height="496.07mm" viewBox="0 0 183.08810424804688 176.53631591796875" version="1.1" id="svg305" xml:space="preserve" inkscape:version="1.2 (dc2aedaf03, 2022-05-15)" sodipodi:docname="vishroom_color.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g transform="matrix(-1,0,0,1,203.29302978515625,-7.15194845199585)">...</g>
</svg>
Log:
jspdf.js:494 Uncaught (in promise) TypeError: t.toFixed is not a function
at M.y.roundToPrecision.y.__private__.roundToPrecision (jspdf.js:494:19)
at M.y.hpf.y.__private__.hpf (jspdf.js:504:14)
at M.y.__private__.rect.y.rect (jspdf.js:4635:9)
at e.<anonymous> (svg.ts:47:10)
at tslib.es6.js:100:23
at Object.next (tslib.es6.js:81:53)
at tslib.es6.js:74:71
at new Promise (<anonymous>)
at s (tslib.es6.js:70:12)
at e.render (svg.ts:15:16)
M.y.roundToPrecision.y.__private__.roundToPrecision @ jspdf.js:494
M.y.hpf.y.__private__.hpf @ jspdf.js:504
M.y.__private__.rect.y.rect @ jspdf.js:4635
(anonimowa) @ svg.ts:47
(anonimowa) @ tslib.es6.js:100
(anonimowa) @ tslib.es6.js:81
(anonimowa) @ tslib.es6.js:74
s @ tslib.es6.js:70
e.render @ svg.ts:15
(anonimowa) @ svg2pdf.ts:47
(anonimowa) @ tslib.es6.js:100
(anonimowa) @ tslib.es6.js:81
s @ tslib.es6.js:71
Expected behavior
No error thrown.
Desktop (please complete the following information):
- OS: Windows 10 64-bit
- Browser: Chrome
- Version: 113.0.5672.127
That's because you are passing the number as a string (.toFixed()
returns a string) - pass it as a Number and it should work. The API will not automatically try to parse and convert strings into numbers. Ideally it would provide a clear error message. But typescript should have also warned you about this mistake.
Yup, that was exactly the issue. I haven't even realized that .toFixed()
returns a string. Just parsing it as a float works beautifully, thanks!