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() {
var rad = Math.atan2(this.line.endY - this.line.startY, this.line.endX - this.line.startX);
var r = this.arrow.sizeX * this.strokeWidth;
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>