svgdotjs / svgdom

Straightforward DOM implementation to make SVG.js run headless on Node.js
MIT License
269 stars 53 forks source link

How to set output viewbox width and height? #83

Closed diogodomanski closed 2 years ago

diogodomanski commented 2 years ago

Hi,

I've been playing with svg.js v3 and svgdom and I got stucked while trying to create a "simple" code. What I am trying to do is to import a SVG content from an input file and then create a new file with the exact same content.

import { createSVGWindow } from 'svgdom';
import { SVG, registerWindow } from "@svgdotjs/svg.js";
import * as fs from 'fs';

const window = createSVGWindow();
const document = window.document;
registerWindow(window, document);

const canvas = SVG(document.documentElement);
canvas.svg(fs.readFileSync('./input.svg').toString());
fs.writeFileSync('./output.svg', canvas.svg());

The above code is creating a copy of "input.svg" into "output.svg", however the original dimensions (1000x1000) are not being preserved.

How could I set output viewbox width and height as the same values from input content?

Thanks

Fuzzyma commented 2 years ago

Please also post the simplified input and output to help tracking down the issue

diogodomanski commented 2 years ago

I realized that the issue was being caused by the extra <svg> (called "parser") that SVG v3 adds, to calculate path data, bounding boxes for invisible elements and so on (https://svgjs.dev/docs/3.0/faq/).

What I had to do was to copy width and height values from the first child element (the input SVG content) to that outter svg container - making both dimensions the same.

The updated code follows:

import { createSVGWindow } from 'svgdom';
import { SVG, registerWindow } from "@svgdotjs/svg.js";
import * as fs from 'fs';

const window = createSVGWindow();
const document = window.document;
registerWindow(window, document);

const canvas = SVG(document.documentElement);
canvas.svg(fs.readFileSync('./input.svg').toString());

const inputWidth = canvas.children()[0].attr('width');
const inputHeight = canvas.children()[0].attr('height');
canvas.attr('width', inputWidth);
canvas.attr('height',inputHeight);

fs.writeFileSync('./output.svg', canvas.svg());

I don't know if this is the best approach, but it solved the problem.

Thanks for ready response

Fuzzyma commented 2 years ago

I dont think this is what you want. canvas is already an SVG document. Now you are importing another svg into the SVG. Then you export the outer svg into a file. So you end up with <svg...>your imported file</svg>. Your imported file however is an svg on its own so you probably want to export that instead.

So canvas.findOne('svg').svg() is probably what you want. In this case the width and height should be already set correctly

diogodomanski commented 2 years ago

@Fuzzyma your suggestions helped me a lot. Thanks