箭头线
vue+uni-app+canvas 画带箭头可拖动的线段
<template><div><canvas ref="canvas" class="canvas" width="600px" height="400px" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas></div>
</template><script>
export default {data() {return {drawing: false,context: null,startX: 0,startY: 0,endX: 0,endY: 0};},mounted() {this.initializeCanvas();},methods: {initializeCanvas() {this.context = this.$refs.canvas.getContext('2d');this.context.strokeStyle = 'red';this.context.lineWidth = 2;this.context.strokeRect(300, 150, 10, 100);},startDrawing(event) {this.drawing = true;let rect = this.$refs.canvas.getBoundingClientRect()this.startX = event.clientX - rect.left;this.startY = event.clientY - rect.top;},draw(event) {if (!this.drawing) return;let rect = this.$refs.canvas.getBoundingClientRect()this.endX = event.clientX - rect.left;this.endY = event.clientY - rect.top;this.clearCanvas();this.drawLineArrow(this.context, this.startX, this.startY, this.endX, this.endY);},stopDrawing() {this.drawing = false;this.clearCanvas();this.startX = 0this.startY = 0this.endX = 0this.endY = 0},clearCanvas() {this.context.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height);},drawArrowLine(startX, startY, endX, endY) {this.context.beginPath();this.context.moveTo(startX, startY);this.context.lineTo(endX, endY);const angle = Math.atan2(endY - startY, endX - startX);const arrowSize = 10;this.context.lineTo(endX - arrowSize * Math.cos(angle - Math.PI / 6), endY - arrowSize * Math.sin(angle - Math.PI / 6));this.context.moveTo(endX, endY);this.context.lineTo(endX - arrowSize * Math.cos(angle + Math.PI / 6), endY - arrowSize * Math.sin(angle + Math.PI / 6));this.context.stroke();},drawLineArrow(ctx, fromX, fromY, toX, toY) {var headlen = 0.2 * 1.41 * Math.sqrt((fromX - toX) * (fromX - toX) + (fromY - toY) * (fromY - toY));headlen = headlen > 40 ? 40 : headlen;var theta = 30;var arrowX, arrowY;var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI;var angle1 = (angle + theta) * Math.PI / 180;var angle2 = (angle - theta) * Math.PI / 180;var topX = headlen * Math.cos(angle1);var topY = headlen * Math.sin(angle1);var botX = headlen * Math.cos(angle2);var botY = headlen * Math.sin(angle2);var toLeft = fromX > toX;var toUp = fromY > toY;arrowX = toX + topX;arrowY = toY + topY;var arrowX1 = toX + botX;var arrowY1 = toY + botY;var arrowX2 = toUp ? arrowX + 0.25 * Math.abs(arrowX1 - arrowX) : arrowX - 0.25 * Math.abs(arrowX1 - arrowX);var arrowY2 = toLeft ? arrowY - 0.25 * Math.abs(arrowY1 - arrowY) : arrowY + 0.25 * Math.abs(arrowY1 - arrowY);var arrowX3 = toUp ? arrowX + 0.75 * Math.abs(arrowX1 - arrowX) : arrowX - 0.75 * Math.abs(arrowX1 - arrowX);var arrowY3 = toLeft ? arrowY - 0.75 * Math.abs(arrowY1 - arrowY) : arrowY + 0.75 * Math.abs(arrowY1 - arrowY);ctx.beginPath();ctx.moveTo(fromX, fromY);ctx.lineTo(arrowX2, arrowY2);ctx.lineTo(arrowX, arrowY);ctx.lineTo(toX, toY);ctx.lineTo(arrowX1, arrowY1);ctx.lineTo(arrowX3, arrowY3);ctx.lineTo(fromX, fromY);ctx.closePath();ctx.strokeStyle = "#FB8978";ctx.fillStyle = "rgba(255,197,179,0.3)";ctx.fill();ctx.stroke();}}
};
</script><style scoped>
.canvas {background: #ccc;
}
</style>