箭头线
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 = 0
this . startY = 0
this . endX = 0
this . 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>