search

Home  >  Q&A  >  body text

How can I fill the bottle with color using clipPath

I have an image of a bottle and try to fill this bottle with a certain color

I found the fill coordinates but the background inside the bottle is not filled

.item {
  width: 150px;
  height: 150px;
}

#tubeLiquid {
  background-color: #74ccf4;
  clip-path: polygon(45% 19%, 41% 22%, 41% 29%, 41% 36%, 41% 43%, 41% 50%, 41% 57%, 41% 63%, 41% 70%, 41% 77%, 41% 83%, 41% 90%, 43% 93%, 50% 92%, 56% 93%, 60% 88%, 59% 81%, 60% 75%, 60% 68%, 60% 61%, 59% 55%, 59% 48%, 59% 42%, 59% 35%, 59% 29%, 58% 23%, 54% 19%);
}

#bottleMask{
  background-color: #FFFFFF;
  clip-path: polygon(45% 19%, 41% 22%, 41% 29%, 41% 36%, 41% 43%, 41% 50%, 41% 57%, 41% 63%, 41% 70%, 41% 77%, 41% 83%, 41% 90%, 43% 93%, 50% 92%, 56% 93%, 60% 88%, 59% 81%, 60% 75%, 60% 68%, 60% 61%, 59% 55%, 59% 48%, 59% 42%, 59% 35%, 59% 29%, 58% 23%, 54% 19%);
}
<div class="item">
  <svg viewBox="0 0 300 300">
    <image
      width="300"
      clip-path="url(#bottleMask)"
      xlink:href="https://i.ibb.co/Mhfwtxp/image-removebg-preview-1.png"
    ></image>
    <defs>
      <mask id="bottleMask"></mask>
    </defs>
    <g id="maskedLiquid" mask="url(#bottleMask)">
      <path id="tubeLiquid" fill="#74ccf4"></path>
    </g>
  </svg>
</div>

P粉690200856P粉690200856474 days ago555

reply all(2)I'll reply

  • P粉343141633

    P粉3431416332023-09-10 14:35:30

    You don't need the extra .
    Due to the shape of the bottle, you can use the circle as the clipping path:

    waterLevel.addEventListener('input', e => {
      let value = +e.currentTarget.value
      tubeLiquid.setAttribute('stroke-dasharray', `${value} 100`)
    })
    svg {
      width: 20%;
    }
    <h3>Draw clip-path</h3>
    <svg viewBox="0 0 300 300">
        <image width="300" href="https://i.ibb.co/Mhfwtxp/image-removebg-preview-1.png" />
        <!-- test clip path -->
        <rect x="115" y="55" width="69" height="235" rx="20" ry="20" fill="red" />
      </svg>
    
    <h3>Draw liquid fill</h3>
    <svg viewBox="0 0 300 300">
        <image width="300" href="https://i.ibb.co/Mhfwtxp/image-removebg-preview-1.png" />
        <line x1="149.5" y1="290" x2="149.5" y2="50" stroke="green" stroke-width="70" />
      </svg>
    
    <h3>Apply clip path</h3>
    <p><input type="range" min="0" max="100" value="100" id="waterLevel" name="water-level" /></p>
    <svg viewBox="0 0 300 300">
        <clipPath id="clip">
              <rect x="115" y="55" width="69" height="235" rx="20" ry="20" fill="red" />
        </clipPath>
        <image width="300" href="https://i.ibb.co/Mhfwtxp/image-removebg-preview-1.png" />
        <line id="tubeLiquid" clip-path="url(#clip)" pathLength="100" stroke-dasharray="100 100" x1="149.5" y1="290" x2="149.5" y2="50" stroke="#74ccf4" stroke-width="80" />
      </svg>

    First draw the clipping path and fill scale/progress bar shape - without clipping anything - to find the correct coordinates and dimensions.

    You can then apply a clipping path.
    I used the element for the "tubeLiquid" element because it allows us to set the pathLength property to 100.

    We can easily change the current padding value by updating the lines-dasharray property:

    // show 100 %
    stroke-dasharray="100 100"
    
    // show 50 %
    stroke-dasharray="50 100"

    You will find many examples of using this method to implement various dynamic gauges/progress bars or animated pie charts , such as "Set svg progress bar percentage in JavaScript"

    reply
    0
  • P粉593649715

    P粉5936497152023-09-10 11:34:50

    The closest solution I found was I didn't fill the whole bottle, but you just had to change some coordinates in the polygon, I don't know much about shapes and polygons.

    <style>
    .item {
      width: 150px;
      height: 150px;
    }
    
    #tubeLiquid {
      background-color: #74ccf4;
      clip-path: polygon(45% 19%, 41% 22%, 41% 29%, 41% 36%, 41% 43%, 41% 50%, 41% 57%, 41% 63%, 41% 70%, 41% 77%, 41% 83%, 41% 90%, 43% 93%, 50% 92%, 56% 93%, 60% 88%, 59% 81%, 60% 75%, 60% 68%, 60% 61%, 59% 55%, 59% 48%, 59% 42%, 59% 35%, 59% 29%, 58% 23%, 54% 19%);
    }
    
    #bottleMask{
      background-color: #FFFFFF;
      clip-path: polygon(45% 19%, 41% 22%, 41% 29%, 41% 36%, 41% 43%, 41% 50%, 41% 57%, 41% 63%, 41% 70%, 41% 77%, 41% 83%, 41% 90%, 43% 93%, 50% 92%, 56% 93%, 60% 88%, 59% 81%, 60% 75%, 60% 68%, 60% 61%, 59% 55%, 59% 48%, 59% 42%, 59% 35%, 59% 29%, 58% 23%, 54% 19%);
    }</style>
    
    <div class="item">
      <svg viewBox="0 0 300 300">
        <defs>
          <mask id="bottleMask" fill="white">
            <path d="M0,0h300v300H0V0z M89,68h122v147H89V68z" />
          </mask>
          <clipPath id="liquidClip">
            <path d="M89,68h122v147H89V68z" />
          </clipPath>
        </defs>
        <image width="300" xlink:href="https://i.ibb.co/Mhfwtxp/image-removebg-preview-1.png" />
        <path id="tubeLiquid" fill="#74ccf4" d="M0,0h300v300H0V0z" clip-path="url(#liquidClip)" mask="url(#bottleMask)" />
      </svg>
    </div>

    reply
    0
  • Cancelreply