Reputation: 1035
I have an SVG rounded corner container that shows a fill level. I need to change the fill level dynamically. This would be trivial if the container were a rect, but the rounded corners need a path.
here is the path for the black 'filled area'
`M0, 220 L100,220 L100,220 C100,231.045695 91.045695,240 80,240 L20,240 C8.954305,240 1.3527075e-15,231.045695 0,220 L0,120 L0,120 Z`
I need to know which elements of the path to change to fill and empty the tank in a clean way.
Upvotes: 1
Views: 1208
Reputation: 11283
Even if you find the way to fill the tank you have to take care of top borders.
const { useState, useRef, useEffect } = React;
const App = () => {
const [value, setValue] = useState(220);
const handle = useRef(null);
useEffect(() => {
if(value < 50) {
clearTimeout(handle.current);
}
}, [value]);
useEffect(() => {
let isUnmounted = false;
const loop = () => {
if(isUnmounted) {
return;
}
setValue(value => value - 10);
handle.current = setTimeout(loop, 200);
}
handle.current = setTimeout(loop, 200);
return () => {
isUnmounted = true;
clearTimeout(handle.current);
}
}, [])
return <div>
<svg width="400" height="400">
<path d={`M0, ${value} L100,${value} L100,220 C100,231.045695 91.045695,240 80,240 L20,240 C8.954305,240 1.3527075e-15,231.045695 0,220 L0,120 L0,120 Z`}/>
<rect fill="none" stroke="black" x="0" y="40" width="100" height="200" rx="15" />
</svg>
</div>
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
svg, path {
transition: all .3s ease-in;
}
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>
Upvotes: 1
Reputation: 33044
You don't need a new shape. You can use a linear gradient:
<svg viewBox="0 0 100 120" width="100">
<linearGradient id="lg" x1 = "0%" y1 = "0%" x2 = "0%" y2 = "100%">
<stop offset="0%" stop-color="#fff"></stop>
<stop offset="50%" stop-color="#fff"></stop>
<stop offset="50%" stop-color="#f00"></stop>
<stop offset="100%" stop-color="#f00"></stop>
</linearGradient>
<rect x="10" y="10" width="50" height="100" rx="15" ry="15" fill="url(#lg)" stroke="black" />
</svg>
In order to change the fill level dynamically you need to change the value of the second and 3rd stop offset to ${100 - yourvalue}%
Upvotes: 1