I have a very weird issue. I am doing a basic animation like (with framer-motion 5.5.5 and tailwindcss 2.2.16):
<motion.div
className="w-2/3 h-96 bg-red-500 absolute left-10 top-10"
initial={{ x: 2700 }}
animate={{ x: 0 }}
transition={{
type: "spring",
stiffness: 80,
delay: 0.6,
damping: 15,
}}
></motion.div>
The problem with this animation is that on Edge it lags/freezes a tiny amount in the ending. On any other browser like Chrome and Firefox, the animation is very smooth. The weird part is that if I am using the Edge Incognito mode (InPrivate) the animation is smooth without any lag or freeze.
I have to specify that I am returning the above element in index.js so nothing else it's interfering.
My node version is v16.13.1 and my npm version is 8.1.2.
I'm trying to draw a dashed path, or at least give that illusion, using Framer Motion. Think animating a foot path on a treasure map. Animating the path length seems to be a common method, and so I've implemented it like below.
<motion.span
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
d="...a list of coordinates"
stroke="#000"
strokeWidth="5"
strokeDasharray="8"
/>
But it appears animating the path length doesn't work well with strokeDasharray. When I add the strokeDasharray value using the attribute, the path length animates but the strokeDasharray value, when inspected, reads 2000px instead of 8px. And when I add the strokeDasharray using CSS or inline styling, the path is dashed correctly, but the animation doesn't work.
From what I've read, strokeDasharray uses the path length when doing it's computations, so I'm guessing the initial "0" value is throwing things off. Might be way off. I don't know.
Is there a simple fix here? Or should I reassess how I go about the animation? Thank you!
Not a solution using Framer Motion, but found this pen by Ruskinz that does the job using some css animation. The HTML looks like this:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="340" height="333" viewBox="0 0 340 333">
<defs>
<path id="path1" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41 C46.039,146.545,53.039,128.545,66.039,133.545z" />
<mask id="mask1"><use class="mask" xlink:href="#path1"></mask>
</defs>
<use class="paths" xlink:href="#path1" mask="url(#mask1)" />
</svg>
And the CSS looks like this:
.paths {
fill: none;
stroke: grey;
stroke-dasharray: 5;
stroke-width: 5;
stroke-linejoin: round;
}
.mask {
fill: none;
stroke: white;
stroke-width: 10;
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear alternate infinite;
}
/* does not work in IE, need JS to animate there */
#keyframes dash {
from {
stroke-dashoffset: 1000;
}
to {
stroke-dashoffset: 0;
}
}
See the full pen at https://codepen.io/elliz/pen/prYqwx
I had the same issue because i wanted to animate it with framer-motion and not in css. What i just did is i just put an exact copy of the path with the dashedArray line below the path which i'm going to animate.
It will act as an overlay. I just gave it the stroke color of the background and tweaked the stroke-width. I don't know how it would be with a linearGradient background. But in my case with a static background color it worked.
import { motion } from 'framer-motion';
export default function Path({ pathColor, bg }) {
return (
<svg
width="245.24878"
height="233.49042"
viewBox="0 0 64.888737 61.777671"
version="1.1"
id="svg1033">
<defs
id="defs1030" />
<g
id="layer1"
transform="translate(-20.472293,-22.027827)">
<g
id="g484"
transform="translate(11.886667,6.306109)"
>
<motion.path
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{
pathLength: { delay: 0.4, type: "tween", duration: 3, bounce: 0 }
}}
stroke={pathColor}
strokeDasharray='3.846, 1.282'
strokeDashoffset='0'
strokeWidth='0.641'
style={{ fill: 'none', fillRule: 'evenodd', strokeLinejoin: 'round' }}
d="m 70.258127,15.782623 c 0,0 -1.867161,10.194243 -5.854843,12.473363 -9.471023,5.413069 -22.204956,-6.41444 -32.583479,-3.054701 -9.553598,3.092694 -21.015474,9.948708 -22.6557013,19.855557 -1.7758628,10.726077 5.8258513,25.311914 16.2917403,28.255989 11.258271,3.166974 19.313188,-18.990719 30.80157,-16.800859 5.208004,0.992724 10.182339,12.218805 10.182339,12.218805"
id="path1154"
/>
<path
stroke={bg}
strokeDasharray='3.846, 2.282'
strokeDashoffset='0'
strokeWidth='1.641'
style={{ fill: 'none', fillRule: 'evenodd', strokeLinejoin: 'round' }}
d="m 70.258127,15.782623 c 0,0 -1.867161,10.194243 -5.854843,12.473363 -9.471023,5.413069 -22.204956,-6.41444 -32.583479,-3.054701 -9.553598,3.092694 -21.015474,9.948708 -22.6557013,19.855557 -1.7758628,10.726077 5.8258513,25.311914 16.2917403,28.255989 11.258271,3.166974 19.313188,-18.990719 30.80157,-16.800859 5.208004,0.992724 10.182339,12.218805 10.182339,12.218805"
id="path1155"
/>
</g>
</g>
</svg>
);
}
I'm using the following to try to animate a simple square from red to green with framer motion. If I use the exact same code with opacity, everything works. Likewise if I transform the square with x and y. But with fill, as soon as the square renders it changes fill, and there is no transition. After a few hours of trying to understand why this is, I can't find an answer.
In the docs it says "For instance, physical properties like x or scale will be animated via a spring simulation. Whereas values like opacity or color will be animated with a tween."
It makes no mention of whether I need to do more to create this tween.
Any help would be hugely appreciated, thanks.
const pathVariants = {
notSwitched: {
fill: 'red',
},
switched: {
fill: 'green',
},
}
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="600"
height="300"
viewBox="0 0 600 300"
>
<motion.path
initial="switched"
animate="notSwitched"
variants={pathVariants}
id="square"
d="M38,212V88H162V212Z"
/>
</svg>
)
I like to make a div expand according to its content height but the hole Component inside that div is hidden if I use like height: '100%'. It's a bit complex and wish for some extra eyes!
I made a CodeSandbox
Looks like this in Chrome:
I can see during debug that the "hidden" Component is rendering ok so it's strange that it's "hidden"
If I set the same Style to height: 1000 the <ul> have Children:
But I want it to expand according to its content height so height: 1000 will not work.
In this CodeSandbox I set the height: 1000, to demonstrate what happens. The Component that refuse to expand height is a Masonry image gallery Component
style={{
width,
height: 1000,
position: 'relative',
margin: '0 auto',
}}
When you open the Sandbox you see in the left editor windows this TimeLineViewer.js and the Style code problem. The TimeLineViewer.js loads the Masonry image gallery Component Masonry.js
What I have tried is to set parent to also 100% height but with no luck.. I'm a little bit new to JavaScript and HTML so advice would be good
To debug this, start by taking off or commenting out the LeComponent and then testing your div actual height when you are implementing the 100% height.
<div
style={{
width,
height: !fullscreen && "100%",
position: fullscreen ? 'initial' : 'relative',
margin: '0 auto',
}}
>
{/* <LeComponent
infinite
items={items}
itemRenderer={ItemRenderer}
gutter={gutter}
outerGutter={outerGutter}
extraPx={0}
debug={debug}
rows={{
0: 1,
320: 2,
480: 3,
640: 4,
}}
cols={{
0: 1,
360: 2,
640: 2,
960: 3,
1280: 4,
1400: 5,
1720: 6,
2040: 7,
2360: 8,
}}
onEnd={() => {
// TODO possible when many items lazy load them
// this.addItems();
}}
/> */}
</div>
You will notice, that it still takes up no height at all and the component you created did not have any bearing to that. This is because it is a CSS issue. The height percentage cannot be determined because there is no parent or ancestor with a height definition. You are getting the percentage of void.
After that, we can take a glance at your Masonry component. Just by looking at the method identifiers (such as _getDimensions, _setContainerHeight) and further reviewing the code base, we can learn that this component is actually dependent on certain element dimensions (most likely the parent div dimension as well) - and from what we learned from the CSS issue awhile ago, the parent div actually has a height of 0.
At this point, I took out the style props on your Masonry Component so that it would not be dependent on the parent dimensions and that fixed the issue
<div ref={this.container}>
<ul ref={this.list}>
{mounted && items.map((item, index) => this.renderItem({ index, item, maxIndex }))}
</ul>
</div>
I develop a SPA application and I wish place table in parent element bounds but I can't set explicit height. I can set scroll.y of table body but then result total height is large by header height. I can't get header height to calculate total needed height.
How I may place table into parent bounds?
<div style={{ width: '100vw', height: '100vh'}}>
<Table scroll={{ y: '100%' }} style={{ width: '100%', height: '100%' }} pagination={false} columns={columns} dataSource={data} />
Seems like it's more of a CSS issue within Ant then a bug. it's a browser limitation.
Try working with vh units mixed with calc:
Example:
scroll={{ y: 'calc(100vh - 4em)' }}
Related Github discussion (require tranlation)
Instead of setting scroll={{ y: '100%' }}, set a number. Because scroll y only takes a number where scroll x takes a number or boolean.