Describe the bug
When I don't define default/initial values _as attributes_, the component fails with the error:
Uncaught TypeError: Cannot read property 'red' of null
To Reproduce
As an example, this component/animation fails. This should be a looping spinner.
const animation = {
strokeDasharray: ['1px, 200px', '100px, 200px', '100px, 200px'],
strokeDashoffset: [0, -15, -125],
transition: { duration: 1.4, ease: 'linear' },
};
const Spinner: FC = (): ReactElement => {
const controls = useAnimation();
const handleAnimationComplete = useCallback(() => {
controls.start(animation);
}, [controls]);
useEffect(() => {
controls.start(animation);
}, [controls]);
return (
<svg viewBox='22 22 44 44'>
<Circle
animate={controls}
onAnimationComplete={handleAnimationComplete}
cx='44'
cy='44'
r='20.2'
fill='none'
strokeWidth='3.6'
/>
</svg>
);
};
Expected behavior
Modifing the circle to the below works, but this is the only way to resolve the issue. Setting the styles in CSS (with styled-components as an example) does not help.
<Circle
animate={controls}
onAnimationComplete={handleAnimationComplete}
strokeDasharray='80px, 200px'
strokeDashoffset='0'
cx='44'
cy='44'
r='20.2'
fill='none'
strokeWidth='3.6'
/>
Desktop (please complete the following information):
Additional context
I had the same issue when trying to add a rotate animation to an SVG element. I could not find any workaround for this one, so any help would be greatly appreciated.
const Spinner: FC= (): ReactElement => {
return (
<motion.svg viewBox='22 22 44 44' animate={{ rotate: 100 }}>
<Circle />
</motion.svg>
);
};
Other than this, I'm loving Framer Motion - amazing work!
Thanks for the detailed write-up! I'll take a look at this next week.
Glad you're enjoying it!
Thanks @InventingWithMonster! Let me know if I can help at all.
Ran into the same issue. Also happens when using variants. In my case it happened when trying to animate the <g> tag inside an <svg />
That's because initial~ values for SVGs are read from attributes here. That's certainly not that helpful - would be great to at least have a dev warning for this.
Yes, @Andarist - I also guessed that (which is how I solved the issue for my use case). It would be great to see this improved in some way.
Currently working on this bug but if anyone runs into similar, you can always explicitly set an initial value via the initial prop.
const Spinner = () => (
<motion.svg viewBox='22 22 44 44' initial={{ rotate: 0 }} animate={{ rotate: 100 }}>
<Circle />
</motion.svg>
)
Thanks @InventingWithMonster, that fix works - but if I use it with some properties, I get an error from react-dom:
Warning: Invalid DOM property `stroke-dasharray`. Did you mean `strokeDasharray`?
in circle (created by RenderComponent)
in RenderComponent (created by ForwardRef(MotionComponent))
in ForwardRef(MotionComponent) (at Spinner.tsx:28)
in svg (created by RenderComponent)
in RenderComponent (created by ForwardRef(MotionComponent))
in ForwardRef(MotionComponent) (at Spinner.tsx:27)
in div (created by Spinner)
in Spinner (at Spinner.tsx:24)
in Spinner (at Spinner.stories.tsx:7)
in ThemeProvider (at config.jsx:12)
In the DOM, I can see the attribute applied as stroke-dasharray;
initial={{ strokeDasharray: whatever }} comes out as that error?
Yes, sadly. If you aren't seeing that, I can set up a demo for you.
For the record, this is still happening in 1.2.6, although (if I understand correctly) it should have been fixed #221 and released in 1.2.5?
Example: https://codesandbox.io/s/confident-williamson-s09g1
… produces the same originally reported error Uncaught TypeError: Cannot read property 'red' of null
Ah yeah there may still be instances where this occurs. I'm tempted to default unreadable values to 0 - this would work well for the above but it'd break stuff like fill. I'll probably, in cases where we just can't find or infer an initial value, add a warning to ensure you set one.
Yes, I think a meaningful error message would go a long way. I was super-confused about the Cannot read property 'red' of null part and only found out by trial and error how to fix it.
Thanks for this!
I just ran into this today as well! I'm not sure 0 would be the expected here though. I ended up doing this:
const variants = {
initial: ({ x, y }) => ({
translateX: x,
translateY: y,
opacity: 0
}),
animate: ({ x, y }) => ({
translateX: x,
translateY: y,
opacity: 1
})
};