Javascript 带修改点的箭头

Javascript 带修改点的箭头,javascript,html5-canvas,Javascript,Html5 Canvas,嗨,我想复制一种效果。当你画一个箭头时,它在箭头中间显示一个蓝色点,允许你在两条线之间创建角度,它显示两个蓝色点,允许你用两条新的线做同样的操作。我已经添加了下面的图片。这样更容易理解。 我想知道如何动态地编码这些蓝点,以允许“中断”线路 var ctx=tempcanvas.getContext('2d'), mainctx=canvas.getContext('2d'), w=画布宽度, h=画布高度, x1, y1, isDown=假; ctx.translate(0.5,0.5);

嗨,我想复制一种效果。当你画一个箭头时,它在箭头中间显示一个蓝色点,允许你在两条线之间创建角度,它显示两个蓝色点,允许你用两条新的线做同样的操作。我已经添加了下面的图片。这样更容易理解。 我想知道如何动态地编码这些蓝点,以允许“中断”线路

var ctx=tempcanvas.getContext('2d'),
mainctx=canvas.getContext('2d'),
w=画布宽度,
h=画布高度,
x1,
y1,
isDown=假;
ctx.translate(0.5,0.5);
tempcanvas.onmousedown=函数(e){
var rect=canvas.getBoundingClientRect();
x1=e.clientX-右左;
y1=e.clientY-rect.top;
isDown=真;
}
tempcanvas.onmouseup=函数(){
isDown=假;
mainctx.drawImage(tempcanvas,0,0);
ctx.clearRect(0,0,w,h);
}
tempcanvas.onmousemove=函数(e){
如果(!isDown)返回;
var rect=canvas.getBoundingClientRect(),
x2=e.clientX-右左,
y2=e.clientY-rect.top;
var p0={x1,y1};
var p1={x2,y2};
ctx.clearRect(0,0,w,h);
带箭头的抽绳(p0、p1、25);
}
带箭头的功能绘图线(p0、p1、头长){
var-PI=Math.PI;
变化率径向225=225*PI/180;
变化率半径135=135*PI/180;
var dx=p1.x2-p0.x1;
var dy=p1.y2-p0.y1;
变量角度=数学常数2(dy,dx);
//计算箭头点
var x225=p1.x2+头长*数学系数(角度+度数半径225);
变量y225=p1.y2+头长*数学正弦(角度+度数半径225);
var x135=p1.x2+头长*数学系数(角度+度数半径135);
变量y135=p1.y2+头长*数学正弦(角度+度数半径135);
ctx.beginPath();
//从p0到p1画一条线
ctx.moveTo(p0.x1,p0.y1);
ctx.lineTo(p1.x2,p1.y2);
//在225度处绘制局部箭头
ctx.moveTo(p1.x2,p1.y2);
ctx.lineTo(x225,y225);
//在135度处绘制局部箭头
ctx.moveTo(p1.x1,p1.y1);
ctx.lineTo(x135,y135);
//画线和箭头
ctx.stroke();
}
canvas{位置:绝对;左侧:0;顶部:0}
#画布{背景:#eef}

示例代码段 抱歉,没有时间(周末和所有时间)编写详细的解释,没有必要浪费代码,所以希望它能有所帮助

const ctx=canvas.getContext(“2d”);
ctx.bounds=canvas.getBoundingClientRect();
常数P2=(x=0,y=0)=>({x,y});
常数点=[];
const lineStyle=“#000”;
常量nearLineStyle=“#0AF”;
常数线宽=2;
常数nearLineWidth=3;
const pointStyle=“#000”;
const nearPointStyle=“#0AF”;
常量pointLineWidth=1;
常数nearPointLineWidth=2;
常数arrowSize=18;
常量pointSize=5;
常数nearPointSize=15;
常量checkerSize=256;//二次幂
const checkerCol1=“#CCC”;
常量checkerCol2=“#EEE”;
const MIN_SELECT_DIST=20;//以像素为单位;
var w=canvas.width,h=canvas.height;
var cw=w/2,ch=h/2;
var cursor=“default”;
var工具提示=”;
常量鼠标={x:0,y:0,按钮:0};
常量拖动={拖动:false};
requestAnimationFrame(更新);
功能鼠标事件(e){
mouse.x=e.pageX-ctx.bounds.left-scrollX;
mouse.y=e.pageY-ctx.bounds.top-scrollY;
如果(e.type==“mousedown”){mouse.button |=1{
常数s=checkerSize,s2=s/2;
const c=document.createElement(“画布”);
c、 高度=c.宽度=复选框大小;
const ctx=c.getContext(“2d”,{alpha:false});
ctx.fillStyle=checkerCol1;
ctx.fillRect(0,0,s,s);
ctx.fillStyle=checkerCol2;
ctx.fillRect(0,0,s2,s2);
ctx.fillRect(s2,s2,s2,s2);
ctx.globalAlpha=0.25;
var-ss=s2;
而(ss>8){
ctx.fillStyle=ctx.createPattern(c,“重复”);
ctx.setTransform(1/8,0,0,1/8,0,0);
ctx.fillRect(0,0,s*8,s*8);
ss/=2;
}
返回ctx.createPattern(c,“repeat”);
})();
函数nearestPointLine(点,点,mindsist){//用最近的点和线到点填充最近的对象(如果在mindsist内)。
变量i=0,p1,距离;
最近的。重置(心灵主义者);
常数v1=P2();
常数v2=P2();
常数v3=P2();
用于(点的常数){
v2.x=点x-p.x;
v2.y=点y-p.y;
dist=(v2.x*v2.x+v2.y*v2.y)**0.5;
if(距离<最近点距离){
最近点距离=距离;
最近点p=p;
最近的.point.idx=i;
}           
如果(p1){
v1.x=p1.x-p.x;
v1.y=p1.y-p.y;
v2.x=点x-p.x;
v2.y=点y-p.y;
常数u=(v2.x*v1.x+v2.y*v1.y)/(v1.y*v1.y+v1.x*v1.x);
如果(u>=0&&u-1&&nearest.point.dist/2-1){
最近的.active=最近的.line;
nearest.near=true;
}
}
功能抽绳(p1、p2){
ctx.moveTo(p1.x,p1.y);
ctx.lineTo(p2.x,p2.y);
}
功能绘图线箭头(p1、p2){
var nx=p1.x-p2.x;
var ny=p1.y-p2.y;
常数d=(nx*nx+ny*ny)**0.5;
如果(d>箭头大小){
nx/=d;
ny/=d;
setTransform(-nx,-ny,ny,-nx,p2.x,p2.y);
ctx.beginPath()
ctx.fillStyle=ctx.strokeStyle;
ctx.moveTo(0,0);
ctx.lineTo(-arrowSize,arrowSize/2);
ctx.lineTo(-arrowSize,-arrowSize/2);
ctx.fill();
setTransform(1,0,0,1,0,0);
}
}
函数绘图点(p,大小=点大小){
ctx.rect(p.x-尺寸/2,p.y-尺寸/2,尺寸,尺寸);
}
功能抽绳(点){
var-p1;
ctx.strokeStyle=线型;
ctx.lineWidth=线宽;
ctx.beginPath()
用于(点的常数){
if(p1){抽绳(p1,p)}
p1=p;
}
ctx.stroke();
如果(点长度>1){
拉线箭头(点[点.长度-2],p1);
}
}
功能提取点(点){
ctx.strokeStyle=点样式;
ctx.lineWidth=点线宽;
ctx.beginPath()
对于(点的常数){draw