SVG Morphing not working
I thought it would be cool to use react-anime to create something like this: https://tympanus.net/Development/ShapeMorphIdeas/index3.html
I tried to morph the paths by wrapping each one in <Anime> and added the "d" attribute for each one respectively, but nothing happens. Any suggestions would be greatly appreciated!
Here's my code:
js
<svg className="scene" width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 1440 800">
<Anime
easing="easeOutElastic"
direction="alternate"
loop={true}
autoplay={true}
duration={Math.floor(Math.random() * 5000) + 3000}
d="M -84.52,-81.13 C -94.62,-73.4 -88.88,-59.55 -90.33,-48.91 -89.29,27.31 -89.61,103.5 -88.33,179.8 -85.99,416.1 -81.32,888.9 -81.32,888.9 -81.32,888.9 974.5,888.7 1587,891.9 1518,719.9 1487,644 1429,533 1388,437.7 1447,259.7 1400,187 1362,132 1270,90.53 1207,39.93 1161,2.932 1071,-74.45 1071,-74.45 1071,-74.45 914.5,-77.77 848.2,-80.17 537.6,-80.84 227,-81.38 -83.6,-81.6 -83.91,-81.44 -84.21,-81.29 -84.52,-81.13 Z"
>
<path d="M -84.52,-81.13 C -94.62,-73.4 -88.88,-59.55 -90.33,-48.91 -89.29,27.31 -89.61,103.5 -88.33,179.8 -85.99,416.1 -81.32,888.9 -81.32,888.9 -81.32,888.9 974.5,888.7 1587,891.9 1518,719.9 1487,644 1429,533 1388,437.7 1447,259.7 1400,187 1362,132 1270,90.53 1207,39.93 1161,2.932 1071,-74.45 1071,-74.45 1071,-74.45 914.5,-77.77 848.2,-80.17 537.6,-80.84 227,-81.38 -83.6,-81.6 -83.91,-81.44 -84.21,-81.29 -84.52,-81.13 Z"></path>
</Anime>
<Anime
easing="easeOutElastic"
direction="alternate"
loop={true}
autoplay={true}
duration={Math.floor(Math.random() * 5000) + 3000}
d="M 665.2,-83.08 C 413.7,-81.89 162.2,-82.43 -89.29,-81.61 -90.35,164.3 -85.06,410.2 -84.09,656.1 -83.37,733.7 -82.64,811.3 -81.92,888.9 442.4,889.8 966.7,890.7 1491,891.6 1253,747.5 1417,429.4 1286,245.4 1227,163.2 1107,142.1 1043,64.54 1009,24.41 973,-76.01 973,-76.01 973,-76.01 706.6,-83.67 665.2,-83.08 Z"
>
<path d="M 665.2,-83.08 C 413.7,-81.89 162.2,-82.43 -89.29,-81.61 -90.35,164.3 -85.06,410.2 -84.09,656.1 -83.37,733.7 -82.64,811.3 -81.92,888.9 442.4,889.8 966.7,890.7 1491,891.6 1253,747.5 1417,429.4 1286,245.4 1227,163.2 1107,142.1 1043,64.54 1009,24.41 973,-76.01 973,-76.01 973,-76.01 706.6,-83.67 665.2,-83.08 Z"></path>
</Anime>
<Anime
easing="easeOutElastic"
direction="alternate"
loop={true}
autoplay={true}
duration={Math.floor(Math.random() * 5000) + 3000}
d="M -85.01,-74.02 C -92.39,-66.64 -85.37,-55.79 -87.81,-46.91 -86.65,265.1 -84.66,577.2 -83.18,889.2 317.2,888.3 717.5,885.8 1118,890.4 1152,890.6 1187,890.9 1221,890 1219,768.3 1224,643.6 1187,526 1153,417 1091,319.3 1029,224.1 998.8,178.5 968.8,132.6 936.6,88.23 891.7,27.39 772.2,-78.96 772.2,-78.96 772.2,-78.96 222.1,-81.07 -85.01,-74.02 Z"
>
<path d="M -85.01,-74.02 C -92.39,-66.64 -85.37,-55.79 -87.81,-46.91 -86.65,265.1 -84.66,577.2 -83.18,889.2 317.2,888.3 717.5,885.8 1118,890.4 1152,890.6 1187,890.9 1221,890 1219,768.3 1224,643.6 1187,526 1153,417 1091,319.3 1029,224.1 998.8,178.5 968.8,132.6 936.6,88.23 891.7,27.39 772.2,-78.96 772.2,-78.96 772.2,-78.96 222.1,-81.07 -85.01,-74.02 Z"></path>
</Anime>
<Anime
easing="easeOutElastic"
direction="alternate"
loop={true}
autoplay={true}
duration={Math.floor(Math.random() * 5000) + 3000}
d="M -92.42,-79.11 C -89.97,243.8 -87.52,566.7 -85.07,889.6 201.8,889.9 488.7,889.9 775.5,895.6 880.4,896.9 985.2,894 1090,892.5 1064,773.3 1037,651.6 976.1,544.8 946.7,495.8 914.6,448.3 882,401.3 820.9,314.4 742.3,252 666.4,177.4 583.2,98.01 496.5,12.18 386.7,-23.38 328.4,-45.64 232.6,-81.38 232.6,-81.38 232.6,-81.38 9.82,-84.94 -92.42,-79.11 Z"
>
<path d="M -92.42,-79.11 C -89.97,243.8 -87.52,566.7 -85.07,889.6 201.8,889.9 488.7,889.9 775.5,895.6 880.4,896.9 985.2,894 1090,892.5 1064,773.3 1037,651.6 976.1,544.8 946.7,495.8 914.6,448.3 882,401.3 820.9,314.4 742.3,252 666.4,177.4 583.2,98.01 496.5,12.18 386.7,-23.38 328.4,-45.64 232.6,-81.38 232.6,-81.38 232.6,-81.38 9.82,-84.94 -92.42,-79.11 Z"></path>
</Anime>
<Anime
easing="easeOutElastic"
direction="alternate"
loop={true}
autoplay={true}
duration={Math.floor(Math.random() * 5000) + 3000}
d="M -88.6,95.54 C -90.38,166.1 -88.23,236.7 -88.68,307.4 L -86.19,890 C 229.7,890.2 939.8,892.4 939.8,892.4 855.2,767 831,639.4 721.4,519.4 634.7,424.5 526.4,360.9 428.8,281.8 332.7,204 251.6,102.3 140.1,48.9 70.75,15.73 -24.82,24.2 -85.28,0.03 Z"
>
<path d="M -88.6,95.54 C -90.38,166.1 -88.23,236.7 -88.68,307.4 L -86.19,890 C 229.7,890.2 939.8,892.4 939.8,892.4 855.2,767 831,639.4 721.4,519.4 634.7,424.5 526.4,360.9 428.8,281.8 332.7,204 251.6,102.3 140.1,48.9 70.75,15.73 -24.82,24.2 -85.28,0.03 Z"></path>
</Anime>
<Anime
easing="easeOutElastic"
direction="alternate"
loop={true}
autoplay={true}
duration={Math.floor(Math.random() * 5000) + 3000}
d="M -95.69,252.3 -87.65,890.4 698.1,892 C 698.1,892 599.1,687.7 518.9,610.6 348,446.2 131.4,466.5 -95.69,252.3 Z"
>
<path d="M -95.69,252.3 -87.65,890.4 698.1,892 C 698.1,892 599.1,687.7 518.9,610.6 348,446.2 131.4,466.5 -95.69,252.3 Z"></path>
</Anime>
<Anime
easing="easeOutElastic"
direction="alternate"
loop={true}
autoplay={true}
duration={Math.floor(Math.random() * 5000) + 3000}
d="M -85.59,444.4 -85.59,890.6 489,895.6 C 489,895.6 436.8,745.3 382.5,690.8 258.1,565.8 57.98,629.2 -85.59,444.4 Z"
>
<path d="M -85.59,444.4 -85.59,890.6 489,895.6 C 489,895.6 436.8,745.3 382.5,690.8 258.1,565.8 57.98,629.2 -85.59,444.4 Z"></path>
</Anime>
</svg>
css
.scene {
position: fixed;
background: #282886;
z-index: -10;
}
.scene g:first-child path {
fill: #4f4fea;
}
.scene g:nth-child(2) path {
fill: #0c27cf;
}
.scene g:nth-child(3) path {
fill: #13269c;
}
.scene g:nth-child(4) path {
fill: #242468;
}
.scene g:nth-child(5) path {
fill: #2648e6;
}
.scene :nth-child(6) path {
fill: #2c31b0;
}
.scene g:nth-child(7) path {
fill: #262689;
}
Yeah messing around with the d prop to make some cool animations like frame by frame stuff sounds like a pretty important use case!
Would you mind sending a CodePen our way?
@8ctopotamus I got something similar to this working:
const d = [
{ value: "M -88.52,-43.13 C -34.62..." }
]
<Anime
easing="easeInOutCubic"
duration={3000}
d={d}
direction='alternate'
width={1500}
height={1500}
loop={true}
>
<path className='path' d='M -84.52,-81.13 C -94.62...' />
</Anime>
Your d prop has to be a different value than the one assigned to your actual path.
@ryandunnewold That didn't work for me. Can you post a full/barebones example? :\
Here's what I tried: https://codepen.io/corysimmons/pen/LeGaNy?editors=0010
Also, it'd be nice to pull the <svg> outside of <Anime> but that seems to break the svg all together...
It should look like this after animation is complete:

It would be nice to see a full/barebones example on codepen or something. I can't seem to get it working either.
I'll work on putting it into a Codepen example
I am having issues with triggering React-Anime animations via state change. I am conditionally rendering naked elements in their initial state -> the element with an <Anime> wrapper when it is time to animate. However, when going back to the initial state, the transition back is very rough, probably because I am removing the entire Anime wrapper and re-rendering the original element, so it jumps in.
Working Example: https://codesandbox.io/embed/6lxoq1vz5r
I am having issues when I try to manually modulate the points prop in the Anime wrapper around an SVG element. The entire Polygon seems to disappear.
Error: https://codesandbox.io/s/mjv24o32rp
Is there any update on this? I am having a similar problem. I can get the animation to run, but if the parent component's state changes, the Anime component disappears and I then get the error Cannot read property 'nodeType' of null (possibly the same issue as https://github.com/hyperfuse/react-anime/issues/43?)
Update: This was fixed when adding a unique key to my Anime element:
key={11+Date.now()}
When trying this I can see the SVG path is in fact morphing but it adds a div tag around the path and messes up the SVG and creates invalid html.
Is there any way to prevent the path from being wrapped inside a div tag by anime?
I can post a codepen but it is easy to reproduce.
