围绕旋转物体旋转

Rotate around rotating object

我想制作太阳系的svg动画。我已经设法编写了大部分内容,但我被困在绕地球旋转的月球上。任何想法如何使它工作?

<svg viewBox="0 0 500 500">
    <!-- sun -->
    <circle cx="250" cy="250" r="30" style="stroke: none; fill:
    #fffb00;"></circle>
    
    <!-- earth -->
    <circle cx="170" cy="170" r="12" style="stroke: none; fill:
    #040e9e;">
        <animateTransform attributeName="transform" type="rotate" from="0
        250 250" to="360 250 250" `scale(1 1)` begin="0s" dur="7s" repeatCount="indefinite" />
    </circle>
    
    <!-- moon -->
    <circle cx="157" cy="157" r="3" style="stroke: none; fill:
    #040e9e;">
        <animateTransform attributeName="transform" type="rotate" from="0
        170 170" to="360 250 250" begin="0s" dur="10s" repeatCount="indefinite" />
    </circle>
</svg>

https://jsfiddle.net/txuovbgr/

您将地球和月亮放在一个组中,然后对组和月亮进行动画转换

<svg viewBox="0 0 500 500">
  <!-- sun -->
  <circle cx="250" cy="250" r="30" style="stroke: none; fill:
    #fffb00;"></circle>

 
  <g>
     <!-- earth -->
    <circle cx="170" cy="170" r="12" style="stroke: none; fill:
    #040e9e;">
    </circle>

    <!-- moon -->
    <circle cx="157" cy="157" r="3" style="stroke: none; fill:
    red">
      <animateTransform attributeName="transform" type="rotate" from="0 170 170" to="360 170 170" begin="0s" dur="10s" repeatCount="indefinite" />
    </circle>

    <animateTransform attributeName="transform" type="rotate" from="0 250 250" to="360 250 250" scale(1 1) begin="0s" dur="7s" repeatCount="indefinite" />
  </g>

</svg>

您需要将 earthmoon 合并为一组并围绕太阳旋转该组。

在此组中,moon 将在其目录中轮换

<g id="earth">
        <circle cx="170" cy="170" r="12" style="stroke: none; 
          fill: green;">
        </circle>

        <!-- moon -->
        <circle id="moon" cx="185" cy="185" r="3" style="stroke: none; 
           fill:red">   
        <!-- Within this group, the moon will rotate in its directory -->
            <animateTransform attributeName="transform" type="rotate" from="0
            170 170" to="360 170 170" begin="0s" dur="10s" repeatCount="indefinite" />
        </circle> 
         
   </g>   
        <!-- Group rotation -->
     <animateTransform  xlink:href="#earth" attributeName="transform" type="rotate" from="0
            250 250" to="360 250 250"  begin="0s" dur="7s" repeatCount="indefinite" />

<!doctype html>
<html class="no-js" lang="">

<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        html,
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
            /* background: url('./bg.png'); */
        }

        svg {
            position: fixed;
            top: 0;
            left: 0;
            height: 100%;
            width: 100%;
        }
    </style>
</head>

<body>
    <svg viewBox="0 0 500 500">

        <!-- sun -->
        <circle cx="250" cy="250" r="30" style="stroke: none; fill:
        #fffb00;"></circle>

        <!-- mercury -->
        <circle cx="215" cy="215" r="8" style="stroke: none; fill:
        #502d05;">
            <animateTransform attributeName="transform" type="rotate" from="0
            250 250" to="360 250 250" begin="0s" dur="1.7s" repeatCount="indefinite" />
        </circle>

        <!-- venus -->
        <circle cx="195" cy="195" r="10" style="stroke: none; fill:
        #eb9b40;">
            <animateTransform attributeName="transform" type="rotate" from="0
            250 250" to="360 250 250" ) begin="0s" dur="4s" repeatCount="indefinite" />
        </circle>

        <!-- earth -->
    <g id="earth">
        <circle cx="170" cy="170" r="12" style="stroke: none; fill: skyblue;">
           
        </circle>

        <!-- moon -->
        <circle id="moon" cx="185" cy="185" r="5" style="stroke: none; fill:#FFD417">
            <animateTransform attributeName="transform" type="rotate" from="0
            170 170" to="360 170 170" begin="0s" dur="10s" repeatCount="indefinite" />
        </circle> 
         
   </g> 
     <animateTransform  xlink:href="#earth" attributeName="transform" type="rotate" from="0
            250 250" to="360 250 250"  begin="0s" dur="7s" repeatCount="indefinite" />
        <!-- mars -->
        <circle cx="145" cy="145" r="11" style="stroke: none; fill:
        #af0404;">
            <animateTransform attributeName="transform" type="rotate" from="0
            250 250" to="360 250 250" begin="0s" dur="12s" repeatCount="indefinite" />
        </circle>

        <!-- jupiter -->
        <circle cx="110" cy="110" r="16" style="stroke: none; fill:
         #291702;">
            <animateTransform attributeName="transform" type="rotate" from="0
             250 250" to="360 250 250" begin="0s" dur="70s" repeatCount="indefinite" />
        </circle>
    </svg>
</body>

</html>

作为奖励

这是我的 answer

太阳系的动画会在点击start按钮后开始播放

var zodiac = new Audio();
zodiac.src = 'https://svg-art.ru/files/zodiac.mp3';

function play() {
  zodiac.play();
}
.solar-system{
  background-color:#002;
  width:100%;
  height:100%;
 
}
.sun{
  
  fill:url(#gradSun);
  filter:url(#dropShadow2);
  
 }
.mercury-orbit{
  stroke:  rgba(255,255,255,.4);
  stroke-width:1;
  fill:none;
  }
.mercury{
   fill:url(#gradMercury);
   filter:url(#dropShadow1);
 }
 .venus-orbit{
  stroke:rgba(255,255,255,.4);
  stroke-width:1;
  fill:none;
  }
.venus{
   fill:url(#gradVenus);
   filter:url(#dropShadow1);
   
 }
 
 .Earth-orbit{
  stroke:rgba(255,255,255,.4);
    stroke-width:1;
  fill:none;
  }
.Earth{
   filter:url(#dropShadow1);
   fill:url(#gradEarth);
 }
 .Mars-orbit{
  stroke:rgba(255,255,255,.4);
    stroke-width:1;
  fill:none;
  }
.Mars{
   filter:url(#dropShadow1);
   fill:url(#gradMars);
 } 
 
 .Jupiter-orbit{
  stroke:rgba(255,255,255,.4);
    stroke-width:1;
  fill:none;
  }
.Jupiter{
   filter:url(#dropShadow1);
   fill:url(#gradJupiter);
 }
<div class="solar-system">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
      viewBox="0 0 500 400" > 
  
  <defs>
    <filter id="dropShadow1" 
        x="-20%" y="-20%" 
        width="150%" height="150%"
    >
     <feGaussianBlur   stdDeviation="1" />
    </filter>
     <filter id="dropShadow2" 
        x="-20%" y="-20%" 
        width="150%" height="150%">
        <feGaussianBlur   stdDeviation="4" />
     </filter>
      <radialGradient id="gradSun">
        <stop offset="80%" stop-color="yellow">
         <animate attributeName="offset" values="80%;20%;80%" dur="12s" repeatCount="indefinite" />
         </stop>
        <stop offset="100%" stop-color="gold" >
        <animate attributeName="stop-color" values="gold;red;gold" dur="6s" repeatCount="indefinite" />
        </stop>
      </radialGradient>
        <linearGradient id="gradEarth">
            <stop offset="40%" stop-color="dodgerblue"></stop>
            <stop offset="100%" stop-color="yellowgreen" ></stop>
        </linearGradient>
    <linearGradient id="gradMercury"> 
        <stop offset="20%" stop-color="#824549"></stop>
        <stop offset="20%" stop-color="#956356"></stop>  
        <stop offset="80%" stop-color="#5F3631" ></stop>
        <stop offset="100%" stop-color="#807019" ></stop>
    </linearGradient>
      <linearGradient id="gradVenus">
        <stop offset="40%" stop-color="#805050"></stop>
        <stop offset="100%" stop-color="yellow" ></stop>
      </linearGradient>
      
        <linearGradient id="gradMars">
        <stop offset="40%" stop-color="crimson"></stop>
        <stop offset="100%" stop-color="yellow" ></stop>
    </linearGradient>  
        <linearGradient id="gradJupiter">
        <stop offset="10%" stop-color="#AE5D49"></stop>
        <stop offset="10%" stop-color="#783632" ></stop>
        <stop offset="20%" stop-color="#C58460" ></stop>
        <stop offset="20%" stop-color="#866D65" ></stop>
        <stop offset="30%" stop-color="#995645" ></stop>
        <stop offset="30%" stop-color="#C58460" ></stop>
        <stop offset="40%" stop-color="#AE5D49" ></stop>
        <stop offset="40%" stop-color="#C58460" ></stop>
        <stop offset="50%" stop-color="#AE5D49"></stop>
        <stop offset="50%" stop-color="#783632" ></stop>
        <stop offset="60%" stop-color="#C58460" ></stop>
        <stop offset="60%" stop-color="#866D65" ></stop> 
        <stop offset="70%" stop-color="#995645" ></stop>
        <stop offset="70%" stop-color="#C58460" ></stop>
        <stop offset="80%" stop-color="#AE5D49" ></stop>
        <stop offset="80%" stop-color="#943A31" ></stop>
        
    </linearGradient>  

      
  </defs>
 
 <g id="btn1" onclick='play()' >
     <circle  cx="30" cy="45" r="8" fill="url(#gradEarth)" filter="url(#dropShadow1)" /> 
     <text id="txt1" x="15" y="70" font-size="1rem" fill="gold" >Start</text>
 </g>
 <!-- mercury -->
  <g>
  <animateTransform 
      attributeName="transform" 
      type="rotate"
      begin="btn1.click"      
      values="0 250 175;360 250 175" 
      dur="8s"
      repeatCount="indefinite"
  />
 <circle class="mercury-orbit" cx="250" cy="175" r="40"   />
 <circle class="mercury" cx="210" cy="175" r="6"  />
</g> 
   <!-- venus -->
   <g>
  <animateTransform 
      attributeName="transform" 
      type="rotate"
      begin="btn1.click"
      values="0 250 175;360 250 175" 
      dur="10s"
      repeatCount="indefinite"
  />
 <circle class="venus-orbit" cx="250" cy="175" r="60"     />
 <circle class="venus" transform="rotate(-45 250 175)" cx="190" cy="175" r="10"   />
</g> 
 <!-- Earth -->
   <g>
  <animateTransform 
      attributeName="transform" 
      type="rotate"
      begin="btn1.click"      
      values="0 250 175;360 250 175" 
      dur="12s"
      repeatCount="indefinite"
  />
 <circle class="Earth-orbit" cx="250" cy="175" r="90"     />
 <circle class="Earth" cx="160" cy="175" r="10" transform="rotate(45 250 175)"  />
</g>
    <!-- Mars -->
  <g>
  <animateTransform 
      attributeName="transform" 
      type="rotate"
      begin="btn1.click"      
      values="0 250 175;360 250 175" 
      dur="14s"
      repeatCount="indefinite"
  />
 <circle class="Mars-orbit" cx="250" cy="175" r="120"     />
 <circle class="Mars" cx="130" cy="175" r="8" transform="rotate(90 250 175)"  />
</g>  
    <!-- Jupiter -->
    <g>
  <animateTransform 
      attributeName="transform" 
      type="rotate" 
      begin="btn1.click"
      values="0 250 175;360 250 175" 
      dur="16s"
      repeatCount="indefinite"
  />
 <circle class="Jupiter-orbit" cx="250" cy="175" r="180"     />
 <circle class="Jupiter " cx="70" cy="175" r="20" transform="rotate(180 250 175)"  />
</g>
  <circle class="sun" cx="250" cy="175" r="18"  >
     <animate attributeName="r" values="18;18;22;22;22;18" dur="12s" repeatCount="indefinite" />
  </circle>
    
</div> 

当动画为运行时,Zodiac group的轨道会响起。