如何为 svg 中的(路径)元素设置动画以在不视觉移动位置的情况下放大和缩小
How to animate a (path) element inside an svg to scale larger and smaller without moving position visually
我有一个带有一些元素的 svg,看起来像这样:
我想创建一个动画,其中每个元素“脉动”(大小增长约 20%,然后 returns 恢复到正常大小而不移动到不同的位置)一个接一个地循环在循环中重复。
我开始为此创建一个 css 动画,但我尝试添加缩放动画显然没有使用正确的中心点,因为每次缩放移动也会将该元素移动到不同的位置。
我尝试探索 属性 变换原点的不同值,但 none 似乎达到了预期的效果。
我已经包含了一个演示行为的演示 reprex:
#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>
当您使用 CSS“覆盖”transform
时,translate
将被删除。在这里,我将 transform/translate 移到了父级 <g>
。因此每个元素都使用 <g>
中的变换移动,然后使用 CSS.
缩放每个元素
圆圈很容易缩放,因为它们的原点已经位于中心,但其他形状需要移动以便 0,0 位于中心(更改 d 属性中的所有值)或使用 transform-origin
移动原点。我想这里的结果是一个组合 - 可以优化(由你决定:-))。
#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>
我有一个带有一些元素的 svg,看起来像这样:
我想创建一个动画,其中每个元素“脉动”(大小增长约 20%,然后 returns 恢复到正常大小而不移动到不同的位置)一个接一个地循环在循环中重复。
我开始为此创建一个 css 动画,但我尝试添加缩放动画显然没有使用正确的中心点,因为每次缩放移动也会将该元素移动到不同的位置。
我尝试探索 属性 变换原点的不同值,但 none 似乎达到了预期的效果。
我已经包含了一个演示行为的演示 reprex:
#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>
当您使用 CSS“覆盖”transform
时,translate
将被删除。在这里,我将 transform/translate 移到了父级 <g>
。因此每个元素都使用 <g>
中的变换移动,然后使用 CSS.
圆圈很容易缩放,因为它们的原点已经位于中心,但其他形状需要移动以便 0,0 位于中心(更改 d 属性中的所有值)或使用 transform-origin
移动原点。我想这里的结果是一个组合 - 可以优化(由你决定:-))。
#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>