-
Notifications
You must be signed in to change notification settings - Fork 0
/
simplify
executable file
·80 lines (75 loc) · 2.47 KB
/
simplify
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
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const yargs = require('yargs/yargs')
const { JSDOM } = require('jsdom')
const paper = require('paper')
const pluralize = require('pluralize')
const { SVGPathData } = require('svg-pathdata');
const main = async () => {
const args = (
yargs(process.argv.slice(2))
.command(
'* [files..]',
'This program uses paper.js to reduce the number of points in an SVG’s <path/>s.',
)
.option('tolerance', {
default: 10,
alias: 't',
})
.demandOption('files')
.alias('h', 'help')
.help()
.showHelpOnFail(true, 'HELP!')
)
const argv = await args.argv
paper.setup(new paper.Canvas(1000, 1000))
await Promise.all(
argv.files.map(async (file) => {
try {
const out = `${path.basename(file, '.svg')}.simplified.svg`
try {
await fs.promises.access(out, fs.F_OK)
console.error(`Destination ${out} Exists: Skipping`)
} catch(dne) {
const dom = (await JSDOM.fromFile(
file,
{ contentType: 'image/svg+xml' },
))
const { document: doc } = dom.window
const counts = await Promise.all(
Array.from(doc.querySelectorAll('path')).map(
(elem) => {
const data = elem.getAttribute('d')
const path = new paper.Path(
// paper.js path parsing sometimes fails
new SVGPathData(data).encode()
)
const preCount = path.segments.length
path.simplify(argv.tolerance)
const postCount = path.segments.length
elem.setAttribute(
'd', path.exportSVG().getAttribute('d')
)
console.info(
`Reduced ${preCount} ${pluralize('segment', preCount)}`
+ ` to ${postCount}`
+ ` (-${((preCount - postCount) * 100 / preCount).toFixed(2)}%)`
)
return { preCount, postCount }
}
)
)
console.info(`Writing processed SVG (tolerance: ${argv.tolerance}) to ${out}`)
await fs.promises.writeFile(out, await dom.serialize())
}
} catch(err) {
console.error(`Couldn’t Load: ${path.basename(file)}`)
console.error(` Error: ${err.message}`)
}
})
)
}
main()
.then(() => process.exit(0))
.catch((reason) => console.error(reason))