我正在尝试使用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程序。
答案 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>