I want to nest a set of svg pentagons inside each other, to get a result like this:
I can do this by manually setting the translate and scale values relative to the outer svg.
<svg class="defs-only"
xmlns="http://www.w3.org/2000/svg"
style="display: none;">
<symbol id="pentagon">
<polygon
points="
190.2113,0
0,138.1966
72.6542,361.8034
307.7684,361.8034
380.4226,138.1966
"/>
</symbol>
</svg>
<svg id="1" style="fill:#666" viewBox="0 0 380 362" width="380" height="362">
<use xlink:href="#pentagon"/>
<svg id="2" style="fill:#777" viewBox="0 0 380 362" width="380" height="362">
<use xlink:href="#pentagon" transform="translate(72.5 138) scale(0.618 0.618)"/>
<svg id="3" style="fill:#888" viewBox="0 0 380 362" width="380" height="362">
<use xlink:href="#pentagon" transform="translate(118 225) scale(0.381924 0.381924)"/>
</svg>
</svg>
</svg>
Is there a way that I can use the same translate and scale values in each nested layer, and have those values relative to the immediate parent? Will this mean using a percentage value for translate, and is this possible?
Heres a jsFiddle.
Context: eventually, I want the user to be able to drag the shapes around, with each moving the same way relative to its parent, in order to be able to create images like this:
source
EDIT: Here's the final version of the game.
Yes. Like so:
<svg class="defs-only"
xmlns="http://www.w3.org/2000/svg"
style="display: none;">
<symbol id="pentagon">
<polygon
points="
190.2113,0
0,138.1966
72.6542,361.8034
307.7684,361.8034
380.4226,138.1966
"/>
</symbol>
</svg>
<svg viewBox="0 0 380 362" width="380" height="362">
<g id="pent2and3">
<use xlink:href="#pentagon" style="fill:#777"/>
<use xlink:href="#pentagon" style="fill:#888" transform="translate(72.5 138) scale(0.618 0.618)"/>
</g>
<g id="pent1">
<use xlink:href="#pentagon" style="fill:#666"/>
<use xlink:href="#pent2and3" transform="translate(72.5 138) scale(0.618 0.618)"/>
</g>
</svg>
Related
I understand that I could simply swap one image for another on hover, or I could move the position of a sprite as a background, but is there any way I can change the fill of the svg on hover in some other way?
I originally thought the below would work but have discovered it does not work if the SVG is used as the src of an html image tag.
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="17px" viewBox="0 0 24 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
#Page-1:hover #Shape{
fill: #00A49E !important;
}
</style>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Desktop" transform="translate(-454.000000, -1073.000000)" fill-rule="nonzero" fill="#9B9B9B">
<g id="email" transform="translate(454.000000, 1073.000000)">
<g id="Group">
<g id="Shape">
<path d="M22.2254762,0 C23.2055186,0 24,0.797143779 24,1.78716696 L24,15.212833 C24,16.1998581 23.2014771,17 22.2254762,17 L1.77452382,17 C0.794481378,17 0,16.2028562 0,15.212833 L0,1.78716696 C0,0.800141908 0.798522933,0 1.77452382,0 L22.2254762,0 Z M10.6054162,9.87197556 L2.12964982,3.11784921 C1.93425396,2.96214312 1.77777778,3.0378817 1.77777778,3.28512523 L1.77777778,14.7628523 C1.77777778,15.0060917 1.97746978,15.2105263 2.22380231,15.2105263 L21.7761977,15.2105263 C22.0198764,15.2105263 22.2222222,15.0100958 22.2222222,14.7628523 L22.2222222,3.28512523 C22.2222222,3.04188583 22.0646837,2.96298968 21.8703502,3.11784921 L13.3945838,9.87197556 C12.624058,10.4859884 11.3756236,10.4857346 10.6054162,9.87197556 Z M12.3507416,8.42142877 L20.3224534,2.06897091 C20.5152517,1.91533479 20.473415,1.78947368 20.2269738,1.78947368 L3.77302622,1.78947368 C3.52161302,1.78947368 3.48383733,1.91460885 3.67754658,2.06897091 L11.6492584,8.42142877 C11.8420567,8.57506489 12.1570324,8.57579083 12.3507416,8.42142877 Z"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
I want to center the rect shape with something equivalent to
transform="translate(50% - 100,0)" for example:
<svg width="100%" height="100%" viewbox="0 0 100% 100%">
<g transform="translate(50% - 100,0)">
<rect width="200" height="100" fill="rgb(0,0,255)" />
</g>
</svg>
I can't find the right syntax.
You can use an inner <svg> element to do the percentage part via its x attribute then the rest with the <g> element as you already have.
I'm not sure what you intend with the viewBox but percentage values are not valid there. Looks like you just don't need that at all.
<svg width="100%" height="100%">
<svg x="50%" overflow="visible">
<g transform="translate(-100,0)">
<rect width="200" height="100" fill="rgb(0,0,255)" />
</g>
</svg>
</svg>
I'm trying to create an header using a svg to generate a curved shape, like so
I copied the SVG code generate from Sketch, deleted some extra tags and fixed the image path
<svg viewBox="0 0 1440 638" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<path d="M-4.54747351e-13,163 L1440,163 L1440,700.10075 C1259.32216,751.363088 1140.10686,781.914324 1082.35411,791.754457 C776.214966,843.915606 628.837414,646.620792 362.433874,644.205808 C184.831514,642.595818 64.0202229,656.876199 6.73310296e-11,687.046952 L-4.54747351e-13,163 Z" id="path-1"></path>
</defs>
<g id="Header-Copy" transform="translate(0, -163.000000)">
<mask id="mask" fill="white"><use xlink:href="#path-1"></use></mask>
<use id="Rectangle-Copy-2" fill="#0BE17D" transform="translate(720.000000, 481.765165) scale(-1, 1) translate(-720.000000, -481.765165) " xlink:href="#path-1"></use>
<image style="mix-blend-mode: darken;" mask="url(#mask)" x="0" y="0" width="1462.5" height="975" xlink:href="~assets/header_bg.jpg"></image>
</g>
</svg>
But I end up with this
How can I make this work?
Remove the transform attribute from element <use id="Rectangle-Copy-2">.
<svg viewBox="0 0 1440 638" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path d="M-4.54747351e-13,163 L1440,163 L1440,700.10075 C1259.32216,751.363088 1140.10686,781.914324 1082.35411,791.754457 C776.214966,843.915606 628.837414,646.620792 362.433874,644.205808 C184.831514,642.595818 64.0202229,656.876199 6.73310296e-11,687.046952 L-4.54747351e-13,163 Z" id="path-1"></path>
</defs>
<g id="Header-Copy" transform="translate(0, -163.000000)">
<mask id="mask" fill="white"><use xlink:href="#path-1"></use></mask>
<use id="Rectangle-Copy-2" fill="#0BE17D" xlink:href="#path-1"></use>
<image style="mix-blend-mode: darken;" mask="url(#mask)" x="0" y="0" width="1462.5" height="975" xlink:href="~assets/header_bg.jpg"></image>
</g>
</svg>
I am trying to create an SVG sprite.
I have set the SVG image to be 100px wide, 50px height, then offset the second by 50.
How can I set the size of the actual icon? Currently, the icon is huge and not 50px.
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100px"
height="50px">
<defs>
<g id="arrow">
<path d="M378.135,227.256L206.224,55.354c-12.354-12.359-12.354-32.394,0-44.748c12.354-12.359,32.388-12.359,44.747,0
L445.258,204.89c6.177,6.18,9.262,14.271,9.262,22.366c0,8.098-3.091,16.195-9.262,22.372L250.971,443.91
c-12.359,12.365-32.394,12.365-44.747,0c-12.354-12.354-12.354-32.391,0-44.744L378.135,227.256z M9.265,399.166
c-12.354,12.354-12.354,32.391,0,44.744c12.354,12.365,32.382,12.365,44.748,0l194.287-194.281
c6.177-6.177,9.257-14.274,9.257-22.372c0-8.095-3.086-16.192-9.257-22.366L54.013,10.606c-12.365-12.359-32.394-12.359-44.748,0
c-12.354,12.354-12.354,32.388,0,44.748L181.18,227.256L9.265,399.166z"/>
</g>
</defs>
<use x="0" y="0" style="fill: #333" xlink:href="#arrow" />
<use x="50" y="0" style="fill: #999" xlink:href="#arrow" />
</svg>
This is what I see:
DO NOT USE TRANSFORM FOR SCALING
What you are missing is a defined viewBox.
If you do not define a viewBox the viewBox is the same size as the height and width that you defined.
So when you draw a path and some of its point are above 370 then they will be outside its container. Since your defined size is 100 width by 50 height. Any point with values higher then the size will not be drawn.
when you define a viewBox you can change the size without affecting what is drawn or not.
This is the article i allways use when i forget how to properly scale svgs: https://css-tricks.com/scale-svg/
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100px"
height="50px"
viewBox="0 0 500 500">
<defs>
<g id="arrow">
<path d="M378.135,227.256L206.224,55.354c-12.354-12.359-12.354-32.394,0-44.748c12.354-12.359,32.388-12.359,44.747,0
L445.258,204.89c6.177,6.18,9.262,14.271,9.262,22.366c0,8.098-3.091,16.195-9.262,22.372L250.971,443.91
c-12.359,12.365-32.394,12.365-44.747,0c-12.354-12.354-12.354-32.391,0-44.744L378.135,227.256z M9.265,399.166
c-12.354,12.354-12.354,32.391,0,44.744c12.354,12.365,32.382,12.365,44.748,0l194.287-194.281
c6.177-6.177,9.257-14.274,9.257-22.372c0-8.095-3.086-16.192-9.257-22.366L54.013,10.606c-12.365-12.359-32.394-12.359-44.748,0
c-12.354,12.354-12.354,32.388,0,44.748L181.18,227.256L9.265,399.166z"/>
</g>
</defs>
<use x="0" y="0" style="fill: #333" xlink:href="#arrow" />
<use x="50" y="0" style="fill: #999" xlink:href="#arrow" />
</svg>
Like this? I just added transform="scale(0.1)" attribute to the g tag to make it 10x smaller
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100px"
height="50px">
<defs>
<g id="arrow" transform="scale(0.1)">
<path d="M378.135,227.256L206.224,55.354c-12.354-12.359-12.354-32.394,0-44.748c12.354-12.359,32.388-12.359,44.747,0
L445.258,204.89c6.177,6.18,9.262,14.271,9.262,22.366c0,8.098-3.091,16.195-9.262,22.372L250.971,443.91
c-12.359,12.365-32.394,12.365-44.747,0c-12.354-12.354-12.354-32.391,0-44.744L378.135,227.256z M9.265,399.166
c-12.354,12.354-12.354,32.391,0,44.744c12.354,12.365,32.382,12.365,44.748,0l194.287-194.281
c6.177-6.177,9.257-14.274,9.257-22.372c0-8.095-3.086-16.192-9.257-22.366L54.013,10.606c-12.365-12.359-32.394-12.359-44.748,0
c-12.354,12.354-12.354,32.388,0,44.748L181.18,227.256L9.265,399.166z"/>
</g>
</defs>
<use x="0" y="0" style="fill: #333" xlink:href="#arrow" />
<use x="50" y="0" style="fill: #999" xlink:href="#arrow" />
</svg>
I'm trying to reuse an SVG sprite icone into new SVG object.
The new object is just a circle that contains the icon from the sprite.
I understand that I need to use the defs tag to group some shapes together,
But i have have a problem referencing my sprite icone inside the defs tag.
sprite:
<svg style="display:none;">
<symbol id="icon_1" viewBox="0 0 54 54">
<path d="M10.6 29.3h14.5V44H10.6z" class="st0"/>
<path d="M25 29.3h14.5V44H25zm-7.2-14.7h14.5v14.7H17.8zm0 0l3.9-4m10.6 4l3.9-4m-3.9 18l3.9-3.7m-25.6 4.4l4.3-4.4m24.6 4.7l3.9-4M39.5 44l3.9-4M21.2 10.6h15M14.5 24.9h3.3m17.7.6h7.9M36.2 10v15.5m7.2.1V40" class="st0"/>
</symbol >
new object:
<svg><defs>
<g id="shape">
<circle cx="40" cy="40" r="40" fill="rgba(124,240,10,0.5)" />
<image x="0" y="0" xlink:href="#icon_1"></image>
</g>
I read that i can use image tags to reference SVG elements.
obviously i'm doing something wrong.
Basically the expected result should be a stroked circle with the icon inside
in a way that I will be able to animate the entire object
Thanks
You were close. Your main problem was that you were careless with your opening and closing tags.
Your second SVG had a stray opening <defs> element, which meant that the <g id="shape"> element was left inside the <defs> section. <defs> is for defining elements to be re-used later, and anything in a <defs> will only be drawn when referenced from elsewhere.
There were a couple of other problems.
You can't use an <image> to reference a symbol. You will need to use a <use> for that.
You will need to supply a width and height so that the symbol gets draw at an appropriate size.
<svg width="0" height="0">
<defs>
<symbol id="icon_1" viewBox="0 0 54 54">
<path d="M10.6 29.3h14.5V44H10.6z" class="st0"/>
<path d="M25 29.3h14.5V44H25zm-7.2-14.7h14.5v14.7H17.8zm0 0l3.9-4m10.6 4l3.9-4m-3.9 18l3.9-3.7m-25.6 4.4l4.3-4.4m24.6 4.7l3.9-4M39.5 44l3.9-4M21.2 10.6h15M14.5 24.9h3.3m17.7.6h7.9M36.2 10v15.5m7.2.1V40" class="st0"/>
</symbol>
</defs>
</svg>
new object:
<svg>
<g id="shape">
<circle cx="40" cy="40" r="40" fill="rgba(124,240,10,0.5)" />
<use x="0" y="0" width="80" height="80" xlink:href="#icon_1"></use>
</g>
</svg>
The image tag is designed to be used with complete images, not fractions. I guess that use is the right tag for your use case.
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<symbol id="icon_1" viewBox="0 0 54 54">
<path d="M10.6 29.3h14.5V44H10.6z" class="st0"/>
<path d="M25 29.3h14.5V44H25zm-7.2-14.7h14.5v14.7H17.8zm0 0l3.9-4m10.6 4l3.9-4m-3.9 18l3.9-3.7m-25.6 4.4l4.3-4.4m24.6 4.7l3.9-4M39.5 44l3.9-4M21.2 10.6h15M14.5 24.9h3.3m17.7.6h7.9M36.2 10v15.5m7.2.1V40" class="st0"/>
</symbol>
<defs>
<g id="shape">
<circle cx="40" cy="40" r="40" fill="rgba(124,240,10,0.5)" />
<use x="2" y="-3" width="80" height="80" xlink:href="#icon_1"/>
</g>
</defs>
<use xlink:href="#shape"/>
</svg>
Also, if the sprite is in a separate file, you have to reference the symbol within that file: <use hlink:href="sprites.svg#icon1"/>.