I created an <svg>
element with JavaScript, here are my codes:
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<svg id="stroke_carrot" fill="#000000" viewBox="0 0 50 50" width="0px" height="0px">
<path d="M30 13c-1-3-5-4-7-2h-1l1-11h-3l-1
9-4-7-3 1 5 8-8-4-1 2 9 5h-1c-2
2-3 5-2 7l2 2 5-3 1 2-5 3 8 9 5-3
2 2-5 3 12 14 3-2-8-25-5 3-1-2 5-3-3-8">
</path>
</svg>
<defs>
<pattern id="myPat" patternUnits="userSpaceOnUse" width="88" height="88" patternTransform="translate(0,0) rotate(0)">
<use width="44" height="44" xlink:href="#stroke_carrot" style="transform: translate3d(40px, 0px, 0px) rotate(80deg);"></use>
<use width="44" height="44" xlink:href="#stroke_carrot" style="transform: translate3d(60px, 0px, 0px) rotate(50deg);"></use>
</pattern>
</defs>
<rect x="0px" y="0px" width="300px" height="200px" fill="url(#myPat)"> </rect>
</svg>
The <svg>
looks like this on the webpage, you can run the codes to see it.
Then I save this <svg>
element as .svg
file, and open it in Adobe Illustrator to edit it. It becomes different, like this:
Apparently, the transform
attributes (position and rotation) do not work. Do you know how to make the transform work?
I want to save the <svg>
element to a same looking .svg
file that I can edit in Adobe Illustrator.
I tried to use x=
and y=
to set the position in the codes, then it works in the Illustrator. For the rotation I don't find a way to do. Also, since the other features of my site are not compatible with x
and y
(see this question), so I still hope I could be able to use transform
to achieve it.
CodePudding user response:
It does not work to set transform attribute/style for the <use>
element directly, but we can embedded the <use>
in the <svg>
and <g>
.
In this way we can also resize and recolor the referenced element (the <path>
in this case).
Now it can be displayed properly in the browser, as well as be saved as an .svg
file and opened for editing in Adobe Illustrator
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<svg fill="#000000" viewBox="0 0 50 50" width="0px" height="0px">
<path id="stroke_carrot" d="M30 13c-1-3-5-4-7-2h-1l1-11h-3l-1
9-4-7-3 1 5 8-8-4-1 2 9 5h-1c-2
2-3 5-2 7l2 2 5-3 1 2-5 3 8 9 5-3
2 2-5 3 12 14 3-2-8-25-5 3-1-2 5-3-3-8">
</path>
</svg>
<defs>
<pattern id="myPat" patternUnits="userSpaceOnUse" width="88" height="88" patternTransform="translate(0,0) rotate(0)">
<g transform = "rotate(80 45 25) translate(20 0)">
<svg width="50" height="50" viewBox="0 0 50 50" fill="orange">
<use xlink:href="#stroke_carrot"></use>
</svg>
</g>
<g transform = "rotate(50 65 25) translate(40 0)">
<svg width="50" height="50" viewBox="0 0 50 50" fill="blue">
<use xlink:href="#stroke_carrot"></use>
</svg>
</g>
</pattern>
</defs>
<rect x="0px" y="0px" width="300px" height="200px" fill="url(#myPat)"> </rect>
</svg>
Note:
- We need to wrap the
<svg>
in<g>
, and settransform
for<g>
, to make it work for Chrome. More details see: Transform is not applied on Embedded SVGs Chrome - Rotate: The
rotate(<a> [<x> <y>])
transform function specifies a rotation by a degrees about a given point. - Since I want the carrot rotates around its own center, I set the parameters for the
transform
attribute like this:transform = "rotate(degree width/2 x height/2 y) translate(x y)"
CodePudding user response:
You can apply transform
attributes directly to <use>
elements.
Besides, nested svgs usually cause a lot of troubles for vector graphic applications – so be careful!
Example – tested in AI cs6 (so quite old..) and inkscape
<svg width="300px" height="200px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="stroke_carrot"
d="M30 13c-1-3-5-4-7-2h-1l1-11h-3l-1
9-4-7-3 1 5 8-8-4-1 2 9 5h-1c-2
2-3 5-2 7l2 2 5-3 1 2-5 3 8 9 5-3
2 2-5 3 12 14 3-2-8-25-5 3-1-2 5-3-3-8">
</path>
<pattern id="myPat" patternUnits="userSpaceOnUse" width="88" height="88" >
<use fill="orange" href="#stroke_carrot" xlink:href="#stroke_carrot" transform="rotate(80 45 25) translate(20 0)" />
<use fill="blue" href="#stroke_carrot" xlink:href="#stroke_carrot" transform="rotate(50 65 25) translate(40 0)" />
</pattern>
</defs>
<rect x="0px" y="0px" width="300px" height="200px" fill="url(#myPat)"> </rect>
</svg>
Some common practices for standalone or editable svgs
- include namespace attributes like
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
for best compatibility – well done! - include legacy href syntax
xlink:href
for<use>
references. Although these are classified as deprecated – they are still needed by a lot of apps. You can also add the recommendedhref
.– also well done! - use more "conservative" styling/formatting methods and features:
A lot of applications only support a reduced set of svg features (or vaguely described as svg 1.0-1.1 compatibility – not by any means precise) - transformations: As recommended by @Robert Longson: svg transform attributes tend to be more reliable:
3d transformations liketranslate3d
might not be interpreted correctly.
Related properties liketransform-origin
ortransform-box
for specifying e.g. a pivot point for a rotation might also be ignored by some apps. A workaround can be to convert all transformations to a matrix. - avoid nested svgs – a lot of applications will struggle to calculate these nested viewBoxes or x/y offsets.
In your case you can easily define your carrot path within the<defs>
(or create a<symbol>
).