如何用JavaScript生成底边水平的正X边形并解决SVG间距问题?
生成底边水平位于底部的正多边形(无SVG空白)
核心思路
要实现两个目标:让正多边形的底边水平并位于底部,同时消除SVG viewBox的空白,需要从顶点角度调整和viewBox精确计算两方面入手。
1. 调整顶点角度,让底边居底
正多边形的顶点默认通常从顶部或右侧开始排列,我们需要通过调整起始角度,使底边的两个端点处于底部水平线上。
以SVG坐标系(y轴向下,原点在左上角)为例,外接圆半径为r的n边形,顶点坐标计算公式如下:
- 起始弧度:
startAngle = Math.PI / 2 + Math.PI / n(对应90°+180°/n) - 每个顶点的角度:
startAngle - (2 * Math.PI * i) / n(顺时针依次旋转) - 顶点坐标:
x = r * Math.cos(angle),y = r * Math.sin(angle)
这个起始角度确保第一个和最后一个顶点组成的底边水平,且处于多边形的最底部。
2. 精确计算viewBox,消除空白
要让多边形完全填满viewBox,需要先计算所有顶点的坐标极值(最小/最大x、y值),再将viewBox设置为minX minY (maxX-minX) (maxY-minY),这样多边形的边缘会刚好贴合viewBox的边界。
完整实现代码(JavaScript动态生成)
function generateRegularPolygon(sideCount, radius = 50) { const points = []; // 计算起始角度,确保底边水平在底部 const startAngle = Math.PI / 2 + Math.PI / sideCount; // 生成所有顶点坐标 for (let i = 0; i < sideCount; i++) { const angle = startAngle - (2 * Math.PI * i) / sideCount; const x = radius * Math.cos(angle); const y = radius * Math.sin(angle); points.push(`${x},${y}`); } // 计算坐标极值,确定viewBox范围 const coords = points.map(p => p.split(',').map(Number)); const minX = Math.min(...coords.map(c => c[0])); const maxX = Math.max(...coords.map(c => c[0])); const minY = Math.min(...coords.map(c => c[1])); const maxY = Math.max(...coords.map(c => c[1])); // 创建SVG元素 const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.setAttribute('viewBox', `${minX} ${minY} ${maxX - minX} ${maxY - minY}`); svg.setAttribute('width', '200'); svg.setAttribute('height', '200'); const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); polygon.setAttribute('points', points.join(' ')); polygon.setAttribute('fill', 'none'); polygon.setAttribute('stroke', '#000'); polygon.setAttribute('stroke-width', '2'); svg.appendChild(polygon); return svg; } // 调用示例:生成5边形并添加到页面 document.body.appendChild(generateRegularPolygon(5));
静态SVG示例(正五边形)
<svg viewBox="-47.55 -50 95.1 100" width="200" height="200"> <polygon points="29.39,40 -47.55,15.45 -29.39,-40 29.39,-40 47.55,15.45" fill="none" stroke="#000" stroke-width="2"/> </svg>
这个SVG的viewBox是根据顶点坐标极值计算的,多边形完全填满viewBox,且底边(29.39,-40和-29.39,-40)水平位于底部。
内容的提问来源于stack exchange,提问作者sylar32
相关产品推荐
相关产品推荐

