Skip to content

Commit 7fea500

Browse files
authored
Merge pull request #12 from catdad-experiments/render-without-viewbox
support rendering SVGs that don't use `viewBox`
2 parents 00f3c8e + 5a32590 commit 7fea500

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ jobs:
1414
runs-on: ${{ matrix.os }}
1515
strategy:
1616
matrix:
17-
node: [16, 18, 20]
17+
node: [18, 20, 22]
1818
os: [ubuntu-latest, windows-latest, macOS-latest]
1919
# these are only excluded so we don't run so many jobs
2020
# they are more expensive and less likely to be a problem if the rest pass
2121
exclude:
2222
- os: macOS-latest
23-
node: 16
24-
- os: windows-latest
2523
node: 18
26-
- os: macOS-latest
24+
- os: windows-latest
2725
node: 20
26+
- os: macOS-latest
27+
node: 22
2828
steps:
2929
- uses: actions/checkout@v2
3030
- name: Use Node.js ${{ matrix.node }}

index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ const resolveUseTags = ($, $svg) => {
3838
});
3939
};
4040

41+
const resolveViewBox = ($, $svg) => {
42+
const viewBox = $svg.attr('viewBox');
43+
44+
if (viewBox) {
45+
return;
46+
}
47+
48+
const width = $svg.attr('width');
49+
const height = $svg.attr('height');
50+
51+
$svg.attr('viewBox', `0 0 ${width} ${height}`);
52+
};
53+
4154
module.exports = async ({ buffer, width, height } = {}) => {
4255
if (!Buffer.isBuffer(buffer)) {
4356
throw new Error('required "options.buffer" is missing');
@@ -50,6 +63,9 @@ module.exports = async ({ buffer, width, height } = {}) => {
5063
throw new Error('"options.buffer" is not a valid SVG image');
5164
}
5265

66+
resolveViewBox($, $svg);
67+
resolveUseTags($, $svg);
68+
5369
const { naturalWidth, naturalHeight } = await loadImage(Buffer.from($.xml($svg)));
5470

5571
let w, h;
@@ -71,7 +87,6 @@ module.exports = async ({ buffer, width, height } = {}) => {
7187
$svg.attr('width', `${w}`);
7288
$svg.attr('height', `${h}`);
7389

74-
resolveUseTags($, $svg);
7590

7691
const image = await loadImage(Buffer.from($.xml($svg)));
7792
const canvas = createCanvas(w, h);

test/index.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ describe('module', () => {
6262
await validateImage({ png, width: 50, height: 50, hash: 'c7343wq04L3' });
6363
});
6464

65+
it('renders images without a viewbox', async () => {
66+
const input = `
67+
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg">
68+
<circle cx="25" cy="25" r="25" fill="red"/>
69+
<rect width="20" height="20" x="0" fill="cyan" />
70+
<rect width="20" height="20" x="20" fill="magenta" />
71+
<rect width="20" height="20" x="40" fill="yellow" />
72+
<rect width="20" height="20" x="60" fill="black" />
73+
<rect width="20" height="20" x="80" fill="gray" />
74+
</svg>`;
75+
const png = await render({ buffer: Buffer.from(input), width: 200 });
76+
77+
await validateImage({ png, width: 200, height: 100, hash: 'ef0003y01x0' });
78+
});
79+
6580
it('errors if the input is not an SVG image', async () => {
6681
let error;
6782

0 commit comments

Comments
 (0)