如何使用CSS关键帧移动SVG组?

时间:2019-10-08 14:09:41

标签: html css svg

我想使用CSS关键帧在容器中移动SVG元素。

如果我只有<circle />,则可以在关键帧定义中简单地使用cx / cy属性。但是,如果我有一个任意组(<g />),该怎么办?群组没有cx / cy,并且如果要使用CSS'px,似乎必须定义一个单位(例如transform: translate(x,y))。 / p>

MWE(如何为bar组设置动画?)

svg {
padding: 5px;
width: 150px;
height: 150px;
border: 1px solid #000;
}

.foo {
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: moveFoo;
}

.bar {
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: moveBar;
}

@keyframes moveFoo {
from {
cx: 10;
cy: 10;
}
to {
cx: 90;
cy: 90;
}
}

/* how to define this? */
@keyframes moveBar { }
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle class="foo" r="5" fill="red" />
<g class="bar" transform="translate(90 10)">
    <circle r="5" fill="blue" />
    <text
        y="1"
        text-anchor="middle"
        fill="white"
        font-family="monospace"
        font-size="5">
    AB
</text>
</g>
</svg>

3 个答案:

答案 0 :(得分:3)

使用animateTransform执行此操作:

svg {
  padding: 5px;
  width: 150px;
  height: 150px;
  border: 1px solid #000;
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle class="foo" r="5" fill="red" />
<g id="bar" transform="translate(90 10)">

    <circle r="5" fill="blue" />
    <text
        y="1"
        text-anchor="middle"
        fill="white"
        font-family="monospace"
        font-size="5">
    AB
</text>
</g>
<animateTransform xlink:href="#bar" 
    attributeName="transform" 
    type="translate"
    from="90,10" to="90,90"
    dur="2" repeatCount="indefinite"/>
</svg>

答案 1 :(得分:2)

  

如果要使用,似乎必须定义一个单位(如px)   CSS转换:translate(x,y)。

是的,确实如此。

但是,如果您已经在viewbox元素中声明了<svg>属性,那将不是问题。

如果您声明了viewbox,则1px将代表1个视图框单元。

工作示例:

svg {
padding: 5px;
width: 150px;
height: 150px;
border: 1px solid #000;
}

.foo {
fill: red;
transform: translate(10px, 10px);
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: moveFoo;
}

.bar {
transform: translate(90px, 10px);
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: moveBar;
}

.bar circle {
fill: blue;
}

.bar text {
fill: white;
font-family: monospace;
font-size: 5px;
text-anchor: middle;
}

@keyframes moveFoo {
   0% {transform: translate(10px, 10px);}
  50% {transform: translate(90px, 90px);}
 100% {transform: translate(10px, 10px);}
}

@keyframes moveBar {
   0% {transform: translate(90px, 10px);}
  50% {transform: translate(10px, 90px);}
 100% {transform: translate(90px, 10px);}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">

<circle class="foo" r="5" />

<g class="bar">
  <circle r="5" />
  <text y="1">AB</text>
</g>

</svg>

答案 2 :(得分:1)

例如,如果您需要使用@keyframes而不是设置cx和cy属性的动画,则必须从transform:translate(0,0)transform:translate(90px,90px)进行动画处理。

否则,Temani Afif的答案是完全正确的。 `

svg {
padding: 5px;
width: 150px;
height: 150px;
border: 1px solid #000;
}

.foo {
transform:translate(0,0);
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: moveFoo;
}

.bar {
transform:translate(0,0);
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: moveBar;
}



@keyframes moveFoo {
from {
transform:translate(0,0)
}
to {
transform:translate(90px,90px)
}
}

/* how to define this? */
@keyframes moveBar { 
from {
transform:translate(0,0)
}
to {
transform:translate(90px,90px)
}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle class="foo" r="5" fill="red" />
<g class="bar" >
    <circle r="5" fill="blue" cx="10" cy="10" />
    <text
        x="10"
        y="11"
        text-anchor="middle"
        fill="white"
        font-family="monospace"
        font-size="5">
  AB
</text>
</g>
</svg>