如何对齐多边形外边缘上的点以获得 svg 中较粗的边框?
How to align points on the outer edges of polygon for thicker border in svg?
我的问题是:
我有一个通过取一些点绘制的多边形,我在多边形 edges/outline 上显示这些点。当我增加多边形的 stroke-width 时,点在轮廓的中心对齐。我们如何实现 edge/border 外侧的点对齐?
实际情况如下图,点在border/stroke
上居中对齐
工作区域link为此
https://codepen.io/jinata92/pen/JjKZeqE
我正在寻找如下图所示的解决方案,这些点应该在 border/stroke
的外边缘对齐
var height = 100,
width = 100;
var polygon;
var arrVertexes = [
[6, 6],
[94, 6],
[94, 94],
[6, 94]
];
var svg, gContainer;
function config() {
svg = d3
.select(".main")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `0 0 ${width} ${height}`);
gContainer = svg.select("g");
}
function drawPolygon() {
polygon = gContainer
.append("polygon")
.attr("points", arrVertexes)
.attr("class", "segment");
}
function drawCircle() {
gContainer
.selectAll("circle")
.data(arrVertexes)
.enter()
.append("circle")
.attr("class", "vertex")
.classed("handle", true)
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", 4);
}
config();
drawPolygon();
drawCircle();
body {
background-color: grey;
}
svg {
position: absolute;
overflow: visible;
}
.resize-div {
position: relative;
overflow: visible;
}
.polygon {
stroke: yellow;
fill: transparent;
}
.vertex,
.dot {
fill: black;
stroke: none;
}
.segment {
stroke-width: 30;
stroke: yellow;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div style="width:100px;height:100px; left: 400px;
top:50px;" class="resize-div">
<svg class="main" height="100%" width="100%">
<g class="polygon"></g>
</svg>
</div>
stroke-width 始终应用于两侧,因此线的中心仍在所需位置。但是有一些解决方法。一种是只绘制形状,但也应用 clip path 等于元素,但 没有 笔画宽度:
var height = 100,
width = 100;
var polygon;
var arrVertexes = [
[6, 6],
[94, 6],
[94, 94],
[6, 94]
];
var svg, gContainer;
function config() {
svg = d3
.select(".main")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `0 0 ${width} ${height}`);
gContainer = svg.select("g");
}
function drawPolygon() {
polygon = gContainer
.append("polygon")
.attr("clip-path", "url('#my-clip-path')")
.attr("points", arrVertexes)
.attr("class", "segment");
// Append a clip path
svg.append("defs")
.append("clipPath")
.attr("id", "my-clip-path")
.append("polygon")
.attr("points", arrVertexes)
.attr("class", "segment");
}
function drawCircle() {
gContainer
.selectAll("circle")
.data(arrVertexes)
.enter()
.append("circle")
.attr("class", "vertex")
.classed("handle", true)
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", 4);
}
config();
drawPolygon();
drawCircle();
body {
background-color: grey;
}
svg {
position: absolute;
overflow: visible;
}
.resize-div {
position: relative;
overflow: visible;
}
.polygon {
stroke: yellow;
fill: transparent;
}
.vertex,
.dot {
fill: black;
stroke: none;
}
.segment {
stroke-width: 30;
stroke: yellow;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div style="width:100px;height:100px; left: 400px;
top:50px;" class="resize-div">
<svg class="main" height="100%" width="100%">
<g class="polygon"></g>
</svg>
</div>
或者,您可以在另一个多边形之上绘制一个多边形,但要向内一点。使用边界框计算外多边形的中心,并将内多边形的坐标向内移动一些像素:
var height = 100,
width = 100;
var polygon;
var arrVertexes = [
[6, 6],
[94, 6],
[94, 94],
[6, 94]
];
var svg, gContainer;
function config() {
svg = d3
.select(".main")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `0 0 ${width} ${height}`);
gContainer = svg.select("g");
}
function drawPolygon() {
polygon = gContainer
.append("polygon")
.attr("points", arrVertexes)
.attr("class", "segment-border");
// Get the bounding box so you can calculate the centre
const boundingBox = polygon.node().getBBox();
const centre = {
x: boundingBox.x + boundingBox.width / 2,
y: boundingBox.y + boundingBox.height / 2,
};
const innerVertexes = arrVertexes.map(d => [
d[0] < centre.x ? d[0] + 15 : d[0] - 15,
d[1] < centre.y ? d[1] + 15 : d[1] - 15,
]);
polygon = gContainer
.append("polygon")
.attr("points", innerVertexes)
.attr("class", "segment");
}
function drawCircle() {
gContainer
.selectAll("circle")
.data(arrVertexes)
.enter()
.append("circle")
.attr("class", "vertex")
.classed("handle", true)
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", 4);
}
config();
drawPolygon();
drawCircle();
body {
background-color: grey;
}
svg {
position: absolute;
overflow: visible;
}
.resize-div {
position: relative;
overflow: visible;
}
.polygon {
stroke: yellow;
fill: transparent;
}
.vertex,
.dot {
fill: black;
stroke: none;
}
.segment-border {
fill: yellow;
}
.segment {
fill: white;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div style="width:100px;height:100px; left: 400px;
top:50px;" class="resize-div">
<svg class="main" height="100%" width="100%">
<g class="polygon"></g>
</svg>
</div>
我的问题是:
我有一个通过取一些点绘制的多边形,我在多边形 edges/outline 上显示这些点。当我增加多边形的 stroke-width 时,点在轮廓的中心对齐。我们如何实现 edge/border 外侧的点对齐?
实际情况如下图,点在border/stroke
上居中对齐工作区域link为此
https://codepen.io/jinata92/pen/JjKZeqE
我正在寻找如下图所示的解决方案,这些点应该在 border/stroke
的外边缘对齐var height = 100,
width = 100;
var polygon;
var arrVertexes = [
[6, 6],
[94, 6],
[94, 94],
[6, 94]
];
var svg, gContainer;
function config() {
svg = d3
.select(".main")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `0 0 ${width} ${height}`);
gContainer = svg.select("g");
}
function drawPolygon() {
polygon = gContainer
.append("polygon")
.attr("points", arrVertexes)
.attr("class", "segment");
}
function drawCircle() {
gContainer
.selectAll("circle")
.data(arrVertexes)
.enter()
.append("circle")
.attr("class", "vertex")
.classed("handle", true)
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", 4);
}
config();
drawPolygon();
drawCircle();
body {
background-color: grey;
}
svg {
position: absolute;
overflow: visible;
}
.resize-div {
position: relative;
overflow: visible;
}
.polygon {
stroke: yellow;
fill: transparent;
}
.vertex,
.dot {
fill: black;
stroke: none;
}
.segment {
stroke-width: 30;
stroke: yellow;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div style="width:100px;height:100px; left: 400px;
top:50px;" class="resize-div">
<svg class="main" height="100%" width="100%">
<g class="polygon"></g>
</svg>
</div>
stroke-width 始终应用于两侧,因此线的中心仍在所需位置。但是有一些解决方法。一种是只绘制形状,但也应用 clip path 等于元素,但 没有 笔画宽度:
var height = 100,
width = 100;
var polygon;
var arrVertexes = [
[6, 6],
[94, 6],
[94, 94],
[6, 94]
];
var svg, gContainer;
function config() {
svg = d3
.select(".main")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `0 0 ${width} ${height}`);
gContainer = svg.select("g");
}
function drawPolygon() {
polygon = gContainer
.append("polygon")
.attr("clip-path", "url('#my-clip-path')")
.attr("points", arrVertexes)
.attr("class", "segment");
// Append a clip path
svg.append("defs")
.append("clipPath")
.attr("id", "my-clip-path")
.append("polygon")
.attr("points", arrVertexes)
.attr("class", "segment");
}
function drawCircle() {
gContainer
.selectAll("circle")
.data(arrVertexes)
.enter()
.append("circle")
.attr("class", "vertex")
.classed("handle", true)
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", 4);
}
config();
drawPolygon();
drawCircle();
body {
background-color: grey;
}
svg {
position: absolute;
overflow: visible;
}
.resize-div {
position: relative;
overflow: visible;
}
.polygon {
stroke: yellow;
fill: transparent;
}
.vertex,
.dot {
fill: black;
stroke: none;
}
.segment {
stroke-width: 30;
stroke: yellow;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div style="width:100px;height:100px; left: 400px;
top:50px;" class="resize-div">
<svg class="main" height="100%" width="100%">
<g class="polygon"></g>
</svg>
</div>
或者,您可以在另一个多边形之上绘制一个多边形,但要向内一点。使用边界框计算外多边形的中心,并将内多边形的坐标向内移动一些像素:
var height = 100,
width = 100;
var polygon;
var arrVertexes = [
[6, 6],
[94, 6],
[94, 94],
[6, 94]
];
var svg, gContainer;
function config() {
svg = d3
.select(".main")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `0 0 ${width} ${height}`);
gContainer = svg.select("g");
}
function drawPolygon() {
polygon = gContainer
.append("polygon")
.attr("points", arrVertexes)
.attr("class", "segment-border");
// Get the bounding box so you can calculate the centre
const boundingBox = polygon.node().getBBox();
const centre = {
x: boundingBox.x + boundingBox.width / 2,
y: boundingBox.y + boundingBox.height / 2,
};
const innerVertexes = arrVertexes.map(d => [
d[0] < centre.x ? d[0] + 15 : d[0] - 15,
d[1] < centre.y ? d[1] + 15 : d[1] - 15,
]);
polygon = gContainer
.append("polygon")
.attr("points", innerVertexes)
.attr("class", "segment");
}
function drawCircle() {
gContainer
.selectAll("circle")
.data(arrVertexes)
.enter()
.append("circle")
.attr("class", "vertex")
.classed("handle", true)
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", 4);
}
config();
drawPolygon();
drawCircle();
body {
background-color: grey;
}
svg {
position: absolute;
overflow: visible;
}
.resize-div {
position: relative;
overflow: visible;
}
.polygon {
stroke: yellow;
fill: transparent;
}
.vertex,
.dot {
fill: black;
stroke: none;
}
.segment-border {
fill: yellow;
}
.segment {
fill: white;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div style="width:100px;height:100px; left: 400px;
top:50px;" class="resize-div">
<svg class="main" height="100%" width="100%">
<g class="polygon"></g>
</svg>
</div>