Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill background color to svg image in percentage

Tags:

css

svg

How to fill background color to SVG image in percentage

I want to fill color to svg image in percentage

Here is moon svg image I want to fill white color base on the illumination percentage on moon

90% 80% 70% and so on

<?xml version="1.0" encoding="iso-8859-1"?> 
<svg xmlns="http://www.w3.org/2000/svg" width="139" height="134"> 
<g> 
  <circle stroke-width="7" stroke="#000" fill="#fff" r="58" cy="69" cx="69"/>
  <path stroke-width="0" fill="#000" d="m69,9 a62,60 0 0 0 1,121 l0,-5 a70,68 0 0 1 0,-110 l0,-5 z"/>
 </g></svg>
like image 857
M.Javid Avatar asked Dec 01 '22 14:12

M.Javid


2 Answers

I would do this with a mask. So I can make an elliptical shadow.

// Set handler on input slider
var control = document.getElementById("control");
control.addEventListener("input", setMoonPhase);

// Initialise SVG from initial value of slider
setMoonPhase();

function setMoonPhase(evt) {
  // Convert from percentage to a 0..1 value
  var val = control.value / 100;
  // Get the ellipse element that represents the moon phase
  var  phaseEllipse = document.getElementById("phase-ellipse");
  // Set the X radius of the phase ellipse (where 100% = 0.5 -> 50% = 0 -> 0% = 0.5)
  phaseEllipse.rx.baseVal.value = Math.abs(val - 0.5);
  // If the phase > 50% then the ellipse needs to be white.
  // Otherwise it is black, to make a hole in the mask to let the black background show through.
  phaseEllipse.style.fill = (val > 0.5) ? "white" : "black";
}
<svg xmlns="http://www.w3.org/2000/svg" width="139" height="134">
  <defs>
    <mask id="phase-mask" maskContentUnits="objectBoundingBox">
      <rect x="0.5" y="0" width="0.5" height="1" fill="white"/>
      <ellipse id="phase-ellipse" cx="0.5" cy="0.5" rx="0.2" ry="0.5" fill="white"/>
    </mask>
  </defs>
  <circle fill="black" r="58" cy="69" cx="69"/><!-- moon shadow -->
  <circle fill="#fff" r="54.5" cy="69" cx="69" mask="url(#phase-mask)"/><!-- sunlight on moon -->
  <circle stroke-width="7" stroke="black" fill="none" r="58" cy="69" cx="69"/><!-- moon border -->
</svg>

<p>
<input id="control" type="range" min="0" max="100" value="90" /><span id="output"></span>
</p>
like image 58
Paul LeBeau Avatar answered Dec 09 '22 17:12

Paul LeBeau


I would do it with clip-path.

mooning()


control.addEventListener("input",()=>{
mooning()
})


function map(n, a, b, _a, _b) {
  let d = b - a;
  let _d = _b - _a;
  let u = _d / d;
  return _a + n * u;
}

function mooning(){
output.innerHTML = control.value + "%";
let value = map(control.value, 0, 100, -25, 175)
moon.setAttributeNS(null, "cx", value)
}
svg{border:1px solid; width:75vh}
#control{width:75vh;}
 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150"> 
 <clipPath id="cp">
  <circle id="fullMoon"  r="50" cy="75" cx="75"/>
 </clipPath>
 <g clip-path="url(#cp)">
 <rect width="100%" height="100%" />  
 <circle id="moon" r="50" cy="75" cx="175" fill="white" />
 </g>
 
 <use xlink:href="#fullMoon" fill="none" stroke="black"  />
 
</svg>

<p><input id="control" type="range" min="0" max="100" value="60" /><span id="output"></span></p>
like image 44
enxaneta Avatar answered Dec 09 '22 19:12

enxaneta