Reputation: 15
So I'm pretty new to svg css animation, and I'm trying to morph three paths (all very curved, thus the cubic bezier route) into three rectangle. I've got it working, but during the transition parts of it skew inward in a weird way (see CodePen below). The top right, middle, and bottom left are about what I expect to see, but the top left and bottom right are the wtf areas. Is there a way to set the curves so that this effect doesn't happen, or it this just a side effect of the method chosen. If it is, is there a better way to do what I'm doing so that the transition looks smooth?
svg {
height: 150px;
cursor: pointer;
}
svg path {
transition: d 1s ease;
}
svg:hover .top {
d: path('M 1280,256 C 2560,256 2560,256 2560,256 C 2560,768 2560,768 2560,768 C 1280,768 1280,768 1280,768 C 0,768 0,768 0,768 C 0,256 0,256 0,256 C 1280,256 1280,256 1280,256');
}
svg:hover .middle {
d: path('M 1280,1024 C 2560,1024 2560,1024 2560,1024 C 2560,1280 2560,1280 2560,1280 C 2560,1536 2560,1536 2560,1536 C 1280,1536 1280,1536 1280,1536 C 0,1536 0,1536 0,1536 C 0,1280 0,1280 0,1280 C 0,1024 0,1024 0,1024 C 1280,1024 1280,1024 1280,1024');
}
svg:hover .bottom {
d: path('M 1280,1792 C 2560,1792 2560,1792 2560,1792 C 2560,2304 2560,2304 2560,2304 C 1280,2304 1280,2304 1280,2304 C 0,2304 0,2304 0,2304 C 0,1792 0,1792 0,1792 C 1280,1792 1280,1792 1280,1792');
}
<!DOCTYPE html>
<html>
<body>
<svg viewBox="0 0 2560 2560">
<path class="top" d="
M 1280,0
C 1986.92447978368,0 2489.165,505 2553.665,1152
C 2553.665,1152 2041.665,1152 2041.665,1152
C 1976.434,789.00439808 1704.154687870208,512 1280,512
C 855.8453121297921,512 583.566,789.00439808 518.335,1152
C 518.335,1152 6.335,1152 6.335,1152
C 70.835,505 573.07552021632,0 1280,0
" />
<path class="middle" d="
M 1280,768
C 1562.769791913472,768 1792,997.230208086528 1792,1280
C 1792,1280 1792,1280 1792,1280
C 1792,1562.769791913472 1562.769791913472,1792 1280,1792
C 1280,1792 1280,1792 1280,1792
C 997.230208086528,1792 768,1562.769791913472 768,1280
C 768,1280 768,1280 768,1280
C 768,997.230208086528 997.230208086528,768 1280,768
C 1280,768 1280,768 1280,768
" />
<path class="bottom" d="
M 1280,2048
C 1704.154687870208,2048 1976.434,1770.99560192 2041.665,1408
C 2041.665,1408 2553.665,1408 2553.665,1408
C 2489.165,2055 1986.92447978368,2560 1280,2560
C 573.07552021632,2560 70.835,2055 6.335,1408
C 6.335,1408 518.335,1408 518.335,1408
C 583.566,1770.99560192 855.8453121297921,2048 1280,2048
" />
</svg>
</body>
</html>
CodePen (Tested in Chrome.)
Upvotes: 0
Views: 338
Reputation: 101820
I am pretty sure it is just a combination of the following things:
You have chosen to set both control points to be the same as the curve endpoint
C ... ... 1280,256
C 2560,256 2560,256 2560,256
As the curve is being linear interpolated, it results in some curves bulging outwards and some bulging inwards. Depending on the path direction and whether you are on the inside or outside of the curve.
You will get much better results by doing your control points a different way. Either:
In the following example I have chosen the second method (because it was quicker and easier here). It produces a better result.
C ... ... 1280,256
C 1280,256 2560,256 2560,256
svg {
height: 150px;
cursor: pointer;
}
svg path {
transition: d 1s ease;
}
svg:hover .top {
d: path('M 1280,256 C 1280,256 2560,256 2560,256 C 2560,256 2560,768 2560,768 C 2560,768 1280,768 1280,768 C 1280,768 0,768 0,768 C 0,768 0,256 0,256 C 0,256 1280,256 1280,256');
}
<svg viewBox="0 0 2560 2560">
<path class="top" d="
M 1280,0
C 1986.92447978368,0 2489.165,505 2553.665,1152
C 2553.665,1152 2041.665,1152 2041.665,1152
C 1976.434,789.00439808 1704.154687870208,512 1280,512
C 855.8453121297921,512 583.566,789.00439808 518.335,1152
C 518.335,1152 6.335,1152 6.335,1152
C 70.835,505 573.07552021632,0 1280,0
" />
</svg>
PS. Be aware that CSS animation of the d
attribute is not yet supported in all browsers. It is just the Webkit based browsers, like Chrome, right now.
Upvotes: 1