1

我正在尝试使用 SVG 和纯 CSS 在一个圆圈内创建一个 16 点星——没有 JS!我的策略是创建 16 个等边三角形(通过 Defs 和 Use,使其保持干燥),将每个 Use 迭代旋转 22.5 度。我的问题是,当我将 rotate() 变换应用于第二个三角形时,SVG 会改变三角形的中心点——CSS3 不会(它围绕固定轴旋转)。我尝试添加 x 和 y 参数,添加一个类并进行 translate() 变换,内联进行...没有任何效果——我只是不知道如何将三角形移回原位(旋转)圆(以 150 为中心,我估计为 150)。
任何帮助,将不胜感激。这是我遇到问题的 SVG 代码行。

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

您可以在这里看到它的实际效果。

<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 点,因为出于某种原因,一系列 22.5 度的旋转会产生不平衡的十六边形。我去掉了红色圆圈中心点和背景网格,并添加了 SVG 动画。 是(最终)工作示例。

对 CodePen 感到抱歉,但我正在尝试弄清楚如何使代码片段适用于整个 HTML/CSS/SVG 程序。

4

1 回答 1

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 问题。请阅读这篇关于SVG 元素上的变换的文章

.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>

于 2019-01-23T08:30:48.510 回答