-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
83 lines (63 loc) · 1.91 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const { createCanvas, loadImage } = require('@napi-rs/canvas');
const cheerio = require('cheerio');
const resolveUseTags = ($, $svg) => {
$svg.find('use').each((i, elem) => {
const $elem = $(elem);
const id = $elem.attr('href');
const $shape = $(id).clone();
$shape.removeAttr('id');
const $g = $('<g></g>');
const position = { x: 0, y: 0 };
for (let key in $elem.get(0).attribs) {
if (key === 'href') {
continue;
}
const value = $elem.attr(key);
if (key === 'x') {
position.x = value;
continue;
}
if (key === 'y') {
position.y = value;
continue;
}
$shape.attr(key, value);
}
$g.attr('transform', `translate(${position.x}, ${position.y})`);
$shape.wrap($g);
$elem.replaceWith($g);
});
};
module.exports = async ({ buffer, width, height } = {}) => {
if (!Buffer.isBuffer(buffer)) {
throw new Error('required "options.buffer" is missing');
}
const $ = cheerio.load(buffer.toString(), { xmlMode: true });
const $svg = $('svg').first();
if ($svg.length < 1) {
throw new Error('"options.buffer" is not a valid SVG image');
}
const { naturalWidth, naturalHeight } = await loadImage(Buffer.from($.xml($svg)));
let w, h;
if (width && !height) {
// scale both based on width
w = width;
h = width * naturalHeight / naturalWidth;
} else if (height && !width) {
// scale both based on width
h = height;
w = height * naturalWidth / naturalHeight;
} else {
// we either have both or neither
w = width || naturalWidth;
h = height || naturalHeight;
}
$svg.attr('width', `${w}`);
$svg.attr('height', `${h}`);
resolveUseTags($, $svg);
const image = await loadImage(Buffer.from($.xml($svg)));
const canvas = createCanvas(w, h);
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
return canvas.toBuffer('image/png');
};