Forked from msand/svg-css-inliner-color-hexer-gradient-defs-grouper-number-formatter.js
Created
June 24, 2017 03:58
-
-
Save anhtuank7c/ed9df4714b455f6d1cbd0ecd93d2f97f to your computer and use it in GitHub Desktop.
Convert Illustrator SVG export into cross-platform CSS independent mode. CSS rule and style inlining, group gradients into a definitions tag, remove elements with display set to none, make colors hex. Works with react-native-web react-native-svg and svgs to give cross-platform web and native mobile rendering of any SVG produced in Illustrator.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Import https://raw.githubusercontent.com/MikeMcl/decimal.js/master/decimal.js first | |
Then run this. | |
Then put it into the SVG to JSX Online Converter http://svg-jsx.patmoody.com/ | |
Then find (e.g. using WebStorm) all occurences of the regexp </?. | |
Select all matches (the first letter of every react tag) and toggle case / replace with upper case (to use cross-platform react components from the svgs library) | |
Finally, wrap in a pure function and make sure to import all needed components: | |
import React from "react"; | |
import { | |
Circle, | |
ClipPath, | |
Defs, | |
Ellipse, | |
G, | |
Image, | |
Line, | |
LinearGradient, | |
Path, | |
Polygon, | |
Polyline, | |
RadialGradient, | |
Rect, | |
Stop, | |
Svg, | |
Symbol, | |
Text, | |
TextPath, | |
Use | |
} from "svgs"; | |
export default () => <Svg />; | |
*/ | |
(function() { | |
function rgb2hex(input) { | |
var rgb = input.match( | |
/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i | |
); | |
return rgb && rgb.length === 4 | |
? "#" + | |
("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + | |
("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + | |
("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) | |
: input; | |
} | |
/* Inline all rules from all CSS stylesheets as attributes on all matching elements and remove class attribute */ | |
let styles = Array.from(document.querySelectorAll("style")); | |
styles.forEach(styleSheet => { | |
Array.from(styleSheet.sheet.cssRules).forEach(rule => { | |
if (rule.style.display === "none") { | |
// Remove hidden elements | |
Array.from(document.querySelectorAll(rule.selectorText)).forEach(el => { | |
el.parentElement.removeChild(el); | |
}); | |
} else { | |
const styles = []; | |
for (let [key, value] of Object.entries(rule.style)) { | |
if (key !== "cssText" && value) { | |
/* Convert rgba? values to hex */ | |
styles.push([key, rgb2hex(value.replace(/"/g, ""))]); | |
} | |
} | |
Array.from(document.querySelectorAll(rule.selectorText)).forEach(el => { | |
styles.forEach(([key, value]) => { | |
el.setAttribute(key, value); | |
}); | |
}); | |
} | |
}); | |
}); | |
styles.forEach(styleSheet => { | |
Array.from(styleSheet.sheet.cssRules).forEach(rule => { | |
Array.from(document.querySelectorAll(rule.selectorText)).forEach(el => { | |
el.removeAttribute("class"); | |
}); | |
}); | |
styleSheet.parentElement.removeChild(styleSheet); | |
}); | |
/* Move inline CSS style values into element attributes */ | |
Array.from(document.querySelectorAll("[style]")).forEach(el => { | |
for (let [key, value] of Object.entries(el.style)) { | |
if (key !== "cssText" && value) { | |
el.setAttribute(key, rgb2hex(value)); | |
} | |
} | |
el.removeAttribute("style"); | |
}); | |
const gradients = Array.from( | |
document.querySelectorAll("linearGradient, radialGradient") | |
); | |
/* Move gradients inside of a defs tag, convert offsets from scientific notation to decimal notation */ | |
if (gradients.length) { | |
if (typeof Decimal !== "undefined") { | |
Array.from(document.querySelectorAll("stop")).forEach(el => { | |
const offset = el.getAttribute("offset"); | |
const newOffset = new Decimal(offset).toFixed(); | |
el.setAttribute("offset", newOffset); | |
}); | |
} | |
let def = document.createElement("defs"); | |
gradients.forEach(el => def.appendChild(el)); | |
let svg = document.querySelector("svg"); | |
svg.insertBefore(def, svg.firstChild); | |
svg.innerHTML = svg.innerHTML | |
.replace(/stopColor/g, "stop-color") | |
.replace(/stopOpacity/g, "stop-opacity"); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment