Search code examples
svg

How to use one svg path as viewport or as a boundary to another svg


I need to use the cup as the yellow liquid container

<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="74.816 9.773 216.518 267.963" width="216.518" height="267.963" xmlns="http://www.w3.org/2000/svg">
  <path id="cup" d="M 104.816 11.024 L 263.836 9.773 C 280.405 9.773 291.334 24.455 291.334 41.024 L 259.943 250.942 C 257.98 267.511 250.611 276.282 235.534 276.282 L 139.087 277.736 C 122.818 277.736 112.515 271.916 111.215 255.347 L 74.816 41.024 C 74.816 24.455 88.247 11.024 104.816 11.024 Z" stroke="rgb(222, 227, 240)" strokewidth="1" style="fill: rgb(173, 173, 173);" transform="matrix(1, 0, 0, 1, 0, -7.105427357601002e-15)"/>
  <path id="gentle-wave" d="M 86.759 115.641 C 105.042 107.431 75.76 124.011 111.277 98.943 C 146.794 73.875 163.342 76.758 186.793 78.455 C 210.244 80.152 243.25 87.673 259.122 101.068 C 274.994 114.463 273.667 112.514 281.515 116.703 L 256.016 272.501 L 114.383 268.251 L 86.759 115.641 Z" style="fill-rule: nonzero; fill: rgb(215, 218, 85);" transform="matrix(1, 0, 0, 1, 0, -7.105427357601002e-15)">
    <animate attributeName="d" values="M 54.885 151.764 C 73.168 143.554 75.76 124.011 111.277 98.943 C 146.794 73.875 163.342 76.758 186.793 78.455 C 210.244 80.152 243.25 87.673 259.122 101.068 C 274.994 114.463 319.353 147.575 327.201 151.764 L 327.201 275.688 L 54.885 275.688 L 54.885 151.764 Z; M 54.885 151.764 C 73.168 143.554 75.76 124.011 111.277 98.943 C 146.794 73.875 163.342 76.758 186.793 78.455 C 210.244 80.152 243.25 87.673 259.122 101.068 C 274.994 114.463 319.353 147.575 327.201 151.764 L 327.201 275.688 L 54.885 275.688 L 54.885 151.764 Z" begin="0.13s" dur="2s" fill="freeze" end="2.13s"/>
    <animateMotion path="M 0 -19.124 L 22.441 -81.809" calcMode="linear" begin="0s" dur="2s" fill="freeze"/>
  </path>
</svg>

This is the current result.

enter image description here

That's what I need.
The limit of the liquid needs to be the cup, even if the liquid is out.

enter image description here


Solution

  • You need to use the cup path twice therefore I moved it into the <defs> element, so that it isn't painted. First I use the cup path in a mask and second for painting it as the first element, using the <use> tag.

    The mask is used on a grouping element for the liquid.

    <svg viewBox="74.816 9.773 216.518 267.963" width="216.518" height="267.963" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <path id="cup" d="M 104.816 11.024 L 263.836 9.773 C 280.405 9.773 291.334 24.455 291.334 41.024 L 259.943 250.942 C 257.98 267.511 250.611 276.282 235.534 276.282 L 139.087 277.736 C 122.818 277.736 112.515 271.916 111.215 255.347 L 74.816 41.024 C 74.816 24.455 88.247 11.024 104.816 11.024 Z"  transform="matrix(1, 0, 0, 1, 0, -7.105427357601002e-15)"/>
        <mask id="mask01">
          <use href="#cup" stroke="black" strokewidth="1" fill="white"/>
        </mask>
      </defs>
      <use href="#cup" stroke="rgb(222, 227, 240)" strokewidth="1" fill="rgb(173, 173, 173)"/>
      <g mask="url(#mask01)">
        <path id="gentle-wave" d="M 86.759 115.641 C 105.042 107.431 75.76 124.011 111.277 98.943 C 146.794 73.875 163.342 76.758 186.793 78.455 C 210.244 80.152 243.25 87.673 259.122 101.068 C 274.994 114.463 273.667 112.514 281.515 116.703 L 256.016 272.501 L 114.383 268.251 L 86.759 115.641 Z" style="fill-rule: nonzero; fill: rgb(215, 218, 85);" transform="matrix(1, 0, 0, 1, 0, -7.105427357601002e-15)">
          <animate attributeName="d" values="M 54.885 151.764 C 73.168 143.554 75.76 124.011 111.277 98.943 C 146.794 73.875 163.342 76.758 186.793 78.455 C 210.244 80.152 243.25 87.673 259.122 101.068 C 274.994 114.463 319.353 147.575 327.201 151.764 L 327.201 275.688 L 54.885 275.688 L 54.885 151.764 Z; M 54.885 151.764 C 73.168 143.554 75.76 124.011 111.277 98.943 C 146.794 73.875 163.342 76.758 186.793 78.455 C 210.244 80.152 243.25 87.673 259.122 101.068 C 274.994 114.463 319.353 147.575 327.201 151.764 L 327.201 275.688 L 54.885 275.688 L 54.885 151.764 Z" begin="0.13s" dur="2s" fill="freeze" end="2.13s"/>
          <animateMotion path="M 0 -19.124 L 22.441 -81.809" calcMode="linear" begin="0s" dur="2s" fill="freeze"/>
        </path>
      </g>
    </svg>