我正在尝试使用遵循svg多边形轮廓的svg路径创建形状。
我需要设置svg path元素的d
属性,因为形状的大小会有所不同,具体取决于添加到文档中的<text />
元素中有多少文本。我将使用多种形状,但为了简洁起见,这里仅展示一种形状。
我的逻辑是尝试基本上从中间开始,向右下移动60度,再回到中间,然后向左下移动60度,然后加入框的左边。
我的形状不太正确。有很多问题:
形状与六边形的点不对齐。
出现在对角线上的每条平线或H
的长度都不相同。
有一条流氓线试图连接回形状点。
我需要在拐角处添加曲线,我不确定该怎么做。
const getPoint = ({
sides,
size,
center,
rotate,
side
}) => {
const degrees = (360 / sides) * side - rotate;
const radians = (Math.PI / 180) * degrees;
return {
x: center.x + size * Math.cos(radians),
y: center.y + size * Math.sin(radians)
};
};
const path = document.querySelector('path');
const gRef = document.querySelector('.hierarchy-label__container');
gRef.setAttribute('transform', 'translate(0, -40)');
const gbBox = gRef.getBBox();
let startingX = gbBox.x + gbBox.width / 2;
const startingY = gbBox.y + gbBox.height;
startingX = startingX - 0.7;
const [bottomRight, bottomLeft] = [1, 4].map((side) =>
getPoint({
sides: 6,
size: 30,
center: { x: startingX, y: startingY },
side,
rotate: 30
})
);
const bottomRightCoords = `${bottomRight.x} ${bottomRight.y}`;
path.setAttribute(
'd',
`M ${startingX} ${startingY} L ${bottomRightCoords} H ${gbBox.width} M ${startingX} ${startingY} L ${
bottomLeft.x
} ${bottomRight.y} H -${gbBox.width + 4} V -${gbBox.height} H ${gbBox.width} L ${gbBox.width} ${
bottomRight.y
} M ${startingX} ${startingY} Z`
);
.hierarchy-label__text {
fill: white;
text-anchor: middle;
font-size: 1.2rem;
}
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 990 759">
<g class="vx-group vx-cluster" transform="translate(100, 100)">
<g class="vx-group" transform="translate(0, 0)">
<g class="vx-group node-vertical__container" transform="translate(490, 0)">
<polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30"></polygon>
<g class="vx-group node-vertical__business-unit" transform="translate(0, 0)">
<use xlink:href="#icon-BusinessUnit"></use>
</g>
<g class="hierarchy-label__container" transform="translate(0,-40)">
<text class="hierarchy-label__text" width="50" fill="white" x="0" y="0" text-anchor="middle" style="pointer-events: none;">
<tspan x="0" dy="0em">Finance</tspan>
</text>
<path></path>
</g>
</g>
</g>
</g>
</svg>
答案 0 :(得分:1)
为了清楚起见,我简化了很多代码。另外:我选择在JavaScript中绘制六边形,以便能够使用六边形顶点绘制放置文本的路径。
请阅读代码的注释
function drawHex(r){
// this function draws a hexagon with the center in 0,0
// and returns the array of points
// r is the radius of the circumscribed circle
let pointsRy = [];
let a = Math.PI/3;
for( let i = 0; i < 6; i++ ){
let aRad = (a*i) - Math.PI/2;
let Xp = parseFloat(r * Math.cos( aRad )).toFixed(3);
let Yp = parseFloat(r * Math.sin( aRad )).toFixed(3);
pointsRy.push({x:Xp,y:Yp,a:aRad});
}
// the points for the hexagon
let points = pointsRy.map(p => `${p.x}, ${p.y}`).join(" ");
hex.setAttributeNS(null,"points", points)
// the function returns the array of points
return pointsRy;
}
// ry: the array of points used to draw the hexagon: I'll be using the first & the second point to drae the textRect path
let ry = drawHex(30);
function drawTextPath(W,H){
// W: the width of the text "rectangle"
// H: the height of the text "rectangle"
// the textRect & the text art translated upwards (in y). Please see svg
let w = W/2 - (Number(ry[1].x) - Number(ry[0].x));
let d = `M${ry[0].x},${ry[0].y} L${ry[1].x},${ry[1].y} h${w} v-${H} h-${W} v${H} h${w}`;
textRect.setAttributeNS(null,"d",d)
}
drawTextPath(180,50)
svg{font-family: "Century Gothic",CenturyGothic,AppleGothic,sans-serif;}
text{fill:white; text-anchor:middle;pointer-events: none;}
<svg viewBox="-100 -70 200 200">
<polygon id="hex" />
<g transform="translate(0,-6)">
<path id="textRect" />
<text y="-40">
<tspan>Finance</tspan>
</text>
</g>
</svg>
毫无疑问,还有其他方法可以得出此结果。希望您会发现我的解决方案有用。