2016-07-06 4 views
2

Unten ist der Code, den Sie ausführen können, und sehen Sie den Ausgang, der eine schwarze farbige Linie mit einem Marker an seiner Endposition ist.Wie bekomme ich die Marker-Endposition in 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>

Ich mag wissen, ob sie möglich ist, den Wert des Markers Endposition zu berechnen, wie im Bild unten enter image description here mit einem Kreis in roter Farbe dargestellt, die durch den Pfeil in rot spitz Farbe? Ist es mathematisch möglich, die Position des Markerendes zu berechnen?

+0

Ich bin nicht sicher, richtig zu verstehen. Sie möchten einen roten Kreis am Ende des Pfeils hinzufügen? Oder möchten Sie, dass der Pfeil auf den Kreis zeigt, ohne sich zu überlappen? Ist das im zweiten Fall ein fixiertes Bild? Oder haben Sie Benutzerinteraktionen? Denn wenn es nur ein fixiertes Bild ist, geht es in den ersten Fall, den ich angegeben habe. Woher kommt dieser rote Kreis? Ist es behoben? Details bitte =) – Elfayer

+0

@Elfayer Ich möchte die Position (x, y Position) des Endpunktes der schwarz gefärbten Linie mit einem Marker (Dreieck) an seiner Endposition kennen (dh der Punkt i ist mit einem roten Kreis markiert).). Bitte sehen Sie die Code-Ausgabe und das Bild. –

+0

Ich aktualisierte meine Antwort, ich fand schließlich die Lösung =) – Elfayer

Antwort

1

Das einzige, was Sie tun müssen, ist die folgenden Formeln verwenden, um die richtige Position des roten Kreises zu bekommen (so den Endpunkt des Pfeils):

this.point.x = r * Math.cos(rad) + this.line.endX; 
this.point.y = r * Math.sin(rad) + this.line.endY; 

Grundsätzlich für die Position 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]

Voll Code unten: (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>