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>