下面是您可以运行的代码,并查看输出,该输出是黑色线,其末端位置带有标记。
<svg width="600px" height="200px">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refx="0" refy="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
</marker>
</defs>
<line x1="50" y1="50" x2="250" y2="150" stroke="#000" stroke-width="5" marker-end="url(#arrow)" />
</svg>
答案 0 :(得分:1)
您唯一需要做的就是使用以下公式来获得红色圆圈的正确位置(所以箭头的终点):
this.point.x = r * Math.cos(rad) + this.line.endX;
this.point.y = r * Math.sin(rad) + this.line.endY;
基本上对于位置x:
posX = arrowSizeX[width of the arrow * line stroke width] * Math.cos(rad)[rad = angle of the line in radian] + lineEndX[Position of the starting point of the arrow]
以下完整代码:( JSFiddle )
var vue = new Vue({
el: '#container',
data: {
svg: {
width: 400,
height: 200
},
line: {
startX: 50,
startY: 50,
endX: 250,
endY: 150
},
point: {
x: 0,
y: 0
},
arrow: {
sizeX: 9,
sizeY: 6
},
strokeWidth: 5
},
ready: function() {
this.calculatePosition();
},
methods: {
calculatePosition: function() {
// Calculate the angle of the arrow in radian
var rad = Math.atan2(this.line.endY - this.line.startY, this.line.endX - this.line.startX);
// Calculate the radius (the length of the arrow)
// Note: Your arrow size depends on the the 'strokeWidth' attribute of your line
var r = this.arrow.sizeX * this.strokeWidth;
// Calculate the position of the point
this.point.x = r * Math.cos(rad) + this.line.endX;
this.point.y = r * Math.sin(rad) + this.line.endY;
}
}
});
vue.$watch('arrow.sizeX', vue.calculatePosition);
vue.$watch('arrow.sizeY', vue.calculatePosition);
vue.$watch('line.startX', vue.calculatePosition);
vue.$watch('line.startY', vue.calculatePosition);
vue.$watch('line.endX', vue.calculatePosition);
vue.$watch('line.endY', vue.calculatePosition);
vue.$watch('strokeWidth', vue.calculatePosition);
input,
label,
button {
display: block;
}
#toolbar {
display: inline-block;
width: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<div id="container">
<div id="toolbar">
<label>Arrow size x:</label>
<input type="range" min="1" max="10" v-model="arrow.sizeX" v-on:change="calculatePosition()" />
<label>Arrow size y:</label>
<input type="range" min="1" max="10" v-model="arrow.sizeY" />
<label>Line start x:</label>
<input type="range" min="0" max="{{svg.width}}" v-model="line.startX" />
<label>Line start y:</label>
<input type="range" min="0" max="{{svg.height}}" v-model="line.startY" />
<label>Line end x:</label>
<input type="range" min="0" max="{{svg.width}}" v-model="line.endX" />
<label>Line end y:</label>
<input type="range" min="0" max="{{svg.height}}" v-model="line.endY" />
<label>Stroke width:</label>
<input type="range" min="1" max="10" v-model="strokeWidth" />
</div>
<svg width="{{svg.width}}" height="{{svg.height}}">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refx="0" refy="{{arrow.sizeY / 2}}" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,{{arrow.sizeY}} L{{arrow.sizeX}},{{arrow.sizeY / 2}} z" fill="#000" />
</marker>
</defs>
<circle cx="{{point.x}}" cy="{{point.y}}" r="3" fill="red"></circle>
<line x1="{{line.startX}}" y1="{{line.startY}}" x2="{{line.endX}}" y2="{{line.endY}}" stroke="#000" stroke-width="{{strokeWidth}}" marker-end="url(#arrow)" />
</svg>
</div>