Search code examples
svg

When nesting SVGs, how can I reference a parent element from within the child SVG?


When nesting SVGs, how can I reference a parent element from within the child SVG?

Below I have nested an SVG (the yellow rect and circle) within another SVG (the blue rect). I want the entire inner SVG to animate along the path on the parent SVG (id="motionPath" the red path). Is it possible to use href within the child to reference the motion path on the parent?

<svg id="parent" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
  <rect x="0" y="0" width="200" height="200" fill="#87CEEB" />
  
  <!-- Animation path -->
  <path d="M20,50 C20,-50 180,150 180,50 C180,-50,20,150 20,50 z" id="motionPath" fill="none"  stroke="red" />
  
  <!-- Nested SVG to animate -->
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="50" height="50" x="10" y="10">

    <!-- Reference doesn't work -->
    <animateMotion dur="10" repeatCount="indefinite" >
    <mpath href="#parent #motionPath" />
    </animateMotion>
 
    <rect x="0" y="0" width="200" height="200" fill="#FCC25A" />
    <circle r="30" cx="50" cy="50" fill="#000"/>
  </svg>
</svg>


Solution

  • As I've commented: You can put the nested svg in a <defs> and animate an <use> element of the nested svg.

    Alternatively you can transform the nested svg in a <symbol>.

    <svg id="parent" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
      <rect x="0" y="0" width="200" height="200" fill="#87CEEB" />
      
      <!-- Animation path -->
      <path d="M20,50 C20,-50 180,150 180,50 C180,-50,20,150 20,50 z" id="motionPath" fill="none"  stroke="red" />
      <defs>
      <!-- Nested SVG to animate -->
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="50" height="50" x="10" y="10" id="nested_svg">
        <rect x="0" y="0" width="200" height="200" fill="#FCC25A" />
        <circle r="30" cx="50" cy="50" fill="#000"/>
      </svg>
      </defs>
      <use href="#nested_svg">
       <!-- Reference doesn't work -->
        <animateMotion dur="10" repeatCount="indefinite" >
        <mpath href="#motionPath" />
        </animateMotion>
      </use>
    </svg>