Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html5 canvas 带折弯的路线或路径标记解决方案_Html5 Canvas_Bezier_Curve_Konvajs - Fatal编程技术网

Html5 canvas 带折弯的路线或路径标记解决方案

Html5 canvas 带折弯的路线或路径标记解决方案,html5-canvas,bezier,curve,konvajs,Html5 Canvas,Bezier,Curve,Konvajs,我想为我的用户提供一种简单的方法,在地图或图片上直观地跟踪路线。解决方案必须允许用户添加控制点,以便他们可以使用这些控制点在路线中设置弯板 它应该与HTML5Canvas一起工作——我目前使用Konvajs库,所以使用它的解决方案是很好的 为了共享和学习的利益,如果你能建议使用其他HTML5画布库的解决方案,那也很好 注:这不是最初提出的问题。然而,随着时间的推移,人们发现这是实际的要求。OP要求提供在HTML5画布中沿直线/曲线部分查找任意点的方法,以便在该点添加可拖动的控制点以编辑直线/曲线

我想为我的用户提供一种简单的方法,在地图或图片上直观地跟踪路线。解决方案必须允许用户添加控制点,以便他们可以使用这些控制点在路线中设置弯板

它应该与HTML5Canvas一起工作——我目前使用Konvajs库,所以使用它的解决方案是很好的

为了共享和学习的利益,如果你能建议使用其他HTML5画布库的解决方案,那也很好

注:这不是最初提出的问题。然而,随着时间的推移,人们发现这是实际的要求。OP要求提供在HTML5画布中沿直线/曲线部分查找任意点的方法,以便在该点添加可拖动的控制点以编辑直线/曲线。公认的答案不符合这一需要。然而,这个原始问题的答案将涉及严重的碰撞检测数学和潜在的使用贝塞尔控制点-换句话说,这将是一个大问题,而接受的答案是一个非常接近的解决方案,具有一致的用户体验


原始问题可通过此问题下方的编辑链接查看。

这个想法如何。单击需要下一个点的位置,管线将使用新的定位操纵柄沿线段延伸。如果需要箭头,可以根据需要扩展此处的对象。您可以使用route类的属性轻松更改颜色、笔划宽度、圆形不透明度等。这些点在阵列和标准Konva.js线点列表中可用。JS是普通的,不需要或使用其他库

“导出”按钮显示如何获取(x,y)定点对象以进行导出

这里的示例视频,下面的代码片段中的工作代码

//设置画布/舞台
var s1=新的Konva.Stage({container:'container1',宽度:600,高度:300});
//为线条添加图层
var lineLayer=new Konva.Layer({draggable:false});
s1.添加(线图层);
//为拖动点添加图层
var pointLayer=new Konva.Layer({draggable:false});
s1.添加(点图层);
//将矩形添加到图层以捕获事件。让它半透明
var r=new Konva.Rect({x:0,y:0,宽度:600,高度:300,填充:“黑色”,不透明度:0.1})
pointLayer.add(r)
//一切都准备好了,所以绘制到目前为止设置的画布对象。
s1.绘图()
//通用画布末端
//可拖动点的类
//Params:route=父对象,opts=位置信息,doPush=我们应该创建它还是创建并存储它
var DragPoint=函数(路由、选项、doPush){
var-route=route;
this.x=opts.x;
this.y=opts.y;
this.fixed=opts.fixed;
this.id=randId();//随机id。
如果(doPush){//在某些情况下,我们希望创建pt,然后将其插入数组的运行中,而不总是在末尾
路线.点.推(本);
}
//随机id生成器
函数randId(){
返回Math.random();
}
//将pt标记为固定-重要状态,用填充点表示
this.makeFixed=函数(){
this.fixed=true;
s1.find(“#”+this.id)
.填充(路线.填充颜色);
}
this.kill=函数(){
s1.find(“#”+this.id)
.remove();
}
this.draw=函数(){
//添加点&pt
var circleId=this.id;
var pt=新Konva.圆({
id:circleId,
x:这个,
y:这个,y,
半径:route.pointRadius,
不透明度:route.pointOpacity,
冲程宽度:2,
笔划:route.strokeColor,
填充:'透明',
可拖动:“真的”
})
pt.on('dragstart',function(){
route.drawState='drawing';
})
pt.on('dragmove',函数(){
var pos=this.getPosition();
route.updatePt(this.id(),pos)
route.calc(this.id());
route.draw();
})
pt.on('dragend',function(){
route.drawState='drawing';
var pos=this.getPosition();
route.updatePt(this.getId(),pos);
route.splitPts(this.getId());
route.draw();
})
如果(此项已修复){
this.makeFixed();
}
路由.ptLayer.add(pt);
route.draw();
}  
}
var Route=function(){
this.lineLayer=null;
this.ptLayer=null;
this.drawState='';
this.fillColor='Gold';
this.strokeColor='Gold';
该点不透明度=0.5;
该点半径=10;
this.color='LimeGreen';
这个宽度=5;
this.pts=[];//拖动点数组。
this.startPt=null;
this.endPt=null;
//重置点
this.reset=函数(){
对于(变量i=0;i0){
此.splitPts(pt.id,true);
}    
this.startPt=this.endPt;//还记得最后一点吗
this.calc();//从数组计算线点
this.draw();//画线
}
//定位各点。
this.calc=函数(draggingId){
draggingId=(typeof draggingId=='undefined'?'--':draggingId);//拖动未填充的点时,必须覆盖其自动定位。
对于(变量i=1;i