Actualmente tengo dos variables que definen elementos svg. Tengo problemas para transformarme entre los dos, probé react-svg-morph pero el círculo desaparecía en cada renderizado. ¿Cuál es la mejor manera de renderizar un morph?
Esta es mi configuración:
let hexagonShape = <svg width="100%" height="100%" viewBox="0 0 15 15" fill="green" xmlns="http://www.w3.org/2000/svg"> <path d="M1.5 4.5V10.5L7.5 14L13.5 10.5V4.5L7.5 1L1.5 4.5Z" stroke="green" strokeWidth=".6" /> </svg> let circleShape = <svg height="100%" width="100%" viewBox="0 0 15 15" fill='blue' xmlns="http://www.w3.org/2000/svg"> <circle cy="50%" cx="50%" r="49%" stroke="blue" strokeWidth=".3" /> </svg> const [updatedSvg, setUpdatedSvg] = useState(0) const [updatedCircleSvg, setUpdatedCircleSvg] = useState() const [updatedHexagonSvg, setUpdatedHexagonSvg] = useState() function changeSvg() { if (updatedSvg === 0) { setUpdatedCircleSvg(true) setUpdatedHexagonSvg(false) } if (updatedSvg === 1) { setUpdatedCircleSvg(false) setUpdatedHexagonSvg(true) } } useEffect(() => { changeSvg() }, [updatedSvg])Y tengo dos botones simples que alternan entre los dos renders svg:
<div className={classes.container}> <div className={classes.shape}> {/* this is where the svgs are being rendered */} {updatedCircleSvg && circleShape } {updatedHexagonSvg && hexagonShape} </div> <button onClick={() => setUpdatedSvg(0)}>circle</button> <button onClick={() => setUpdatedSvg(1)}>hexagon</button> </div>Un poco de orientación ayudaría mucho. Gracias
Aquí hay un ejemplo simple usando curvas cuadráticas de Bézier:
const getPoints = radius => { const factor = Math.sqrt(3); return [ {x: 0, y: -radius}, {x: radius / factor, y: -radius}, {x: radius * factor / 2, y: -radius / 2}, {x: radius * 2 / factor, y: 0}, {x: radius * factor / 2, y: radius / 2}, {x: radius / factor, y: radius}, {x: 0, y: radius}, {x: -radius / factor, y: radius}, {x: -radius * factor / 2, y: radius / 2}, {x: -radius * 2 / factor, y: 0}, {x: -radius * factor / 2, y: -radius / 2}, {x: -radius / factor, y: -radius} ]; } const getRoundPath = radius => { const p = getPoints(radius); return `M ${p[0].x},${p[0].y} Q ${p[1].x},${p[1].y} ${p[2].x},${p[2].y} Q ${p[3].x},${p[3].y} ${p[4].x},${p[4].y} Q ${p[5].x},${p[5].y} ${p[6].x},${p[6].y} Q ${p[7].x},${p[7].y} ${p[8].x},${p[8].y} Q ${p[9].x},${p[9].y} ${p[10].x},${p[10].y} Q ${p[11].x},${p[11].y} ${p[0].x},${p[0].y}` }; const getHexagonPath = radius => { const p = getPoints(radius); for (let index = 1; index < 12; index += 2) { const prev = p[index - 1]; const next = p[(index + 1) % 12]; p[index].x = (prev.x + next.x) / 2; p[index].y = (prev.y + next.y) / 2; } return `M ${p[0].x},${p[0].y} Q ${p[1].x},${p[1].y} ${p[2].x},${p[2].y} Q ${p[3].x},${p[3].y} ${p[4].x},${p[4].y} Q ${p[5].x},${p[5].y} ${p[6].x},${p[6].y} Q ${p[7].x},${p[7].y} ${p[8].x},${p[8].y} Q ${p[9].x},${p[9].y} ${p[10].x},${p[10].y} Q ${p[11].x},${p[11].y} ${p[0].x},${p[0].y}` } const morphPath = (toHex) => { const path = toHex ? getHexagonPath(80) : getRoundPath(80); d3.select('path') .transition() .duration(750) .attr('d', path); setTimeout(() => morphPath(!toHex), 1000); }; d3.select('path').attr('d', getRoundPath(80)) morphPath(true); <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg width="200" height="200"> <g transform="translate(100,100)"> <path /> </g> </svg>