I have very little experience with SVG and I'm trying to save a path from illustrator so that it can be used as a responsive clipping mask whose size is relative to its parent, using clipPathUnits="objectBoundingBox".
However, Illustrator doesn't seem to allow me to have relative path values between 0 and 1 and only exports absolute values.
How could I get code like this...
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100">
<clippath id="clipping-mask">
<path d="M49.401,64H36.3V30.648h11.201c3.9,0,7.15,0.25,10.501,2.4c4.95,3.15,7.1,8.45,7.1,14.151
C65.102,56.75,59.352,64,49.401,64z M48.501,38.148h-3.7V56.5h3.65c5.7,0,8.15-3.65,8.15-9.051
C56.602,42.148,54.252,38.148,48.501,38.148z"/>
</clippath>
</svg>
... to be relative to its parent?
Thanks!
Taking a cue from Paul LeBeau's answer and from the answer at https://graphicdesign.stackexchange.com/a/42666 I figured out that you can actually set the art board in Illustrator to 1x1 and when saving to SVG increase the decimal places in the SVG Options on save. This will result in an SVG with the decimals already adjusted.
I don't think you can do that with Illustrator directly. And I don't know of any tool to do the conversion. However it is possible to do it manually with a little help from AI.
I would start by designing your clipping path on a page that is 100x100, and treat those coordinates as percentages. Then after exporting. Go throught the path definition adjusting all the coordinates by two decimal places.
Using your path as an example:
M .49401,.64
H .363
V .30648
h .11201
c .039, 0, .0715, .0025, .10501, .024
c .0495, .0315, .071, .0845, .071, .14151
C .65102, .5675, .59352, .64, .49401, .64
z
M .48501, .38148
h -.037
V .565
h .0365
c .057, 0, .0815 -.0365, .0815 -.09051
C .56602, .42148, .54252, .38148, .48501, .38148
z
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"
viewBox="0 0 100 100">
<path d="M49.401,64H36.3V30.648h11.201c3.9,0,7.15,0.25,10.501,2.4c4.95,3.15,7.1,8.45,7.1,14.151
C65.102,56.75,59.352,64,49.401,64z M48.501,38.148h-3.7V56.5h3.65c5.7,0,8.15-3.65,8.15-9.051
C56.602,42.148,54.252,38.148,48.501,38.148z"/>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"
viewBox="0 0 100 100">
<clipPath id="clipping-mask" clipPathUnits="objectBoundingBox">
<path d="M .49401,.64
H .363
V .30648
h .11201
c .039, 0, .0715, .0025, .10501, .024
c .0495, .0315, .071, .0845, .071, .14151
C .65102, .5675, .59352, .64, .49401, .64
z
M .48501, .38148
h -.037
V .565
h .0365
c .057, 0, .0815 -.0365, .0815 -.09051
C .56602, .42148, .54252, .38148, .48501, .38148
z"/>
</clipPath>
<rect width="100%" height="100%" fill="red" clip-path="url(#clipping-mask)"/>
</svg>
It's a bit tedious, I know, but if you have a lot of them to do you could probably write a script for it pretty easily.
Related
So I have this logo that fits the whole page. Is there anyway that, when the browser is resized I can move these paths? That way the height stays the same?
Example of what I want to achieve
Here's my svg code
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1440 52" style="enable-background:new 0 0 1440 52;" xml:space="preserve">
<path d="M1428.4,6.9c-2.5-2.5-6-3.7-10.5-3.7h-7.6h-9.5v19.1H16.3V3.1H7.8v46.8h8.5V30.7h1384.5v19.1h0h9.4V30.6h7.5
c2.3,0,4.3-0.3,6-1c1.8-0.7,3.3-1.7,4.5-2.9c1.2-1.2,2.2-2.7,2.8-4.5c0.7-1.7,1-3.6,1-5.8C1432.2,12.1,1430.9,9.4,1428.4,6.9z
M1421.4,20.1c-1,1-2.8,1.9-5.2,2h-6v-12h6c2.3,0,4,0.6,5.2,1.8s1.7,2.7,1.7,4.4C1423.1,18.5,1421.8,19.8,1421.4,20.1z" />
</svg>
you can do something like this by using preserveAspectRatio="none" for the svg element together with a fixed height and width:100%. This would give tou what you need but the the stroke would be scaled differently on the vertical and horizontal.
To fix it you need to add vector-effect="non-scaling-stroke" for the path.
svg{height:100px; width:100%}
<svg viewBox="0 0 100 20" preserveAspectRatio="none">
<path stroke="black" stroke-width="5" vector-effect="non-scaling-stroke" d="M 1,5V15M1,10H97"/>
</svg>
Yes it is possible, with a bit of trickery. Below is a modified verion of your SVG that behaves how you want.
This matches your SVG exactly, but has a limitation. The trick we are using relies on extending the middle bar a long way to the left. Then covering up the left end of the bar with your vertical piece. But in your original SVG the vertical piece is not right at the left end of your SVG. So I've had to hide some of the extension with a white rectangle. This assumes your background will also be white. If it isn't you'll need to change that white rectangle to be the same colour as your page background.
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="52">
<defs>
<path id="middle-and-right" transform="translate(-1440 0)"
d="M1428.4,6.9c-2.5-2.5-6-3.7-10.5-3.7h-7.6h-9.5v19.1
h -3000 v 8.4 h 3000
v19.1h0h9.4V30.6h7.5 c2.3,0,4.3-0.3,6-1c1.8-0.7,3.3-1.7,4.5-2.9c1.2-1.2,2.2-2.7,2.8-4.5c0.7-1.7,1-3.6,1-5.8C1432.2,12.1,1430.9,9.4,1428.4,6.9z
M1421.4,20.1c-1,1-2.8,1.9-5.2,2h-6v-12h6c2.3,0,4,0.6,5.2,1.8s1.7,2.7,1.7,4.4C1423.1,18.5,1421.8,19.8,1421.4,20.1z" />
</defs>
<use xlink:href="#middle-and-right" x="100%"/>
<rect x="-1" y="3.1" width="10" height="46.8" fill="white"/>
<rect x="7.8" y="3.1" width="8.5" height="46.8"/>
</svg>
If you want to get a better idea how the trick works, have a look at this version. I've modified the SVG to make the trick more apparent.
svg {
background-color: red;
overflow: visible;
}
rect {
opacity: 0.5;
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="52">
<defs>
<path id="middle-and-right" transform="translate(-1440 0)"
d="M1428.4,6.9c-2.5-2.5-6-3.7-10.5-3.7h-7.6h-9.5v19.1
h -3000 v 8.4 h 3000
v19.1h0h9.4V30.6h7.5 c2.3,0,4.3-0.3,6-1c1.8-0.7,3.3-1.7,4.5-2.9c1.2-1.2,2.2-2.7,2.8-4.5c0.7-1.7,1-3.6,1-5.8C1432.2,12.1,1430.9,9.4,1428.4,6.9z
M1421.4,20.1c-1,1-2.8,1.9-5.2,2h-6v-12h6c2.3,0,4,0.6,5.2,1.8s1.7,2.7,1.7,4.4C1423.1,18.5,1421.8,19.8,1421.4,20.1z" />
</defs>
<use xlink:href="#middle-and-right" x="100%"/>
<rect x="-1" y="3.1" width="10" height="46.8" fill="white"/>
<rect x="7.8" y="3.1" width="8.5" height="46.8"/>
</svg>
However if you don't mind the vertical piece on the left end being moved so it's hard up against the left side of the SVG, then we can remove that restriction regarding the background. The new version below will work for any page background colour.
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="52">
<defs>
<path id="middle-and-right" transform="translate(-1440 0)"
d="M1428.4,6.9c-2.5-2.5-6-3.7-10.5-3.7h-7.6h-9.5v19.1
h -3000 v 8.4 h 3000
v19.1h0h9.4V30.6h7.5 c2.3,0,4.3-0.3,6-1c1.8-0.7,3.3-1.7,4.5-2.9c1.2-1.2,2.2-2.7,2.8-4.5c0.7-1.7,1-3.6,1-5.8C1432.2,12.1,1430.9,9.4,1428.4,6.9z
M1421.4,20.1c-1,1-2.8,1.9-5.2,2h-6v-12h6c2.3,0,4,0.6,5.2,1.8s1.7,2.7,1.7,4.4C1423.1,18.5,1421.8,19.8,1421.4,20.1z" />
</defs>
<use xlink:href="#middle-and-right" x="100%"/>
<rect x="0" y="3.1" width="8.5" height="46.8"/>
</svg>
I have a svg image which has four paths which draw the perimeters of cuboid figures with curved corners.
I want to fill the interior of these figures. However, the fill="grey" property I am using on the path does not work.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 40" x="0px" y="0px" fill="grey">
<path fill="grey" d="M5,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H5A3,3,0,0,0,2,5v6A3,3,0,0,0,5,14ZM4,5A1,1,0,0,1,5,4h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H5a1,1,0,0,1-1-1Z"/>
<path d="M21,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3v6A3,3,0,0,0,21,14ZM20,5a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H21a1,1,0,0,1-1-1Z"/>
<path d="M2,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H5a3,3,0,0,0-3,3Zm2-6a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H5a1,1,0,0,1-1-1Z"/>
<path d="M18,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3Zm2-6a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H21a1,1,0,0,1-1-1Z"/>
</svg>
Any thoughts on what I need to do to fill in these cuboids?
Thanks
Your paths are filed grey. The problem is that there is a "hole" in in every path. I've removed the "hole
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 40" fill="grey">
<path d="M5,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H5A3,3,0,0,0,2,5v6A3,3,0,0,0,5,14Z"/>
<path d="M21,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3v6A3,3,0,0,0,21,14Z"/>
<path d="M2,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H5a3,3,0,0,0-3,3Z"/>
<path d="M18,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3Z"/>
</svg>
I have used the code verbatim from this post to dynamically create SVG paths from Lats & Lngs and for 80% of the time it's working very nicely but I have several polygons that are not rendering correctly in SVG
I have prepared an example in JSFiddle showing 1 that works & 1 that doesn't ...
<div style="padding:20px;">
<div>
Top SVG = NOT Working
<svg width="200" height="200" viewBox="227.131 154.886 0.007 0.006">
<path d="M227.125,154.881 227.125,154.881 227.131,154.881 227.132,154.881 227.132,154.882 227.132,154.886 227.132,154.886 227.131,154.886 227.131,154.886 227.129,154.884 227.126,154.881z"> </path>
</svg>
</div>
<div>
Bottom SVG = Working
<svg width="200" height="200" viewBox="227.136 154.905 0.009 0.014">
<path d="M227.145,154.907 227.140,154.905 227.141,154.910 227.138,154.914 227.136,154.919 227.141,154.919 227.145,154.919 227.145,154.916 227.145,154.912z M227.139,154.914 227.140,154.913 227.141,154.913 227.141,154.913 227.141,154.914 227.140,154.914 227.139,154.914z"> </path>
</svg>
</div>
</div>
I'd appreciate it if someone could point out my issue.
ALSO - I would like to know how and where to include a stroke color & width in this html. Thanks!!
I think there are a couple of problems with the first SVG:
The viewBox is incorrect. It doesn't match the shape. It should be more like:
viewBox="227.125 154.881 0.007 0.005"
The first two values (minX and minY) were wrong. How did this happen? I don't know. The code in that question looks alright at first glance, but I haven't attempted to debug it.
Secondly, I think there is likely a floating point issue. There are five orders of magnitude difference between the x and y offset of the shape, and its size. It seems you may be striking some floating point rounding issues, or something like that.
If you reduce the x and y coordinates, the shape renders correctly.
<div style="padding:20px;">
<div>
Top SVG = NOT Working
<svg width="200" height="200" viewBox="7.125 4.881 0.007 0.005">
<path d="M7.125,4.881 7.125,4.881 7.131,4.881 7.132,4.881 7.132,4.882 7.132,4.886 7.132,4.886 7.131,4.886 7.131,4.886 7.129,4.884 7.126,4.881z"
stroke="red" stroke-width=".0002"/>
</svg>
</div>
<div>
Bottom SVG = Working
<svg width="200" height="200" viewBox="227.136 154.905 0.009 0.014">
<path d="M227.145,154.907 227.140,154.905 227.141,154.910 227.138,154.914 227.136,154.919 227.141,154.919 227.145,154.919 227.145,154.916 227.145,154.912z M227.139,154.914 227.140,154.913 227.141,154.913 227.141,154.913 227.141,154.914 227.140,154.914 227.139,154.914z"> </path>
</svg>
</div>
</div>
To avoid this problem with other shapes, you could modify the code to subtract the minX and minY value from all the coordinates. After you fix issue #1, though, of course!
The first SVG is located outside the drawing area/viewBox, however You can add the stroke inside the <g> tag that wraps the graphic, as in the second SVG theres two shapes and I added stroke to one only.
Check this code:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<g stroke-width="3" stroke="#00CF00">
<polygon points="15,81 113,9 170,172 52,189 "/>
</g>
</svg>
<br />
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<circle cx="96.3" cy="93" r="62.3"/>
<g stroke-width="3" stroke="#FFFFFF">
<polygon style="fill:#00CF00;" points="71.7,56 144,92 71.7,128.3 "/></g>
</svg>
My SVG is width="1200" height="600" viewBox="0 0 1200 600". It uses a clipPath from defs of another SVG.
<svg class="svg-def">
<defs>
<clipPath id="clip-1"> ...
</defs>
</svg>
<svg width="1200" height="600" viewBox="0 0 1200 600">
<g clip-path="url(#clip-1)">
...
</g>
</svg>
Demo
When .svg-def does not have width="1200" height="600" viewBox="0 0 1200 600" (the first image), on window width narrower than 1200, the right side is clipped. This is not desired.
I want the second image -- the clip is just the size of the SVG. The second image is good because the <clipPath> being used is from an <svg> element with the same width="1200" height="600" viewBox="0 0 1200 600"
<svg class="svg-def">
<defs>
<clipPath id="clip-1"> ...
</defs>
</svg>
<svg class="svg-def" width="1200" height="600" viewBox="0 0 1200 600">
<defs>
<clipPath id="clip-2"> ...
</defs>
</svg>
Questions
1) In <clipPath> <rect width="100%" height="100%"/>, what is 100% relative to?
2) The first clip's display width varies with window width (when the latter is narrow than 1200px). Narrower window width = narrower display width. What is the display width relative to?
3) So if I have an SVG which has only <defs>, its <svg> tag still has to have viewbox values, so that the other SVG which uses the definitions (and which scales with window width) can have definitions in correct sizes?
I am trying to rotate a SVG on a T-Shirt designer project but edges of the SVG are getting cut off. The code for the SVG is as follows:
Before Rotation (Everything is correct in this)
<g xmlns="http://www.w3.org/2000/svg" transform="scale(2,2)rotate(0,50,50)" id="clip1">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" xmlns:xml="http://www.w3.org/XML/1998/namespace" enable-background="new 0 0 100 100" viewBox="0 0 100 100" height="100px" width="100px" y="0px" x="0px" id="Layer_1" version="1.1">
<g>
[POLYGON CODE WAS HERE]
</svg>
</g>
After Rotation (One of the edges is getting cut off!!!)
<g xmlns="http://www.w3.org/2000/svg" transform="scale(2,2)rotate(45,50,50)" id="clip1">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" xmlns:xml="http://www.w3.org/XML/1998/namespace" enable-background="new 0 0 100 100" viewBox="0 0 100 100" height="100px" width="100px" y="0px" x="0px" id="Layer_1" version="1.1">
<g>
[POLYGON CODE WAS HERE]
</svg>
</g>
Everything in the above 2 codes is the same except for the rotate(...) function.
The screenshot of what is going wrong can be found here - http://i.imgur.com/Kr5Azx3.png. In the right side image, the elbow is cut off as well as the background behind that. The SVG file code is present here - http://pastebin.com/LfC7TkwV
Is this the default behavior of SVG rotation or am I missing some other tag to make this work? Any help will be really appreciated.
Thanks.
As Erik says, the rotate operation is causing part of the design to fall outside the viewport. You may have to add a small translate() to your transform, and/or enlarge the size of your viewBox so that it encompasses the new larger bounding box.