I have an svg with a few elements that looks something like this:
I would like to create an animation where each element "pulses" (grows about 20% in size and then returns to its normal size without moving to a different position) one after the other, going around in a circle on repeat.
I began creating a css animation for this but my attempts to add a scale animation clearly were not using the correct center point because every scaling movement would shift that element to a different position as well.
I tried exploring different values for the property transform-origin, but none seemed to achieve the desired behaviour.
I have included a demo reprex that shows the behaviour:
#Ellipse_1 {
/* No transform-origin */
animation: pulse 2s linear infinite alternate;
animation-delay: 2.6s fill-opacity: 50%;
}
#Ellipse_2 {
/* transform-origin same as circle's center location */
transform-origin: 4 8;
fill-opacity: 50%;
animation: pulse 2s linear infinite alternate;
animation-delay: 3.4s
}
#Ellipse_3 {
/* Trying transform-origin center center keyword */
transform-origin: center center;
fill-opacity: 50%;
animation: pulse 2s linear infinite alternate;
animation-delay: 3s
}
#Path_1 {
/* Trying transform-origin center keyword */
transform-origin: center;
animation: pulse 2s linear infinite alternate;
animation-delay: 4s
}
#Path_2 {
/* This goes off screen as soon as animation starts */
animation: pulse 2s linear infinite alternate;
animation-delay: 4s
}
@keyframes pulse {
0% {
transform: scale(1);
-ms-transform: scale(1);
-webkit-transform: scale(1);
}
100% {
transform: scale(2);
-ms-transform: scale(2);
-webkit-transform: scale(2);
}
}
<svg id="shapes" data-name="shapes data" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-10 -10 100 100">
<circle id="Ellipse_1" data-name="Ellipse 1" cx="2.083" cy="2.083" r="2.083" transform="translate(14 3)" fill="red"/>
<path id="Path_1" data-name="Path 259" d="M60.749,74.282a103.267,103.267,0,0,0-5.686,23.5.459.459,0,0,1-.455.408H48.887a.46.46,0,0,1-.453-.38l-3.1-17.357a.458.458,0,0,1,.321-.519A75.754,75.754,0,0,0,60.24,73.846C60.708,73.591,60.936,73.783,60.749,74.282Z" transform="translate(-45.326 -63.944)" fill-rule="evenodd" fill="green"/>
<circle id="Ellipse_2" data-name="Ellipse 2" cx="2.083" cy="2.083" r="2.083" transform="translate(4 8)" fill="blue"/>
<circle id="Ellipse_3" data-name="Ellipse 3" cx="1.62" cy="1.62" r="1.62" transform="translate(21.942)" fill="green"/>
<path id="Path_2" data-name="Path 2" d="M97.486,54.462C94.879,58.549,90.751,66.907,88.6,81.11a.6.6,0,0,1-.572.505,16.478,16.478,0,0,0-8.995,3.049.355.355,0,0,1-.562-.322,90.68,90.68,0,0,1,6.77-25.419.966.966,0,0,1,.352-.4q1.521-.866,3.1-1.629a.016.016,0,0,1,.009,0,50.611,50.611,0,0,1,8.261-3.124h0A.465.465,0,0,1,97.486,54.462Z" transform="translate(-66.545 -51.149)" fill-rule="evenodd" fill="red"/>
</svg>
CodePudding user response:
When you "overwrite" the transform
using CSS the translate
is removed. Here I moved the transform/translate to a parent <g>
. So each element is moved using the transform in <g>
and then each element is scaled using CSS.
The circles are easy to scale because their origin is in the center already, but the other shapes need either to be moved so that 0,0 is in the center (change all values in the d attribute) or use transform-origin
to move the origin. I guess that the result here is a combination - that could be optimized (up to you :-)).
#Ellipse_1 {
/* No transform-origin */
animation: pulse 2s linear infinite alternate;
animation-delay: 2.6s fill-opacity: 50%;
}
#Ellipse_2 {
/* transform-origin same as circle's center location */
fill-opacity: 50%;
animation: pulse 2s linear infinite alternate;
animation-delay: 3.4s
}
#Ellipse_3 {
/* Trying transform-origin center center keyword */
fill-opacity: 50%;
animation: pulse 2s linear infinite alternate;
animation-delay: 3s
}
#Path_1 {
/* Trying transform-origin center keyword */
transform-origin: 50px 80px;
animation: pulse 2s linear infinite alternate;
animation-delay: 4s
}
#Path_2 {
/* This goes off screen as soon as animation starts */
transform-origin: 80px 70px;
animation: pulse 2s linear infinite alternate;
animation-delay: 4s
}
@keyframes pulse {
0% {
transform: scale(1);
-ms-transform: scale(1);
-webkit-transform: scale(1);
}
100% {
transform: scale(1.2);
-ms-transform: scale(1.2);
-webkit-transform: scale(1.2);
}
}
<svg id="shapes" data-name="shapes data" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<g transform="translate(14 3)">
<circle id="Ellipse_1" data-name="Ellipse 1" cx="2.083" cy="2.083" r="2.083" fill="red"/>
</g>
<g transform="translate(-45.326 -63.944)">
<path id="Path_1" data-name="Path 259" d="M60.749,74.282a103.267,103.267,0,0,0-5.686,23.5.459.459,0,0,1-.455.408H48.887a.46.46,0,0,1-.453-.38l-3.1-17.357a.458.458,0,0,1,.321-.519A75.754,75.754,0,0,0,60.24,73.846C60.708,73.591,60.936,73.783,60.749,74.282Z" fill-rule="evenodd" fill="green"/>
</g>
<g transform="translate(4 10)">
<circle id="Ellipse_2" data-name="Ellipse 2" r="2.083" fill="blue"/>
</g>
<g transform="translate(22 3)">
<circle id="Ellipse_3" data-name="Ellipse 3" r="1.62" fill="green"/>
</g>
<g transform="translate(-66.545 -51.149)">
<path id="Path_2" data-name="Path 2" d="M97.486,54.462C94.879,58.549,90.751,66.907,88.6,81.11a.6.6,0,0,1-.572.505,16.478,16.478,0,0,0-8.995,3.049.355.355,0,0,1-.562-.322,90.68,90.68,0,0,1,6.77-25.419.966.966,0,0,1,.352-.4q1.521-.866,3.1-1.629a.016.016,0,0,1,.009,0,50.611,50.611,0,0,1,8.261-3.124h0A.465.465,0,0,1,97.486,54.462Z" fill-rule="evenodd" fill="red"/>
</g>
</svg>