2016-07-06 23 views
2

下面是你可以运行的代码,看到输出是一个带有标记的黑色线条的末端位置。如何获得svg中的标记结束位置?

<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>

我想知道其是否是能够计算的标记结束位置的值作为所示的图像在下面enter image description here与红色的圆,其由箭头指出在红颜色? 是否可以用数学方法计算标记结束的位置?

+0

我不知道理解正确。你想在箭头的末尾添加一个红色圆圈?或者你想让箭头指向圆圈而不重叠?在第二种情况下,这是一个固定的图像?或者你有用户交互?因为如果它只是一个固定的图像,那么我会说我的第一个案例。那个红圈从哪里来?它是否修复?详情请=) – Elfayer

+0

@Elfayer我想知道黑色线的终点位置(x,y位置),在终点位置有一个标记(三角形)(即我用红色圆圈标记的点。 )。请参阅代码输出和图像。 –

+0

我更新了我的答案,我终于找到了解决方案=) – Elfayer

回答

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>