SVG元素在圆圈上旋转

Posted

技术标签:

【中文标题】SVG元素在圆圈上旋转【英文标题】:SVG element rotate on circle 【发布时间】:2019-09-14 23:15:32 【问题描述】:

所以我有一个 SVG 元素 - 大圆圈 - 和里面的一组元素。

我想围绕这个大圆圈旋转这些元素。代码非常简单,但我已经开始担心如何在正确的路径(大圆圈)上设置这个圆圈(graph__skils)。正如您在下面的链接中看到的,这个小圆圈在大圆圈上旋转不正确。请帮忙

Circle rotate jsfiddle

HTML 文件

<section class="graph">
 <svg xmlns="http://www.w3.org/2000/svg" 
     
     
    viewBox="0 0 670 696">
    <g>
      <g class="graph__middle">
         <path fill="#3f9" d="M345 264c34.794 0 63 28.206 63 63s-28.206 63-63 63-63-28.206-63-63 28.206-63 63-63z"/>
      </g>

       <g class="graph__design" >
          <g class="graph_mainCircle">
             <path fill="none" stroke="#cf9" stroke- linecap="round" stroke-linejoin="round" stroke-miterlimit="50" d="M345 197c71.797 0 130 58.203 130 130s-58.203 130-130 130-130-58.203-130-130 58.203-130 130-130z"/>
          </g>

          <g class="graph__skills">
             <g class="graph__middle">
                <path fill="#cf9" d="M445.053 387c11.052 0 20.012 8.954 20.012 20s-8.96 20-20.012 20-20.012-8.954-20.012-20 8.96-20 20.012-20z"/>
              </g>
         </g>
      </g>
    </g>
</svg>

SCSS 文件

.graph 
  position: relative;
  width:500px;
  height:500px;

  svg 
    position: relative;
    border: 2px solid blue;
    width: 99%;
    height: 99%;
  

  &__design 
    position: relative;
  

  &__skills 
    transform-origin: center;
    position: absolute;
    animation: mercury-group 18s linear infinite;
  

  &__middle 
    position: relative;
  


@keyframes mercury-group 
  0% 
    transform: rotateZ(0deg);
  

  100% 
    transform: rotateZ(-360deg);
  

【问题讨论】:

【参考方案1】:

svg 元素的中心不是行星的中心。您需要将transform-origin 更改为345px 328px。为了计算新中心,我使用了 graph__middle 的 getBBox() 方法

.graph 
  position: relative;
  width: 500px;
  height: 500px;

.graph svg 
  position: relative;
  border: 2px solid blue;
  width: 99%;
  height: 99%;

.graph__design 
  position: relative;

.graph__skills 
  transform-origin: 345px 328px;
  position: absolute;
  animation: mercury-group 18s linear infinite;

.graph__middle 
  position: relative;


@keyframes mercury-group 
  0% 
    transform: rotateZ(0deg);
  
  100% 
    transform: rotateZ(-360deg);
  
<section class="graph">
     <svg xmlns="http://www.w3.org/2000/svg" 
         
         
        viewBox="0 0 670 696">
        <g>
          <g class="graph__middle" id="KK">
             <path fill="red" d="M345 264c34.794 0 63 28.206 63 63s-28.206 63-63 63-63-28.206-63-63 28.206-63 63-63z"/>
          </g>

           <g class="graph__design" >
              <g class="graph_mainCircle">
                 <path fill="none" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="50" d="M345 197c71.797 0 130 58.203 130 130s-58.203 130-130 130-130-58.203-130-130 58.203-130 130-130z"/>
              </g>

              <g class="graph__skills">
                 <g class="graph__middle">
                    <path d="M445.053 387c11.052 0 20.012 8.954 20.012 20s-8.96 20-20.012 20-20.012-8.954-20.012-20 8.96-20 20.012-20z"/>
                  </g>
             </g>
          </g>
        </g>
       
       <circle cx="345" cy="328" r="3" />
    </svg>
</section>

【讨论】:

【参考方案2】:

您可以像下面这样旋转大圆圈:

.graph 
  position: relative;
  width: 500px;
  height: 500px;


svg 
  position: relative;
  border: 2px solid blue;
  width: 99%;
  height: 99%;


.graph__design 
  position: relative;
  transform-box:fill-box;
  transform-origin: center;
  animation: mercury-group 18s linear infinite;


.graph__skills 
  transform-origin: center;
  position: absolute;


.graph__middle 
  position: relative;




@keyframes mercury-group 
  0% 
    transform: rotateZ(0deg);
  
  
  100% 
    transform: rotateZ(-360deg);
  
<section class="graph">
  <svg xmlns="http://www.w3.org/2000/svg"   viewBox="0 0 670 696">
        <g>
          <g class="graph__middle">
             <path fill="#3f9" d="M345 264c34.794 0 63 28.206 63 63s-28.206 63-63 63-63-28.206-63-63 28.206-63 63-63z"/>
          </g>

           <g class="graph__design" >
              <g class="graph_mainCircle">
                 <path fill="none" stroke="#cf9" stroke- linecap="round" stroke-linejoin="round" stroke-miterlimit="50" d="M345 197c71.797 0 130 58.203 130 130s-58.203 130-130 130-130-58.203-130-130 58.203-130 130-130z"/>
              </g>

              <g class="graph__skills">
                 <g class="graph__middle">
                    <path fill="#cf9" d="M445.053 387c11.052 0 20.012 8.954 20.012 20s-8.96 20-20.012 20-20.012-8.954-20.012-20 8.96-20 20.012-20z"/>
                  </g>
             </g>
          </g>
        </g>
    </svg>
</section>

【讨论】:

好的,谢谢,这是个好主意,但是我里面有更多的圆圈,当我添加第二个时,它们会失去稳定性。我不知道发生了什么事。我不知道是什么原因。从早上开始我就一直在与它作斗争 - jsfiddle.net/n5amvbdw/2 @Agata 如果添加另一个元素(例如:jsfiddle.net/s5hdawep),则需要调整变换原点,因为它不再是正方形【参考方案3】:

SVG 示例

我的例子并没有完全回答你的问题,但我希望你能从我的回答中得到一些想法。

从动画的名字来看mercury-group你想创建一个太阳系的模型。 我提出了行星围绕太阳旋转的动画的变体。

我将太阳系行星的旋转中心定位在太阳中心,坐标为x =" 250 "y =" 175 "太阳中心

因此,行星绕太阳公转的动画组有以下形式:

<animateTransform 
      attributeName="transform" 
      type="rotate"
      values="0 250 175;360 250 175" 
      dur="12s"
      repeatCount="indefinite"
  />        

滤镜和渐变用于设计行星和太阳的外观。

太阳波纹和改变颜色的动画

<radialGradient id="gradSun">
        <stop offset="80%" stop-color="yellow">
         <animate attributeName="offset" values="80%;20%;80%" dur="6s" repeatCount="indefinite" />
         </stop>
        <stop offset="100%" stop-color="gold" >
        <animate attributeName="stop-color" values="gold;red;gold" dur="6s" repeatCount="indefinite" />
        </stop>
      </radialGradient>   

下面是行星绕太阳旋转的完整动画代码:

.solar-system
  background-color:#002;
  width:100%;
  height:100%;

.sun
  
  fill:url(#gradSun);
  filter:url(#dropShadow2);
  
 
 .Earth-orbit
  stroke:rgba(255,255,255,.4);
    stroke-width:1;
  fill:none;
  
.Earth
   filter:url(#dropShadow1);
   fill:url(#gradEarth);
 
<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%" 
		 >
	<feGaussianBlur   stdDeviation="1" />
 </filter>
    <filter id="dropShadow2" 
		x="-20%" y="-20%" 
		 >
		<feGaussianBlur   stdDeviation="4" />
	</filter>
	 <radialGradient id="gradSun">
        <stop offset="80%" stop-color="yellow">
		 <animate attributeName="offset" values="80%;20%;80%" dur="6s" 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>	  
 </defs>	 
 <!-- planet rotation animation -->
   <g>
  <animateTransform 
	  attributeName="transform" 
	  type="rotate"
      values="360 250 175;0 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>
 <circle class="sun" cx="250" cy="175" r="20"  /> 
</svg>

【讨论】:

【参考方案4】:

首先,你必须设置关键帧,然后使用 css 动画

@-webkit-keyframes rotated 
0% 
    -webkit-transform: rotate(0);
    transform: rotate(0);


100% 
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);



@keyframes rotated 
0% 
    -webkit-transform: rotate(0);
    transform: rotate(0);


100% 
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);

然后在css中使用动画

.bg-shape
animation: rotated 35s linear infinite;

然后在html中使用svg图片来旋转

<div class="col-lg-4">
                        <div class="inner-wrapper text-center">
                            <div class="mb-3">
                                <img src="../img/svg/shape-37.svg"  class="bg-shape">
                            </div>
                        </div>
                    </div>

【讨论】:

以上是关于SVG元素在圆圈上旋转的主要内容,如果未能解决你的问题,请参考以下文章

CSS:在一个元素上缩放和旋转多个 SVG 背景图像 - 没有 JS 可能吗?

制作带有css边框的SVG图标作为一个元素

动画 SVG 组对象 - 使用样式组件进行变换旋转不会围绕圆原点旋转

d3.js - 当鼠标悬停在 SVG 容器上的这些元素上时,如何将光标设置为手?

如何更改 viewBox 以使 svg 中的元素居中

围绕其中心旋转可缩放和翻译的 SVG 元素