gpt4 book ai didi

svg - 如何沿着 SVG 线放置多个均匀分布的箭头?

转载 作者:行者123 更新时间:2023-12-03 06:55:25 25 4
gpt4 key购买 nike

我是 SVG 新手,我正在尝试在两点之间画一条直线。到目前为止,我通过使用以下命令进行了管理:

<line x1="50" y1="50" x2="150" y2="150" style="stroke:rgb(255,255,0); stroke-width:2" stroke-dasharray="5,3" />"

在这条线上添加小三角形或箭头(均匀间隔)以指示方向的最简单方法是什么?

编辑 1:

为了更清楚地说明,我并不是在寻找线末端的箭头,而是在整条线上寻找多个三角形(均匀间隔)。如果可能的话,我想用指向该线方向的三角形替换虚线上的每个破折号。

编辑2

根据 Phrogz 的建议,我创建了一个如下所示的页面,但没有显示任何内容。我做错了什么?

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<link href="css/com.css" rel="stylesheet" type="text/css" />
</head>
<body style="background:none;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 70 90">
<defs>
<marker id="t" markerWidth="4" markerHeight="4"
orient="auto" refY="2">
<path d="M0,0 L4,2 0,4" />
</marker>
</defs>
<polyline points="0,0 0,50 20,70 40,10 42,8 44,10, 46,14 50,50" />
</svg>
<script type="text/javascript">
midMarkers(document.querySelector('polyline'),6);

// Given a polygon/polyline, create intermediary points along the
// "straightaways" spaced no closer than `spacing` distance apart.
// Intermediary points along each section are always evenly spaced.
// Modifies the polygon/polyline in place.
function midMarkers(poly,spacing){
var svg = poly.ownerSVGElement;
for (var pts=poly.points,i=1;i<pts.numberOfItems;++i){
var p0=pts.getItem(i-1), p1=pts.getItem(i);
var dx=p1.x-p0.x, dy=p1.y-p0.y;
var d = Math.sqrt(dx*dx+dy*dy);
var numPoints = Math.floor( d/spacing );
dx /= numPoints;
dy /= numPoints;
for (var j=numPoints-1;j>0;--j){
var pt = svg.createSVGPoint();
pt.x = p0.x+dx*j;
pt.y = p0.y+dy*j;
pts.insertItemBefore(pt,i);
}
if (numPoints>0) i += numPoints-1;
}
}
</script>
</body>
</html>

最佳答案

基于对问题的澄清,这里是沿着<polyline>创建中间点的实现。元素使得 marker-mid="url(#arrowhead)"属性将起作用。请参阅下文,了解标记和箭头的介绍。

演示:http://jsfiddle.net/Zv57N/

midMarkers(document.querySelector('polyline'),6);

// Given a polygon/polyline, create intermediary points along the
// "straightaways" spaced no closer than `spacing` distance apart.
// Intermediary points along each section are always evenly spaced.
// Modifies the polygon/polyline in place.
function midMarkers(poly,spacing){
var svg = poly.ownerSVGElement;
for (var pts=poly.points,i=1;i<pts.numberOfItems;++i){
var p0=pts.getItem(i-1), p1=pts.getItem(i);
var dx=p1.x-p0.x, dy=p1.y-p0.y;
var d = Math.sqrt(dx*dx+dy*dy);
var numPoints = Math.floor( d/spacing );
dx /= numPoints;
dy /= numPoints;
for (var j=numPoints-1;j>0;--j){
var pt = svg.createSVGPoint();
pt.x = p0.x+dx*j;
pt.y = p0.y+dy*j;
pts.insertItemBefore(pt,i);
}
if (numPoints>0) i += numPoints-1;
}
}

上面的代码修改了现有的 <polyline>沿每个直边每隔间距单位添加点的元素。将此与 marker-mid 结合起来在每个顶点放置一个旋转标记,您就可以沿着路径一致地绘制任意复杂的形状/图形。

Bird Tracks

尽管代码沿着每个线段均匀地间隔开点(这样在拐角处就不会出现难看的“聚集”),如上面的演示所示,代码不会删除路径中已经存在的任何距离较近的点比间距值。

<小时/>

(原始“标记简介”答案如下。)

<小时/>

您想要定义 SVG <marker> element并添加 marker-start="…"和/或 marker-end="…"您的线路的属性。使用标记将任意形状复制到路径的末端,并(使用 orient="auto" )旋转形状以匹配。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -100 200 200">
<defs>
<marker id='head' orient='auto' markerWidth='2' markerHeight='4'
refX='0.1' refY='2'>
<path d='M0,0 V4 L2,2 Z' fill='red' />
</marker>
</defs>
<path
marker-end='url(#head)'
stroke-width='5' fill='none' stroke='black'
d='M0,0 C45,45 45,-45 90,0'
/>
</svg>​

演示:http://jsfiddle.net/Z5Qkf/1/

Curved line with arrowhead

在上面:

  • orient="auto" 使标记随线旋转
  • markerWidth and markerHeight 定义一个用于标记的边界框(如 viewBox)。
    • 请注意,这些值随后会按 stroke-width 进行缩放。最后一行;高度为“4”会导致最终绘图中的宽度为 20 个单位 (4×5)。
  • refX and refY 定义将形状放置在路径末端时的“原点”位置
    • 我用过refX="0.1"确保标记稍微与行尾重叠
  • 为了使自动方向正常工作,您希望标记的“向前”方向位于 +x 方向。 (用于标记的红色路径在未旋转时看起来像这样 ▶。)
  • 您可以调整fill-opacitystroke-opacity独立地标记和/或线,但更改为 opacity线条的形状也会影响绘制的标记。
    • 由于线条和标记重叠,如果您降低 fill-opacity您会看到标记的重叠;但是,如果您降低 opacity线本身,然后标记在线上合成为完全不透明,然后两者的组合降低不透明度。
      enter image description here
<小时/>

如果您想要沿线长度的箭头,则需要使用 marker-mid="…"<path><polyline>以及沿线的临时点。

演示:http://jsfiddle.net/Z5Qkf/2/

enter image description here

唯一的问题是任何沿着线 messes up the orientation 改变方向的点;这就是为什么在演示中我使用贝塞尔曲线来圆化拐角,以便直线上的中点沿着直线部分。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -100 200 200">
<defs>
<marker id='mid' orient="auto"
markerWidth='2' markerHeight='4'
refX='0.1' refY='1'>
<!-- triangle pointing right (+x) -->
<path d='M0,0 V2 L1,1 Z' fill="orange"/>
</marker>
<marker id='head' orient="auto"
markerWidth='2' markerHeight='4'
refX='0.1' refY='2'>
<!-- triangle pointing right (+x) -->
<path d='M0,0 V4 L2,2 Z' fill="red"/>
</marker>
</defs>

<path
id='arrow-line'
marker-mid='url(#mid)'
marker-end='url(#head)'
stroke-width='5'
fill='none' stroke='black'
d='M0,0 L20,20 C40,40 40,40 60,20 L80,0'
/>

</svg>​

要按程序执行此操作,您可以使用 JavaScript 和 getPointAtLength()命令获取 sample the path 的路径.

关于svg - 如何沿着 SVG 线放置多个均匀分布的箭头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11808860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com