Some time ago we covered the basics of SVG 1.1 in SVG: From Archaic XML to Coding Graphical Marvels, today we will take a step into the future and get familiar with what’s coming to SVG 2. In this article we will focus on a few new Painting concept features.
SVG1.1 has been in use for years now, the main public being the web development community, a community that embraces open-source and modularization like no other. It’s also a very vocal and active bunch that not only asks for new features and improvements, it’s always ready to provide concepts and solutions for the technologies that are exciting and empowering.
In the case of moving forward with SVG 2 the community was vocal, and the verdict was clear: SVG 1.1 was applauded for it’s great deeds and features, and the best features are to become modules shared with CSS. Essentially, SVG 1.1 plays the role of a martyr, and strangely enough it’s more in the favor of CSS than it is in the favor of its younger brother — SVG 2. This shift of priorities may sound like treason at first but there are reasons behind the fact that CSS is stealing the spotlight:
The downside is that SVG is no longer dominant when it comes to its own development course and can no longer make changes without them being approved somewhere else.
A complete list of SVG 1.1 to SVG 2 changes can be found here: https://www.w3.org/TR/SVG2/changes.html
Let’s check some of the more interesting new features for painting.
A very handy new feature is stacking multiple ‘fill’ and ‘stroke’ properties, this will save us from writing extra lines of code and will generally make our code cleaner, prettier and easier to maintain.
Let’s take a look at how we would stack three ‘fill’ properties using SVG 1.1, let’s say we want to apply some horizontal and vertical line patterns as well as a background color, as a basis we will use the X-team logo which is composed out of three ‘path’ objects, meaning we have to apply all three fills to all 3 objects, essentially placing three logos with different properties on top of each other, not a pretty solution:
<code class="html"><defs> <pattern id=”Hatch1" patternUnits=”userSpaceOnUse” patternTransform=”rotate(90)” width=”12" height=”300"> <path stroke=”red” stroke-width=”1" d=”M 1,0 1,300" /> </pattern> <pattern id=”Hatch2" patternTransform=”rotate(180)” xlink:href=”#Hatch1" /> </defs>
<g stroke=”red” stroke-width=”3" transform=”matrix(.650,0,0,.650,5,5)”> <! — SVG1.1 iMPLEMENTATION --> <! — APPLY COLOR FILL TO ALL 3 PATH OBJECTS --> <path fill=”tomato” d=”M 249.2436,153..."></path> <path fill=”tomato” d=”m 185.3175,236..."></path> <path fill=”tomato” d=”M 185.9194,243..."></path> <! — APPLY PREDEFINED FILL HATCH1 TO ALL 3 PATH OBJECTS --> <path fill=”url(#Hatch1)” d=”M 249.21..."></path> <path fill=”url(#Hatch1)” d=”m 185.34..."></path> <path fill=”url(#Hatch1)” d=”M 185.97..."></path> <! — APPLY PREDEFINED FILL HATCH2 TO ALL 3 PATH OBJECTS --> <path fill=”url(#Hatch2)” d=”M 249.26..."></path> <path fill=”url(#Hatch2)” d=”m 185.35..."></path> <path fill=”url(#Hatch2)” d=”M 185.96..."></path> </g>
And here is the SVG 2 equivalent:
<code class="html"><defs> <pattern id=”Hatch1" patternUnits=”userSpaceOnUse” patternTransform=”rotate(90)” width=”12" height=”300"> <path stroke=”red” stroke-width=”1" d=”M 1,0 1,300" /> </pattern> <pattern id=”Hatch2" patternTransform=”rotate(180)” xlink:href=”#Hatch1" /> </defs>
<g stroke=”red” stroke-width=”3" transform=”matrix(.650,0,0,.650,5,5)”> <!--SVG2 IMPLEMENTATION--> <!--STACK MULTIPLE FILL PROPERTIES SEPARATING THEM BY A COMMA--> <path fill="url(#Hatch1), url(#Hatch2), tomato" d="M 249.2436,153..."></path> <path fill="url(#Hatch1), url(#Hatch2), tomato" d="m 185.3175,236..."></path> <path fill="url(#Hatch1), url(#Hatch2), tomato" d="M 185.9194,243..."></path> </g>
Achieving the same result but with less effort and less extra code? Hell yeah!
Check out a fully-working code example here: X-team logo stacking fills
There were three line joins available in SVG 1.1, these were: “miter”, “round” and “bevel” joins, SVG 2 introduces two new joins: “arcs” and “miter-clip”.
“Arcs” creates an arc path for both segments that join together, the curvature of each outer edge is preserved.
“Miter-clip” is an extension to the original “miter”, the addition here is for the case when “stroke-miterlimit” is exceeded, the join curve is trimmed at a length equal to the “stroke-miterlimit” value multiplied by the stroke width.
<code class="html"><?xml version=”1.0" standalone=”no”?>
<svg xmlns=”http://www.w3.org/2000/svg" xmlns:xlink=”http://www.w3.org/1999/xlink" width=”800" height=”180" viewBox=”0 0 800 180">
<style type=”text/css”> <![CDATA[ .simple { stroke: black; stroke-width: 30px } .miterclip { stroke: black; stroke-width: 30px; stroke-miterlimit: 1.5;} ]]> </style>
<defs>
<path id=”path1" d=”m 25,130 c 0,-40 50,-75 100,-75 -35,20 -50,50 -50,75" fill=”none” />
</defs>
<g transform=”translate(0,0)”>
<use class=”simple” xlink:href=”#path1" stroke-linejoin=”miter”/>
</g>
<g transform=”translate(100,0)”>
<use class=”miterclip” xlink:href=”#path1" stroke-linejoin=”miter-clip”/>
</g>
<g transform=”translate(200,0)”>
<use class=”simple” xlink:href=”#path1" stroke-linejoin=”round”/>
</g>
<g transform=”translate(300,0)”>
<use class=”simple” xlink:href=”#path1" stroke-linejoin=”bevel”/>
</g>
<g transform=”translate(400,0)”>
<use class=”simple” xlink:href=”#path1" stroke-linejoin=”arcs”/>
</g>
</svg>
A new property is being introduced called “paint-order”, which dictates the order of paint operations. Paint consists of three operations: fill, stroke and markers, “paint-order” value sets one of these operations to be the first one executed, resulting in other operations being stacked on top of it. The implicit value for this property is “normal”.
Here is an example of SVG code taking advantage of “paint-order” for setting the stroke priority:
<code class="html"><text x=”100" y=”100" stroke-width=”5px” paint-order=”normal”>Red</text>
<text x=”300" y=”100" stroke-width=”5px” paint-order=”stroke”>Red</text>
<text x=”500" y=”100" stroke-width=”5px” paint-order=”fill”>Red</text>
Check out a fully-working code example here: Paint-order SVG2 vs SVG1.1
We reviewed some of the more exciting changes in SVG 2, unfortunately browser support is still mostly lacking, for instance, “paint-order” being the only one supported in Firefox and Chrome. At this point testing most of the completed SVG 2 features is only possible through a development branch of Inkscape — vector editor. Nevertheless, it’s great to see how SVG 2 is influencing and contributing to shaping a better web.