motion
motion copied to clipboard
[BUG] It isn't possible to animate the `x` and `y` coordinates of an SVG element using `animate`
1. Read the FAQs 👇
2. Describe the bug
It is not possible to animate the x and y coordinates of an SVG element using animate.
3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
https://codesandbox.io/p/sandbox/testing-framer-motion-forked-xpwzg4?file=%2Fsrc%2FApp.js
4. Steps to reproduce
Attempt to animate the x and y properties of an SVG element directly, by using x and y on the element.
5. Expected behavior
The x and y attributes should animate to their new values.
+1
@mattgperry I'm facing this issue as well. This seems to have broken with v11 since my old prod site on v10 is still working. Interestingly for me, the animation is only working on exit. Initial → Animate is not working.
+1
@mattgperry same for transform properties. Tried those within sequence array:
scale: [0, 1]
transform: ['scale(0)', 'scale(1)']
+1 spent a while debugging thinking i wasn't selecting the elements correctly, but realised opacity still works fine.
const [scope, animate] = useAnimate()
...
// does not work, works fine with opacity
animate('path', {x: [0, 20]})
Was porting over GSAP animations to framer-motion, but it's impossible to do any complex timeline transitions involving SVGs with framer-motion without this working. 😢
I just hit this as well :( I'm trying to animate a <circle> inside an <svg>
+1 I thought I was doing something wrong, it seems like setting the height, width, fill, rx, ry, etc. It seems like the only thing is transforming the element, setting the x,y scale, rotation, etc.
const duration = 1;
const ease = "easeInOut";
animate("#lines rect#n-left", { fill: "#ff0000" }, { duration, ease }); // works
animate("#lines rect#n-left", { rotate: -23, x: 43, y: 43}, { duration, ease }); // doesn't work
<svg viewBox="0 0 948 389" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="lines">
<rect id="n-left" width="42" height="389" rx="21" fill="#D9D9D9"></rect>
</g>
</svg>
Hope this gets fixed soon.
Digging into this a bit more, it looks like the motion component and animate methods use completely different animation mechanisms (?). Would try to open a PR if I had half an idea what is going on 😅 @mattgperry any way to advise?
I managed to get around this issue by making the elements i needed to animate motion elements.
Using @Drew-Chase's example
<svg viewBox="0 0 948 389" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="lines">
<rect id="n-left" width="42" height="389" rx="21" fill="#D9D9D9"></rect>
</g>
</svg>
should be
<svg viewBox="0 0 948 389" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="lines">
<motion.rect id="n-left" width="42" height="389" rx="21" fill="#D9D9D9"></motion.rect>
</g>
</svg>
Where <rect> becomes <motion.rect>
Then animate("#lines rect#n-left", { rotate: -23, x: 43, y: 43}, { duration, ease }); should work correctly
It seems like Framer needs the elements to be added to Motion in some form to have more complex animations applied to them.
It does add a step to preparing SVGs for animation, as you need to remember to make the bits you want to animate a motion element, so can be a little time-consuming if you keep editing the original graphic but does seem to work.
Hmm.. tried this will Lazy Motion (m), which is what my project uses, and sadly doesn't work for me :( @andrewmumblebee