What is the best way to add color to the bottle's outline using clipPath?

How do I fill the background inside a bottle image with color?

I have the coordinates for filling the bottle, but the background inside remains unfilled.

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

Answer №1

Additional <mask> is not necessary.
Consider utilizing a rounded <rect> as the clip-path due to the bottle's shape:

waterLevel.addEventListener('input', e => {
  let value = +e.currentTarget.value
  tubeLiquid.setAttribute('stroke-dasharray', `${value} 100`)
})
svg {
  width: 20%;
}
<h3>Establish 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>Outline liquid fill level</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>

Begin by designing your clip-path and fill-scale/progress bar shapes first – without applying any clipping – to determine the correct coordinates and dimensions.

Then, proceed with applying the clip-path.
For the "tubeLiquid" element, I chose to use a <line> element which allows setting the pathLength attribute to 100.

To modify the current fill value, simply update the stroke-dasharray attribute:

// display 100 %
stroke-dasharray="100 100"

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

This method is commonly used for various types of dynamic gauges/progress bars or animated pie charts, as demonstrated in examples on SO like "Set svg progress bar percentage in javascript"

Answer №2

The solution that caught my attention is this one where the bottle was not filled entirely, instead, some coordinates in polygons were adjusted. Unfortunately, I lack knowledge about shapes and polygons to make further changes.

<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)&qupt mask="url(#bottleMask)"/>
  </svg>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Eliminate any HTML content using Jsoup while retaining the text lines

I am working with a String that contains e-mail content, and my goal is to eliminate all HTML coding from this String. This is the current code I have: public static String html2text(String html) { Document document = Jsoup.parse(html); document = ...

Incorrect positioning on canvas

Is there a way to adjust text alignment within a canvas? Currently, my text is centered. However, when I change the text size, the alignment gets thrown off. Here is the code snippet: <canvas id="puzzle" width="480" height="480"></canvas> ...

Modifying Ajax-injected HTML with JQuery's editInPlace functionality

I have been successfully using the JQuery editInPlace plug-in on a static HTML page. However, I am facing an issue when trying to use the same plugin with HTML injected via an Ajax call. I have heard that using .on() like '$('.edit_inplace_fiel ...

Is retrieving data from the database causing unexpected additional space to appear in the textarea?

I am facing an issue with a basic php file that fetches information from a MySQL database and displays it inside a textarea. However, when I access the file through browsers, there seems to be extra space at the start and end of the text within the textare ...

Ways to implement a setTimeout function to return to the initial div element?

I have a unique setup on my webpage with three divs. The first div features an html5 video, the second div contains buttons for interaction, and the third div acts as a thank you page that loops back to the beginning like a photo slide. I have shared my co ...

Labels are overlapping each other and being aligned to the right side

Working with the most up-to-date version of Bootstrap, I am currently designing a search bar featuring a dropdown menu preceding the search button. Upon clicking the dropdown, various controls are revealed. Below is the HTML code for this configuration: ...

Tooltip remains visible even after formatting in highcharts

I have successfully hidden the datalabels with 0 values by formatting them. However, after formatting the tooltips for 0 valued data in a pie chart, there is an issue where hovering over the 0 valued portion shows a white box as shown in the picture. I hav ...

Pressing the different buttons on a form does not result in the form being submitted

I have a form with multiple buttons that, when submitted, will redirect to a different page and pass along some variables. echo " <form method=\"POST\" action=\"sightWordsTest.php\"> ...

`javascript pop up notification will only display one time`

I am currently developing a chrome extension with two different modes. When the user clicks on the icon, a pop-up message should appear to indicate which mode is active. However, I am facing an issue where the message does not always display when the pop- ...

Having trouble getting the CSS footer from cssstickyfooter.com to function properly

I tried implementing some basic CSS from to create a sticky footer that remains at the bottom of the page regardless of content length. However, I am encountering a problem with the footer not behaving as expected. There are actually two issues with the f ...

The positioning of drawings on canvas is not centered

I'm facing an issue while attempting to center a bar within a canvas. Despite expecting it to be perfectly centered horizontally, it seems to be slightly off to the left. What could possibly be causing this discrepancy? CSS: #my-canvas { border: ...

Tips on aligning data received as a response from a Perl script

Currently, I am utilizing a Jquery-Ajax call to a perl script in order to retrieve specific data. The perl script executes a database query and transmits the data back to the HTML page. while (my @data = $statement->fetchrow_array()) { print "$ ...

The elements from base.html and the extended page are now placed on separate rows rather than on the same row

I'm relatively new to HTML, Jinja, and CSS and have been playing around with creating a webpage that retrieves data from a sqlite3 database. As of now, I am facing some challenges regarding formatting. To assist with table formatting and overall aest ...

How can I target an element with inline styling using CSS?

How can I target headings with inline style 'text-align: center' in my CSS so that I can add ::after styling to them? This is for a WordPress CMS, specifically to modify content in the WYSIWYG editor used by clients. Here's an example of th ...

Customizing the background color in TurnJSIncorporating

Recently, I encountered a problem that has left me puzzled. Despite searching online for help, I have not been able to find a solution. The issue lies with the basic code provided on the official page of the TurnJS script. <div id="flipbook"> <di ...

Issue with inner span not inheriting max-width set on outer <td> element

Whenever I hover over a table cell, the Angular Bootstrap popover should appear next to the text. However, the 'span' element remains at its full width. <td style="max-width: 50px; text-align: left; white-space:nowrap; overflow:hidden; text- ...

conceal a targeted section from the bottom of the iframe

I have a website embedded inside an iframe for use in a webview application. <body> <iframe id="iframe" src="http://www.medicamall.com"></iframe> </body> This is the CSS code: body { margin:0; padding:0; height:10 ...

Having difficulties redirecting with the button's onclick function

I'm struggling to redirect users to another page using a button (assuming the hostname is localhost:8000) $('#getFruit').attr('onclick', window.location.host + '/getFruit/banana') <script src="https://cdnjs.cloudfl ...

Managing and keeping track of a universal value within the success callback function among numerous Ajax POST requests

I am faced with a challenge involving two HTML elements: 1). a div element that functions as a multiple select, created automatically by a predefined widget, and 2). a button that triggers an onclick event. On the JavaScript side, I have a global variable ...

Unusual ways that backgrounds and borders behave while incorporating CSS transitions for changes in height, positions, and transformations

I was under the impression that I had come up with a brilliant idea... I wanted to create a button with a hover effect where the background would do a wipe transition (top to bottom, left to right) using soft color transitions. My plan was to achieve this ...