'How to fill a png file in function of a percentage [closed]

I'm currently building one of my my first projects in HTML/CSS so i'm a newbie. I want to fill a png in function of a percentage but I don't find anything talking about this. I tried using a double image but it's not clean and not working very well

It's a preview of what I did on figma

I want to make this in HTML CSS to integrate in a videogame



Solution 1:[1]

You could also use CSS crop on some divs instead of an image, that will make your code something like this:

A container, two hearth shaped divs and a button for triggering the fill

<!-- A wrapper for the hearths -->
<div class="container">
    <!-- A shape that serves as the placeholder -->
    <div class="hearth base"></div>
    <!-- The shape that is going to be filled -->
    <div class="hearth color"></div>
</div>
<button onclick="fillHearth()" >Fill Hearth</button>

The styles

.container {
  margin: 70px;
  display:flex;
  flex-wrap: wrap;
  gap: 10px 120px;
  position: relative;
}
.hearth {
  position: absolute;
  width: 24px;
  height: 24px;
  clip-path: path("M12 4.248c-3.148-5.402-12-3.825-12 2.944 0 4.661 5.571 9.427 12 15.808 6.43-6.381 12-11.147 12-15.808 0-6.792-8.875-8.306-12-2.944z");
  transform: scale(5);
}
.base {
  background: #cecece;
}
.color {
  background: transparent;
}

The script that fills the hearth in an interval of half a second

function fillHearth(argument) {
    let current = 0;
    console.log('Filling hearth');
    const interval = setInterval(() => {
        console.log('Current: ', current);
        document.querySelector('div.color').style.background = 
              `linear-gradient(to top, #FF5252 ${current}%, transparent 0)`;
        current += 10;
        if (current > 100) clearInterval(interval);
    }, 500);
}

The crop shape was taken from here

Solution 2:[2]

I think this could be considered the quickest approach to the problem using just one img element and a css rule.

The picture is a png image I uploaded myself having a yellow background and a transparent hearth shape in the middle.

The filling is made by the background css attribute using linear-gradient to paint a given % of the picture height as blue. Since the shape inside the picture is transparent, the blue color comes out only there.

The demo includes a range slider to show how you can control that % dinamically via js.


EDIT:

I added the solution proposed by @FernandoBravoDiaz just to show how you could fill its hearth shaped with clip-path. Its solution is good enough to be the accepted one.

The solutions you proposed on comments use svg ... unfortunately I don't know how to make an hearth shape that way and it wasn't explored that far in the answer you cited.

I think you can use the @FernandoBravoDiaz solution and just add the linear-gradient strategy to fill it up with a solid color for a given %. I placed the hearth inside a relative positioned container.

document.addEventListener("DOMContentLoaded", ()=>{

  document.querySelector('#giveSupport').addEventListener('change', ()=>{
    sliderPercentage = window.event.target.value;
    
    document.querySelector('img.hearth').style.background = 
      `linear-gradient(to top, blue ${sliderPercentage}%, transparent 0)`;
      
    document.querySelector('.hearthvectorial').style.background = 
      `linear-gradient(to top, blue ${sliderPercentage}%, transparent 0)`;
  });
  
});
/*
---------------------------------------
 Original Solution - Using picture mask
---------------------------------------
*/

.hearth{
  width: 200px;
  /* here you are controlling the % */
  background: linear-gradient(to top, blue 49%, transparent 0);
}

/*
---------------------------------------
 Svg Solution - proposed by
---------------------------------------
*/

.backgroundpage{
  width: 100%;
  height: 200px;
  background: red;
  position: relative;
}

.hearthvectorial {  

  /*position absolute will be relative to the container having position:relative*/
  position: absolute;    
  top: 44px;
  left: 48px;  
  
  /*this is when display: block*/
  /*
  margin-left: 42px;
  margin-top: 42px;
  */
  
  /*size*/
    width: 24px;
    height: 24px;       
  
  /*hearth shape*/
    clip-path: path("M12 4.419c-2.826-5.695-11.999-4.064-11.999 3.27 0 7.27 9.903 10.938 11.999 15.311 2.096-4.373 12-8.041 12-15.311 0-7.327-9.17-8.972-12-3.27z");  
    transform: scale(5);
  
  /*background strategy to fill %*/
  background: linear-gradient(to top, blue 100%, transparent 0);
}
<img
  src="https://i.ibb.co/68RY3q8/UA.png"
  class="hearth" />
  
<input
  type="range"
  id="giveSupport"
  style="cursor:pointer;"
  min="0"
  max="100" />
  
  <hr>
  
  <h1>Solution proposed by @FernandoBravoDiaz</h1>
  
  <div class="backgroundpage">    
    <div class="hearthvectorial">
    </div>  
  </div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fernando Bravo Diaz
Solution 2