This toolbox aims to simplify, unify and reduce gas costs for the onchain SVG images.
Instead of writing many times and in many contracts all the SVG code, use instead:
// produces a red rectangle in a complete svg format
return abi.encodedPacked(
svgContract.startSvg(0, 0, 155, 100),
//fills #i1 in red:
svgContract.styleColor("#i1", hex"ff0000ff"),
// rectangle id=i1 class=c1 ending tag/ starts at 0,0 to 10,10:
svgContract.rect(hex"01010100000a0a"),
svgContract.endSvg()
);
//Output (re-indented):
<svg viewBox='0 0 155 100' xmlns='http://www.w3.org/2000/svg'>
<style>
#i1{
fill: rgba(255,0,0,255);
}
</style>
<rect id='i1' class='c1' x='0' y='0' width='10' height='10' />
</svg>
As you can see, most of the parameters are encoded, so the gas cost for the storage is limited.
The most impressive data reduction is visible in <path
data, which draws advanced shapes example here produces this
function startSvg(uint _x, uint _y, uint _length, uint _width) external view returns (bytes memory);
function endSvg() external view returns (bytes memory);
function styleColor(bytes memory _element, bytes memory _b ) external view returns (bytes memory);
function ellipse(bytes memory _b) external view returns (bytes memory);
function path(bytes memory _b, string memory _path) external view returns (bytes memory);
function circle(bytes memory _b) external view returns (bytes memory);
function polyline(bytes memory _b) external view returns (bytes memory);
function rect(bytes memory _b) external view returns (bytes memory);
function polygon(bytes memory _b) external view returns (bytes memory);
function path(bytes memory _b) external view returns (bytes memory);
function use(bytes memory _b) external view returns (bytes memory);
function linearGradient(bytes memory _b) external pure returns (bytes memory);
All the parameters are unified for the shapes, let's see polygon
for example:
Pos | Ex. Value | Meaning | Note |
---|---|---|---|
0 | fa | id="i250" | 00 for no id |
1 | fe | class="c254" | |
2 | 01 | ending '/>' | if 0 ends with '>', you must close the tag |
3,4 | 404e | 1st point x,y | |
5,6 | 4000 | 2nd point x,y | |
7,8 | 006a | 3rd point x,y | |
m,n... | nth point x,y |
tokenURItoSVG.py displays metadata, svg and formatted xml when debbuging in Brownie. Example:
>>> testContract.tokenURI(0)
'data:application/json;base64,eyJuYW1[...]QZz09In0='
>>> from tokenURItoSVG import tokenURItoSVG
>>> tokenURItoSVG(testContract.tokenURI(0), outfile=True)
### Metadata ###
name: Sundowner
### Raw image ###
b"<svg viewBox=[...]"
### Pretty xml ###
<?xml version="1.0" ?>
<svg xmlns=[...]
svgpath2hex.py tries to round a path data
and codes it in a bytes string readable by path
Deployed here
My first Prototype
Exemple of NFT using this tollbox here and on OpenSea (Right click on the image, then open in a new tab to have an animation on hover)