javascript - 绘制倒圆弧改变圆心坐标
问题描述
我正在使用这段代码来绘制弧线,到目前为止它很棒,但是我遇到了一个textPath
我无法弄清楚的问题。
请运行以下代码段。
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
function describeArc(x, y, radius, startAngle, endAngle){
var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);
var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
var d = [
"M", start.x, start.y,
"A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
].join(" ");
return d;
}
var correctPath = document.getElementById('correctPath'),
incorrectPath = document.getElementById('incorrectPath'),
expectedPath = document.getElementById('expectedPath');
correctPath.setAttribute('d', describeArc(24,24,20,0,90));
incorrectPath.setAttribute('d', describeArc(24,24,20,90,0));
expectedPath.setAttribute('d', 'M24 2.75 a 1 1 1 1 1 0 42.8');
.col {width: 32%; float: left; padding: 0.5%}
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<defs>
<path d="" id="correctPath"></path>
</defs>
<circle r="24" cx="24" cy="24" fill="#eee"></circle>
<text id="nameText" fill="green" font-size="3.2">
<textPath xlink:href="#correctPath">correct</textPath>
</text>
</svg>
</div>
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<defs>
<path d="" id="incorrectPath"></path>
</defs>
<circle r="24" cx="24" cy="24" fill="#eee"></circle>
<text id="nameText" fill="red" font-size="3.2">
<textPath xlink:href="#incorrectPath">incorrect</textPath>
</text>
</svg>
</div>
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<defs>
<path d="" id="expectedPath"></path>
</defs>
<circle r="24" cx="24" cy="24" fill="#eee"></circle>
<text id="nameText" fill="blue" font-size="3.2">
<textPath xlink:href="#expectedPath">expected</textPath>
</text>
</svg>
</div>
所以使用
correctPath.setAttribute('d', describeArc(24,24,20,0,90));
它似乎做了应该做的事情,但在这种情况下,我需要将文本颠倒过来,所以我试图startAngle
用endAngle
incorrectPath.setAttribute('d', describeArc(24,24,20,90,0));
你看到的结果是不正确的,它基本上将弧中心坐标重新定位到另一个位置,而不是给我我期望的坐标。
如何调整这两个函数以能够处理相反的情况startAngle
并endAngle
产生预期的结果?
解决方案
arc 命令的结构如下:
rx ry x-axis-rotation large-arc-flag sweep-flag x y
最后一个标志sweep-flag
描述了圆弧绕圆的方向。如果在极坐标中交换起始角和结束角,则方向也会交换:endAngle > startAngle 表示顺时针,startAngle > endAngle 表示逆时针。您的函数绘制从 endAngle 到 startAngle 的弧线,因此反之亦然。
一个简单的解决方案是实施此规则:
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
function describeArc(x, y, radius, startAngle, endAngle){
var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);
var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
var sweepFlag = endAngle > startAngle ? 0 : 1; //sic
var d = [
"M", start.x, start.y,
"A", radius, radius, 0, largeArcFlag, sweepFlag, end.x, end.y
].join(" ");
return d;
}
var correctPath = document.getElementById('correctPath'),
incorrectPath = document.getElementById('incorrectPath'),
expectedPath = document.getElementById('expectedPath');
correctPath.setAttribute('d', describeArc(24,24,20,0,90));
incorrectPath.setAttribute('d', describeArc(24,24,20,90,0));
expectedPath.setAttribute('d', 'M24 2.75 a 1 1 1 1 1 0 42.8');
.col {width: 32%; float: left; padding: 0.5%}
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<defs>
<path d="" id="correctPath"></path>
</defs>
<circle r="24" cx="24" cy="24" fill="#eee"></circle>
<text id="nameText" fill="green" font-size="3.2">
<textPath xlink:href="#correctPath">counterclockwise</textPath>
</text>
</svg>
</div>
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<defs>
<path d="" id="incorrectPath"></path>
</defs>
<circle r="24" cx="24" cy="24" fill="#eee"></circle>
<text id="nameText" fill="red" font-size="3.2">
<textPath xlink:href="#incorrectPath">clockwise</textPath>
</text>
</svg>
</div>
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<defs>
<path d="" id="expectedPath"></path>
</defs>
<circle r="24" cx="24" cy="24" fill="#eee"></circle>
<text id="nameText" fill="blue" font-size="3.2">
<textPath xlink:href="#expectedPath">expected</textPath>
</text>
</svg>
</div>
但请注意,一旦您真的想以度数越过圆的尽头,这条规则就会失效。比方说,顺时针从 300 度到 90 度。如果这是您的意图,则必须明确说明并将旋转方向作为参数传递给您的函数。
(您的参考路径M24 2.75 a 1 1 1 1 1 0 42.8
无法绘制并自动重写为。有关管理此替换的规则,M 24,2.75 a 21.4,21.4 1 1 1 0 42.8
请参阅这些注释。)
推荐阅读
- swift - AVAudioPlayer NSOSStatusErrorDomain 错误
- python - 如何将来自表模型的 HTML 表数据中的记录添加到另一个表模型中?
- c# - 获取 List.Max 的索引?
- symfony4 - MappingException:“需要扩展 DOM。”
- html - 如何使用 Handlebars 将表单中的复选框插入 SQL?
- python - 如何从 gui 中收到的多行输入写入 python 文件?
- sql-server-2012 - 即使有空值也加入 2 个表并对每一行求和
- azure-web-app-service - 在 IaaS VM RHEL 上使用 ASE 与 Docker CE 选择 Azure Web App for Containers 时托管微服务的最佳方式
- docusignapi - 如何指定文档模板标签的尺寸
- bash - 如何打印路径中指定单词的行?