我是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>
Run Code Online (Sandbox Code Playgroud)
Phr*_*ogz 150
基于对问题的澄清,这是一个沿<polyline>元素创建中间点的实现,以使marker-mid="url(#arrowhead)"属性起作用.有关标记和箭头的介绍,请参阅下文.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码修改现有<polyline>元素以沿每个直边每个间隔单位添加点.将其与marker-mid每个顶点放置一个旋转标记相结合,您就可以沿着路径一致地绘制任意复杂的形状/图形.

虽然代码沿着每个段均匀分布点(因此在角落处不会出现难看的"聚集"),因为上面的演示显示代码不会删除路径中已经存在的距离比间距更近的任何点值.
(原始的"标记简介"答案如下.)
您想要定义SVG <marker>元素并将行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>?
Run Code Online (Sandbox Code Playgroud)

在上面:
orient="auto" 导致标记随线旋转markerWidth并markerHeight定义一个用于标记的边界框(如viewBox).
stroke-width最后一行缩放这些; 高度为"4"时,最终图纸(4×5)的宽度为20个单位.refX并refY定义将形状放在路径末端时"原点"的位置
refX="0.1"确保标记略微重叠在线的末端fill-opacity和stroke-opacity标记和/或线的独立,但更改opacity的行会影响画的标记,也是如此.
fill-opacity标记,您将看到重叠; 但是,如果你降低opacity线本身,那么标记在线上合成完全不透明,然后两者的组合在不透明度下降低.
如果您想沿着线的长度使用箭头,则需要使用沿线的marker-mid="…"任一个<path>或<polyline>中间点.

唯一的问题是任何改变方向的点会弄乱方向 ; 这就是为什么在演示中我使用Bézier曲线绕过角落,使得线上的中点沿着直线部分.
<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>?
Run Code Online (Sandbox Code Playgroud)
为了在程序上执行此操作,您可以使用JavaScript和getPointAtLength()命令来路径来对路径进行采样.
只想添加一些有用的链接和示例:
文档:https : //developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Paths
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<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'>
<!-- triangle pointing right (+x) -->
<path d='M0,0 V4 L2,2 Z' fill="black"/>
</marker>
</defs>
<path
id='arrow-line'
marker-end='url(#head)'
stroke-width='1'
fill='none' stroke='black'
d='M0,0 Q45,-20 90,0'
/>
<path
id='arrow-line'
marker-end='url(#head)'
stroke-width='1'
fill='none' stroke='black'
d='M0,50 C10,30 80,30 90,50'
/>
</svg>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
63783 次 |
| 最近记录: |