首页 > 解决方案 > 如何围绕自己的中心旋转 SVG 对象?

问题描述

我正在制作一个 SVG 动画,其中两个齿轮(SVG 对象)应该围绕它们的中心无限次连续旋转。我在堆栈溢出时为这些问题找到了很多答案,但这些都没有解决我的问题。

我曾尝试使用 CSS 动画来旋转它,但它不会围绕自己的中心旋转。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   id="svg8"
   version="1.1"
   viewBox="0 0 151.07708 104.24584"
   height="394"
   width="571">
    <g
        transform="translate(2.1166667,-0.52916663)" id="BlueBigMiddleGear" style="display:inline;opacity:1;">
      <path style="opacity:1;fill:#00a2a2;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;" d="m 18.56808,26.571725 c 3.275987,0.593468 5.566928,-3.837863 3.354539,-5.905877 2.060394,-2.103327 4.554573,-3.44753 7.370537,-4.228609 3.039988,3.951776 5.072643,2.096573 7.063427,0 2.964733,0.684319 5.126395,2.38586 7.157927,4.252232 -1.375995,3.387617 -0.456277,5.532848 3.519902,6.023994 0.978251,2.764264 0.950956,5.496092 -0.02363,8.197361 -3.529105,0.674199 -4.86411,2.602169 -3.543527,6.047618 -2.020934,1.811043 -4.052787,3.610561 -7.181546,4.252233 -2.285064,-2.600365 -4.628765,-2.737974 -7.039808,-0.04725 -2.530906,-0.889292 -5.092152,-1.679982 -7.1343,-4.157739 1.350522,-2.998678 0.192879,-5.025441 -3.496279,-6.071243 -0.882856,-2.787573 -0.865144,-5.575147 -0.04724,-8.36272 z" id="path1423" />
      <ellipse style="opacity:1;fill:#00a2a2;fill-opacity:1;stroke:#ffffff;stroke-width:8.47981644;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;" id="path1430" cx="32.735146" cy="30.88035" rx="4.403945" ry="4.2703118" />
    </g> 
    <g transform="rotate(-6.5973029,34.401484,29.663413);" style="display:inline" id="Gear"  class="Gear" >
      <path style="opacity:1;fill:#d14330;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 44.553944,39.635527 c 0.759184,-2.153091 2.305531,-2.691365 3.897878,-3.165549 2.004141,1.775246 3.092697,0.749881 4.039622,-0.708707 2.071027,0.07811 3.438224,0.805907 4.701076,1.630024 -0.458034,1.912119 -0.200249,3.386793 2.716705,3.23642 0.666429,1.622148 1.272712,3.244296 0.826823,4.866444 -1.948655,0.784004 -2.499529,2.043252 -1.299292,3.897879 -1.018053,1.3543 -2.242948,2.455793 -3.82701,3.118305 -1.827113,-1.587302 -3.075307,-0.903465 -4.086868,0.708705 -1.440932,0.07133 -3.008161,-0.425679 -4.701077,-1.488282 0.426697,-2.797344 -0.9364,-3.293526 -2.693082,-3.283669 -0.933271,-1.379303 -1.4003,-2.914021 -0.826823,-4.795573 1.91108,-0.754162 2.238206,-2.128133 1.252048,-4.015997 z" id="path1438" />
      <circle style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:9.71524143;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" id="path1441" cx="51.99535" cy="44.62009" r="2.5277159" />
    </g>
    </svg>
 </div>
<style>
 .Gear {
  animation: rotate 3s infinite;
 }
 @keyframes rotate{
    from{
       transform: rotate(0deg);}to{
       transform: rotate(360deg);
    }
 }
</style>

我希望 SVG 对象围绕自己的中心旋转而不改变其位置。

标签: animationsvg

解决方案


正如我所评论的,您需要添加.Gear { animation: rotate 3s infinite; transform-origin: 50% 50%; transform-box: fill-box; }到 CSS 中。

 .Gear {
  animation: rotate 3s infinite;
   transform-origin: 50% 50%;
   transform-box: fill-box;
 }
 @keyframes rotate{
    from{
       transform: rotate(0deg);}to{
       transform: rotate(360deg);
    }
 }
<svg
   id="svg8"
   version="1.1"
   viewBox="0 0 151.07708 104.24584"
   height="394"
   width="571">
    <g
        transform="translate(2.1166667,-0.52916663)" id="BlueBigMiddleGear" style="display:inline;opacity:1;">
      <path style="opacity:1;fill:#00a2a2;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;" d="m 18.56808,26.571725 c 3.275987,0.593468 5.566928,-3.837863 3.354539,-5.905877 2.060394,-2.103327 4.554573,-3.44753 7.370537,-4.228609 3.039988,3.951776 5.072643,2.096573 7.063427,0 2.964733,0.684319 5.126395,2.38586 7.157927,4.252232 -1.375995,3.387617 -0.456277,5.532848 3.519902,6.023994 0.978251,2.764264 0.950956,5.496092 -0.02363,8.197361 -3.529105,0.674199 -4.86411,2.602169 -3.543527,6.047618 -2.020934,1.811043 -4.052787,3.610561 -7.181546,4.252233 -2.285064,-2.600365 -4.628765,-2.737974 -7.039808,-0.04725 -2.530906,-0.889292 -5.092152,-1.679982 -7.1343,-4.157739 1.350522,-2.998678 0.192879,-5.025441 -3.496279,-6.071243 -0.882856,-2.787573 -0.865144,-5.575147 -0.04724,-8.36272 z" id="path1423" />
      <ellipse style="opacity:1;fill:#00a2a2;fill-opacity:1;stroke:#ffffff;stroke-width:8.47981644;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;" id="path1430" cx="32.735146" cy="30.88035" rx="4.403945" ry="4.2703118" />
    </g> 
    <g transform="rotate(-6.5973029,34.401484,29.663413);" style="display:inline" id="Gear"  class="Gear" >
      <path style="opacity:1;fill:#d14330;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 44.553944,39.635527 c 0.759184,-2.153091 2.305531,-2.691365 3.897878,-3.165549 2.004141,1.775246 3.092697,0.749881 4.039622,-0.708707 2.071027,0.07811 3.438224,0.805907 4.701076,1.630024 -0.458034,1.912119 -0.200249,3.386793 2.716705,3.23642 0.666429,1.622148 1.272712,3.244296 0.826823,4.866444 -1.948655,0.784004 -2.499529,2.043252 -1.299292,3.897879 -1.018053,1.3543 -2.242948,2.455793 -3.82701,3.118305 -1.827113,-1.587302 -3.075307,-0.903465 -4.086868,0.708705 -1.440932,0.07133 -3.008161,-0.425679 -4.701077,-1.488282 0.426697,-2.797344 -0.9364,-3.293526 -2.693082,-3.283669 -0.933271,-1.379303 -1.4003,-2.914021 -0.826823,-4.795573 1.91108,-0.754162 2.238206,-2.128133 1.252048,-4.015997 z" id="path1438" />
      <circle style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:9.71524143;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" id="path1441" cx="51.99535" cy="44.62009" r="2.5277159" />
    </g>
    </svg>

或者,您可以使用:

.Gear {
      animation: rotate 3s infinite;
      transform-origin: 51.9688975px 44.49px;
     }
     @keyframes rotate{
        from{
           transform: rotate(0deg);}to{
           transform: rotate(360deg);
        }
     }

51.9688975px 44.49px齿轮的中心在哪里。

为了找到 Gear 的中心,您需要知道 Gear 边界框的大小和位置。

let bb = Gear.getBBox()

这将返回如下内容:

 bb =  {
    height: 17.464492797851562
    width: 17.83779525756836
    x: 43.05119705200195
    y: 35.76127243041992
    }

接下来你可以计算齿轮的中心:

let center = {}
center.x = bb.x + bb.width/2
center.y = bb.y + bb.height/2

这是一个例子:

let bb = Gear.getBBox()
let c = {};
c.x = bb.x + bb.width/2;
c.y = bb.y + bb.height/2;
Gear.setAttribute("style",`transform-origin:${c.x}px ${c.y}px` )
.Gear {
  animation: rotate 3s infinite;
  
 }
 @keyframes rotate{
    from{
       transform: rotate(0deg);}to{
       transform: rotate(360deg);
    }
 }
<svg
   id="svg8"
   version="1.1"
   viewBox="0 0 151.07708 104.24584"
   height="394"
   width="571">
    <g
        transform="translate(2.1166667,-0.52916663)" id="BlueBigMiddleGear" style="display:inline;opacity:1;">
      <path style="opacity:1;fill:#00a2a2;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;" d="m 18.56808,26.571725 c 3.275987,0.593468 5.566928,-3.837863 3.354539,-5.905877 2.060394,-2.103327 4.554573,-3.44753 7.370537,-4.228609 3.039988,3.951776 5.072643,2.096573 7.063427,0 2.964733,0.684319 5.126395,2.38586 7.157927,4.252232 -1.375995,3.387617 -0.456277,5.532848 3.519902,6.023994 0.978251,2.764264 0.950956,5.496092 -0.02363,8.197361 -3.529105,0.674199 -4.86411,2.602169 -3.543527,6.047618 -2.020934,1.811043 -4.052787,3.610561 -7.181546,4.252233 -2.285064,-2.600365 -4.628765,-2.737974 -7.039808,-0.04725 -2.530906,-0.889292 -5.092152,-1.679982 -7.1343,-4.157739 1.350522,-2.998678 0.192879,-5.025441 -3.496279,-6.071243 -0.882856,-2.787573 -0.865144,-5.575147 -0.04724,-8.36272 z" id="path1423" />
      <ellipse style="opacity:1;fill:#00a2a2;fill-opacity:1;stroke:#ffffff;stroke-width:8.47981644;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;" id="path1430" cx="32.735146" cy="30.88035" rx="4.403945" ry="4.2703118" />
    </g> 
    <g transform="rotate(-6.5973029,34.401484,29.663413);" style="display:inline" id="Gear"  class="Gear" >
      <path style="opacity:1;fill:#d14330;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 44.553944,39.635527 c 0.759184,-2.153091 2.305531,-2.691365 3.897878,-3.165549 2.004141,1.775246 3.092697,0.749881 4.039622,-0.708707 2.071027,0.07811 3.438224,0.805907 4.701076,1.630024 -0.458034,1.912119 -0.200249,3.386793 2.716705,3.23642 0.666429,1.622148 1.272712,3.244296 0.826823,4.866444 -1.948655,0.784004 -2.499529,2.043252 -1.299292,3.897879 -1.018053,1.3543 -2.242948,2.455793 -3.82701,3.118305 -1.827113,-1.587302 -3.075307,-0.903465 -4.086868,0.708705 -1.440932,0.07133 -3.008161,-0.425679 -4.701077,-1.488282 0.426697,-2.797344 -0.9364,-3.293526 -2.693082,-3.283669 -0.933271,-1.379303 -1.4003,-2.914021 -0.826823,-4.795573 1.91108,-0.754162 2.238206,-2.128133 1.252048,-4.015997 z" id="path1438" />
      <circle style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:9.71524143;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" id="path1441" cx="51.99535" cy="44.62009" r="2.5277159" />
    </g>
    </svg>


推荐阅读