Search code examples
svgnestedscaletranslate

Nesting an svg symbol with scaling and translation relative to parent


I want to nest a set of svg pentagons inside each other, to get a result like this:

nested pentagons

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:

enter image description here

source


EDIT: Here's the final version of the game.


Solution

  • 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>