2016-07-06 55 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>