benboba / svg-slim Goto Github PK
View Code? Open in Web Editor NEWA cool svg optimization tool that supports the svg standard
Home Page: https://benboba.github.io/svg-slim-web
License: MIT License
A cool svg optimization tool that supports the svg standard
Home Page: https://benboba.github.io/svg-slim-web
License: MIT License
解析和输出都需要更新
如题,结合其它配置项可以获得更优的结果
I've written a small CLI slimmer. As you can see, I'm not an advanced JS-coder, but perhaps it helps others.
node svgSlim.js pictogramm.svg > new.svg
<othertool> | node svgSlim.js > new.svg
<othertool> | node svgSlim.js /dev/stdin > new.svg
<othertool> | node svgSlim.js - > new.svg
cat pictogramm.svg | node svgSlim.js > new.svg
< pictogramm.svg node svgSlim.js > new.svg
'use strict';
function MergeRecursive(obj1, obj2) {
// based on https://stackoverflow.com/a/383245 - (c) users Markus etc. under CC BY-SA 3.0
for (let p in obj2) {
try {
// property in destination object set; update its value
if (obj2[p].constructor == Object) {
obj1[p] = MergeRecursive(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
} catch(e) {
// property in destination object not set; create it and set its value
obj1[p] = obj2[p];
}
}
return obj1;
}
const defaultConfig = {
"rules": {
"collapse-g": true,
"collapse-textwrap": true,
"combine-path": [ false, {
"disregardFill": false,
"disregardOpacity": false
}
],
"combine-transform": true,
"compute-path": true,
"rm-attribute": [ true, {
"keepAria": false,
"keepEvent": false
}
],
"rm-comments": true,
"rm-doctype": true,
"rm-hidden": true,
"rm-irregular-nesting": [ true, {
"ignore": []
}
],
"rm-irregular-tag": [ true, {
"ignore": []
}
],
"rm-px": true,
"rm-unnecessary": [ true, {
"tags": [
"desc",
"discard",
"foreignObject",
"video",
"audio",
"iframe",
"canvas",
"metadata",
"script",
"title",
"unknown",
"image"
]
}
],
"rm-version": true,
"rm-viewbox": true,
"rm-xml-decl": true,
"rm-xmlns": true,
"shorten-animate": [ true, {
"remove": false
}
],
"shorten-class": true,
"shorten-color": [ true, {
"rrggbbaa": false
}
],
"shorten-decimal-digits": true,
"shorten-defs": true,
"shorten-filter": true,
"shorten-id": true,
"shorten-shape": true,
"shorten-style-attr": true,
"shorten-style-tag": [ true, {
"deepShorten": true
}
],
},
"params": {
"sizeDigit": 2,
"angelDigit": 2,
"trifuncDigit": 3,
"opacityDigit": 3,
"thinning": 0,
"straighten": 0,
"mergePoint": 0,
"exchangeStyle": false,
"rmAttrEqDefault": true
},
"browsers": ["defaults"]
};
const userConfig = {
"params": {
"sizeDigit": 5,
"angelDigit": 5,
"trifuncDigit": 5
}
};
const fs = require('fs');
const svgSlimming = require('svg-slim');
const fileOrStdin = require('file-or-stdin');
const args = process.argv.slice(2);
async function main() {
const svgFN = (args[0] === '-') ? '/dev/stdin' : args[0];
try {
const svgcode = await fileOrStdin(svgFN, 'utf8');
try {
const config = MergeRecursive(defaultConfig, userConfig);
const result = await svgSlimming(svgcode, config)
console.log(result);
} catch(e) {
console.error('Error while slimming. ' + e);
}
} catch(e) {
console.error('File not found. ' + e);
}
return;
}
main();
When the style of the g element has only one child element that can be inherited, transfer the style to the child element
I've just created a config based on the current defaults (3e81e7a). This might help others with playing with the settings - at least it helped my.
{
"collapse-g": [ true ],
"collapse-textwrap": [ true ],
"combine-path": [ true, {
"disregardFill": false,
"disregardOpacity": false
}
],
"combine-transform": [ true, {
"angelDigit": 2,
"sizeDigit": 2,
"trifuncDigit": 3
}
],
"compute-path": [ true, {
"angelDigit": 2,
"sizeDigit": 2,
"straighten": 0,
"thinning": 0
}
],
"rm-attribute": [ true, {
"keepAria": false,
"keepEvent": false,
"rmDefault": true
}
],
"rm-comments": [ true ],
"rm-doctype": [ true ],
"rm-hidden": [ true ],
"rm-irregular-nesting": [ true, {
"ignore": []
}
],
"rm-irregular-tag": [ true, {
"ignore": []
}
],
"rm-px": [ true ],
"rm-unnecessary": [ true, {
"tags": [
"desc",
"discard",
"foreignObject",
"video",
"audio",
"iframe",
"canvas",
"metadata",
"script",
"title",
"unknown",
"image"
]
}
],
"rm-version": [ true ],
"rm-viewbox": [ true ],
"rm-xml-decl": [ true ],
"rm-xmlns": [ true ],
"shorten-animate": [ true, {
"remove": false
}
],
"shorten-class": [ true ],
"shorten-color": [ true, {
"opacityDigit": 3,
"rrggbbaa": false
}
],
"shorten-decimal-digits": [ true, {
"angelDigit": 2,
"sizeDigit": 2
}
],
"shorten-defs": [ true ],
"shorten-filter": [ true ],
"shorten-id": [ true ],
"shorten-shape": [ true, {
"thinning": 0
}
],
"shorten-style-attr": [ true, {
"exchange": false,
"rmDefault": true
}
],
"shorten-style-tag": [ true, {
"deepShorten": true,
"rmDefault": true
}
]
}
Is it possible to donate you and your development?
对 fill-rule="even-odd" 的路径合并,在 fill 不为 none 的时候可能会导致意外的镂空
例如:use、patten 的自我嵌套或循环嵌套
某些元素当 width 和 height 为负或为 0 时不可渲染等
需要根据 svg 规范进行改进
The collapse-textwrap rule cannot be merged when it encounters non-empty (not pure space) characters in the parent element
First of all, thanks for this nice tool. It's by far the best solution on the web. Good work.
I've got SVGs with lots of text nodes, which have the same styling. So, it's repeated over and over, which increases the size. Would it be possible to create classes to slim the file down even more? This would save many bytes.
<text style="font-family:Arial;font-size:13.31;font-stretch:Normal;font-weight:400;letter-spacing:0;word-spacing:0" dx="206.4" dy="285.43">70</text>
<text style="font-family:Arial;font-size:13.31;font-stretch:Normal;font-weight:400;letter-spacing:0;word-spacing:0" dx="206.4" dy="253.69">80</text>
<text style="font-family:Arial;font-size:13.31;font-stretch:Normal;font-weight:400;letter-spacing:0;word-spacing:0" dx="206.4" dy="221.95">90</text>
<text style="font-family:Arial;font-size:13.31;font-stretch:Normal;font-weight:400;letter-spacing:0;word-spacing:0" dx="198.7" dy="190.21">100</text>
<style type="text/css">
.textA { font-family: Arial; font-size: 13.31; font-stretch: Normal; font-weight: 400; letter-spacing: 0; word-spacing: 0 }
</style>
<text class="textA" dx="206.4" dy="285.43">70</text>
<text class="textA" dx="206.4" dy="253.69">80</text>
<text class="textA" dx="206.4" dy="221.95">90</text>
<text class="textA" dx="198.7" dy="190.21">100</text>
特定条件下 ellipsis 可以转 circle
Hi. Amazing project.
Is it better than svgo? Better API or compression?
In 454349f, some whitespace gets introduced within text-tag.
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="1000" height="150">
<text font-size="20px" x="500" y="100">
<tspan>fixme</tspan>
</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="1e3" height="150"><text font-size="20" x="5e2" y="1e2"> fixme </text></svg>
As discussed in #27, sometimes an SVG can contain nested TSPAN-elements. That's bad of course. But perhaps we can fix this. As you can see, the styled of the inner TSPAN gets lost. It contains fill: red
aka fill: #FF0000;
, which gets lost right now. Also, the x
and y
coordinates of the surrounding TSPAN gets lost (this is fine in this case since they're zero).
It should be discussed, what to do in such cases. I think the lower solution might be fine?
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="900" height="150">
<text x="500.298343" y="115.726494" style="fill:#00FF00;">
<tspan x="0.000" y="0.000">
<tspan style="fill:#FF0000;">fixme</tspan>
</tspan>
</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="9e2" height="150">
<text x="500.29834" y="115.72649" fill="#0f0">
<tspan>fixme</tspan>
</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="9e2" height="150">
<text x="500.29834" y="115.72649" fill="#0f0">
<tspan fill="red" x="0" y="0">fixme</tspan>
</text>
</svg>
特定条件下,可以直接应用 defs 到 ,以获得更优的效果
对于解析过的 stylesheet,可以统一将 selector 修改为短 class ,这样还可以避免由于属性调整和节点名称变化导致选择器失效的问题
I am looking for a tool to prepare SVGs for them to be used to create a fonticon
There are a few steps that needs to go down.
Here are the list https://github.com/fontello/fontello/wiki/How-to-use-custom-images#preparing-images-in-inkscape
I was wondering if those steps could be done with you plugin?
That would be awesome cause i could batch optimize!
Thanks
1、目前很多规则都依赖 style 元素解析,目前执行了很多次,并且每次都 try ... catch ,其实可以抽出来只解析一次
2、可以为 document 创建一个 Node 的子类型,增加 stylesheet 属性来缓存 css 规则
The style of each element should be analyzed in detail, rather than judging whether there is a style tag, so that it will no longer rely on the exchangeStyle configuration item
在元素较少时,考虑直接把 style 标签内的样式应用到元素
有些情况使用 viewBox 可以获得更好的优化效果,需要深入研究
While optimizing some SVGs with nodeJS I have encountered my several svg files giving style issues.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<style>.a{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;}</style>
</defs>
<title>3d-box-corner</title>
<line class="a" x1="12.03" y1="1.5" x2="12.03" y2="6"/>
<polygon class="a" points="12.03 6 4.03 9.5 12.03 13 20.03 9.5 12.03 6"/>
<polyline class="a" points="4.03 9.5 4.03 19 12.03 22.5 20.03 19 20.03 9.5"/>
<line class="a" x1="12.03" y1="13" x2="12.03" y2="22.5"/>
<line class="a" x1="1.03" y1="20.496" x2="4.03" y2="19"/>
<line class="a" x1="20.03" y1="19" x2="23" y2="20.482"/>
</svg>
If I tried to convert this SVG it converts this into :
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0,0,24,24"><path d="m12.03,1.5V6m0,0-8,3.5,8,3.5,8-3.5-8-3.5zm-8,3.5V19l8,3.5,8-3.5V9.5m-8,3.5v9.5m-11-2,3-1.5m16,0L23,20.48" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round"/></svg>
which is okay, it does the job, converting my <style> into attribute of a single path.
But when I tried to convert this one into a single path svg
<svg id="Light" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;}</style>
</defs>
<title>multiple-actions-lock</title>
<g id="_10_23" data-name="10*23">
<path class="cls-1" d="M7.5,23.5l.5-6h2.5V14a5,5,0,0,0-10,0v3.5H3l.5,6Z"/>
<circle class="cls-1" cx="5.5" cy="4" r="3.5"/>
</g>
<g id="_10_23_-_cut" data-name="10*23 - cut">
<g id="_Group_" data-name="<Group>">
<path class="cls-1" d="M17.439,10.37a5.006,5.006,0,0,0-5.561-.9"/>
<circle class="cls-1" cx="14" cy="4.5" r="3"/>
</g>
</g>
<rect class="cls-1" x="14.5" y="16.5" width="9" height="7" rx="1" ry="1"/>
<path class="cls-1" d="M19,19a1,1,0,1,0,1,1,1,1,0,0,0-1-1Z"/>
<path class="cls-1" d="M16.5,16.5V15a2.5,2.5,0,0,1,5,0v1.5"/>
</svg>
it gives this error instead of converting it.
\dist\index.js:10102
dom.styletag.childNodes[0].textContent = cssText;
^
TypeError: Cannot set properties of undefined (setting 'textContent')
at createXML (C:\Users\tidus\Projects\depauli-icons\node_modules\svg-slim\dist\index.js:10102:53)
at C:\Users\tidus\Projects\depauli-icons\node_modules\svg-slim\dist\index.js:10125:18
What I don't understand is they both have the same <style> tags but one of them is giving issue. I tried to change class name to like the first working example but still giving error.
超过 50k 的文件都会失败,svgo 支持处理 2mb 甚至更高
如题
当一个 id 被多处引用,但最后发现不存在时,实际上只有第一处引用被正确移除了
解析和输出都需要更新
Text in nested tspans gets removed when using defaults. I'm using v1.5.3
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="800" height="600" id="svg2020">
<text xml:space="preserve" style="font-size:24.000000px;font-style:normal;font-variant:normal;font-weight:700;font-stretch:Normal;line-height:125.000000%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:sans-serif;text-align:start;text-anchor:start;" transform="matrix(1.000000,-0.000000,0.000000,1.000000,200,200)" x="0.000000" y="0.000000" id="text2018">
<tspan x="0.000000" y="0.000000" id="tspan2016">
<tspan dx="0.000000" dy="0.000000" style="fill:#000000;font-size:24.000000px;font-style:normal;font-variant:normal;font-weight:700;font-stretch:Normal;font-family: sans-serif;" id="tspan2014">fixme</tspan>
</tspan>
</text>
</svg>
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="8e2" height="6e2">
<text style="font-size:24;font-weight:700;font-stretch:Normal;letter-spacing:0;word-spacing:0;font-family:sans-serif" dx="2e2" dy="2e2">
<tspan x="0" y="0"> </tspan>
</text>
</svg>
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="8e2" height="6e2">
<text style="font-size:24;font-weight:700;font-stretch:Normal;letter-spacing:0;word-spacing:0;font-family:sans-serif" dx="2e2" dy="2e2">fixme</text>
</svg>
Some browsers, like Internet Explorer 11, need a unit at font-size. Seems like config browsers: []
is perfect for this in the future.
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="1000" height="150">
<text font-size="20px" x="500" y="100">
<tspan>fixme</tspan>
</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="1e3" height="150"><text font-size="20" x="5e2" y="1e2"> fixme </text></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="1e3" height="150"><text font-size="20px" x="5e2" y="1e2">fixme</text></svg>
Before compression:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="7px" height="14px" viewBox="0 0 7 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>向左icon</title>
<g id="向左icon" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<polyline id="路径备份" stroke="currentColor" points="6 13 1 6.74135516 6 1"></polyline>
</g>
</svg>
After compression
<svg width="7" height="14" xmlns="http://www.w3.org/2000/svg"/>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.