SVG使用-旋转后无法重新定位多边形

时间:2019-01-23 03:05:18

标签: svg

我正在尝试使用SVG和纯CSS在圆内创建一个16点星形-没有JS! 我的策略是创建16个等边三角形(通过Defs和Use,使其保持DRY状态),将每个Use迭代旋转22.5度。 我的问题是,当我将rotate()变换应用于第二个三角形时,SVG更改了三角形的中心点,而CSS3却没有(它绕固定轴旋转)。 我试过添加x和y参数,添加类并执行translate()转换,然后进行内联处理……没有任何效果-我只是想不出如何将三角形移回内部的位置(旋转)圆(以150,150我估计为中心)。
任何帮助,将不胜感激。这是我遇到麻烦的SVG代码行。

<use xlink:href="#triangle" style="transform: rotate(22.5deg);"  />

您可以在操作here中看到它。

<style > .toile {
  display: flex;
  flex-direction: column;
  max-width: 400px;
  max-height: 800px;
  justify-content: center;
  align-items: center;
  /* centers outer containing element (the circle) horizontally & vertically */
  border: 5px #009000;
  /* green */
  border-style: groove;
  background-color: #f9e4b7;
  margin: 0 auto;
  /* centers surface on a page */
}
<div class="toile">
  <svg>
  <defs>
    <pattern id="grid" width="15" height="15" patternUnits="userSpaceOnUse">
  		<rect fill="white" x="0" y="0" width="14" height="14"/>
  		<rect fill="#009000" x="14" y="0" width="1" height="14"/>
  		<rect fill="#009000" x="0" y="14" width="14" height="5"/>
  	</pattern>

    <g id="triangle"> 
	<svg>
	<polygon points="150,18 200,100 100,100" 
	style="stroke:#009000;stroke-width:1; fill:#afeeee; opacity:.7" />
	</svg>
  </g>
  </defs>

  <rect fill="url(#grid)" x="0" y="0" width="100%" height="100%" />
  <svg viewBox="0 100 400 400" stroke="#009000" stroke-width=".5" width="300" height="300" class="cercle">
   <circle cx="50%" cy="50%" r="75" fill="transparent" /> </svg>

  <svg viewBox="0 100 400 400" stroke="#ce2029" stroke-width=".5" width="300" height="300">
   <circle cx="50%" cy="50%" r="2" fill="#ce2029" /> </svg>

  <use xlink:href="#triangle" />
  <use xlink:href="#triangle" style="transform: rotate(22.5deg);" />
  </svg>
</div>

感谢您提供解决此问题的方法;我只是想不通!请不要使用JS解决方案!

更新:

我已将16点的gon更改为15点的gon,因为某些原因,一系列22.5度旋转会生成不平衡的六边形。我摆脱了红色圆圈的中心点和背景网格,并添加了SVG动画。 Here是(最终)工作示例。

对不起CodePen,但我试图弄清楚如何使代码段适用于整个HTML / CSS / SVG程序。

1 个答案:

答案 0 :(得分:1)

这是一种实现方式: 首先,我简化了您的代码。除非您有充分的理由这样做,否则最好使事情保持简单。

我计算了围绕svg画布中心的三角形的点: <polygon id="triangle" points="200,125 264.95,237.5 135.05,237.5"

我使用svg变换旋转三角形:transform="rotate(22.5,200,200)"

第一个值是以度为单位的旋转,接下来是旋转中心的x和y。

随着SVG转换的推出,您不会遇到IE问题。请阅读有关Transforms on SVG Elements

的这篇文章

.toile {
  display: flex;
  flex-direction: column;
  max-width: 400px;
  max-height: 800px;
  justify-content: center;
  align-items: center;
  /* centers outer containing element (the circle) horizontally & vertically */
  border: 5px #009000;
  /* green */
  border-style: groove;
  background-color: #f9e4b7;
  margin: 0 auto;
  /* centers surface on a page */
}
<div class="toile">
   <svg viewBox="0 0 400 400" stroke="#009000" stroke-width=".5" width="300" height="300" >
  <defs>
    <pattern id="grid" width="15" height="15" patternUnits="userSpaceOnUse">
  		<rect fill="white" x="0" y="0" width="14" height="14"/>
  		<rect fill="#009000" x="14" y="0" width="1" height="14"/>
  		<rect fill="#009000" x="0" y="14" width="14" height="5"/>
  	</pattern>

 
	<polygon id="triangle" points="200,125 264.95,237.5 135.05,237.5" 
	style="stroke:#009000;stroke-width:1; fill:#afeeee; opacity:.7" />

  </defs>

  <rect fill="url(#grid)" x="0" y="0" width="100%" height="100%" />
  <circle class="cercle" cx="50%" cy="50%" r="75" fill="transparent" /> 
<circle cx="50%" cy="50%" r="2" fill="#ce2029" /> 
   

  <use xlink:href="#triangle" />
  <use xlink:href="#triangle" transform="rotate(22.5,200,200)" />
  </svg>
</div>

更新

要计算三角形的点,可以使用javascript。在像三角形这样的规则多边形的情况下,所有3个顶点都在一个彼此成2*Math.PI/3角的外接圆上。我从第一个顶点的偏移量-Math.PI / 2(-90度)开始。

// the center of the SVG canvas calculated from the values of the viewBox attribute. Alternatively you can choose a different point
 let c = {x:200,y:200}
 let radius = 75;
 let points = [];
 
 
 for(let a = -Math.PI/2; a < 3*Math.PI/2; a+= 2*Math.PI/3){
   let x = c.x + radius*Math.cos(a);
   let y = c.y + radius*Math.sin(a);
   points.push(x);
   points.push(y);
 }
 
 tri.setAttributeNS(null, "points", points.join());
svg{border:1px solid;height:90vh}
<svg viewBox="0 0 400 400">
<polygon id="tri" />
</svg>