Javascript Konva.js:[自由绘制&拖动&缩放]在拖动或缩放后无法使用指针正确绘制
欢迎任何讨论。谢谢你的阅读 我想做什么 我正在尝试使用Konva.js实现简单的paperwhiteboard 到目前为止,我已经实现了在纸上拖动、缩放和自由绘图 我提到 用于缩放 免费绘画 我只想在米色背景的区域上绘制,并且我想在指针下精确绘制,即使它被缩放或拖动 但是,自由绘图和拖动和缩放功能不能很好地协同工作 缺陷 拖动或缩放后无法正确绘制 我认为错误的事情正在发生,但无法修复 我认为下面两部分有问题 缩放的实现 如何在绘图实现中使用stage.getPointerPosition 或者这两者的实现不适合在一起 密码 最低代码在这里 /*-模式管理-*/ 让modeSelector=document.getElementById'mode-selector'; let mode=modeSelector.value; modeSelector.addEventListener'change',=>{ //旧模式使用的Discead事件处理程序 开关模式{ 案例“手”:{ 尾端; 打破 } “笔”一案:{ endPen; 打破 } } //为新模式设置事件处理程序 mode=modeSelector.value; 开关模式{ 案例“手”:{ 二手货; 打破 } “笔”一案:{ usePen; 打破 } } }; /*-Konva对象-*/ 让舞台=新康瓦舞台{ 容器:'容器', 宽度:window.innerWidth, 高度:window.innerHeight }; //仅用于背景色的图层 让backgroundLayer=新Konva.Layer; 让backgroundColor=新Konva.Image{ 宽度:window.innerWidth, 高度:window.innerHeight, 填充:“RGB242233226” } backgroundLayer.addbackgroundColor; stage.addbackgroundLayer; backgroundLayer.draw; //用于自由绘制的图层 设drawLayer=新Konva.Layer; stage.adddrawLayer; /*-模式转换功能--*/ 常用函数{ //使舞台拖拉 stage.draggabletrue; //使舞台可缩放 //***代码是从中复制和粘贴的 // *** https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.htmlhttps://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.html 设scaleBy=1.3; 舞台。在“轮子”上,evt=>{ evt.evt.preventDefault; 设oldScale=stage.scaleX; 让mousepointo={ x:stage.getPointerPosition.x/oldScale-stage.x/oldScale, y:stage.getPointerPosition.y/oldScale-stage.y/oldScale }; 让newScale=evt.evt.deltaY>0?oldScale*scaleBy:oldScale/scaleBy; stage.scale{x:newScale,y:newScale}; 设newPos={ x:-mousepointo.x-stage.getPointerPosition.x/newScale*newScale, y:-mousepointo.y-stage.getPointerPosition.y/newScale*newScale }; stage.positionnewPos; 第二阶段:抽签; }; } 功能结束{ stage.draggablefalse; 舞台。脱离“轮子”; } 函数usePen{ 让isDrawing=false; 让电流线; 舞台。在“mousedown”上,evt=>{ //开始绘图 isDrawing=true; //创建新线对象 设pos=stage.getPointerPosition; currentLine=新的Konva.Line{ 笔画:“黑色”, 冲程宽度:3, 点数:[位置x,位置y] }; drawLayer.addcurrentLine; }; stage.on'mousemove',evt=>{ 如果!正在绘制{ 回来 } //如果是图形,请向当前直线对象添加新点 设pos=stage.getPointerPosition; 设newPoints=currentLine.points.concat[pos.x,pos.y]; currentLine.points新点; drawLayer.batchDraw; }; 舞台上的“鼠标”,evt=>{ //端部拉深 isDrawing=false; }; } 函数结束笔{ 舞台。离开“鼠标镇; 舞台。离“老鼠洞”远点; 舞台。离“鼠标”远点; } /*-初始化-*/ 二手货; 纸张 手 笔 -> stage.getPointerPosition返回画布容器左上角指针相关的绝对位置 在变换、移动和缩放舞台时,需要找到相对位置,以便将其用于线条 演示如何执行此操作: 函数GetRelativePositionNode{ //函数将返回指针相对于所传递节点的位置 var transform=node.getAbsoluteTransform.copy; //为了检测相对位置,我们需要反转变换 变换。反转; //让指针说出鼠标或触摸位置 var pos=node.getStage.getPointerPosition; //现在我们找到一个相对点 返回transform.pointpos; } /*-模式管理-*/ 让modeSelector=document.getElementById'mode-selector'; let mode=modeSelector.value; modeSelector.addEventListener'change',=>{ //旧模式使用的Discead事件处理程序 开关模式{ 案例“手”:{ 尾端; 打破 } “笔”一案:{ endPen; 打破 } } //为新模式设置事件处理程序 mode=modeSelector.value; 开关模式{ 案例“手”:{ 二手货; 打破 } “笔”一案:{ usePen; 打破 } } }; /*-Konva对象-*/ 让舞台=新康瓦舞台{ 容器:'容器', 宽度:window.innerWidth, 高度:window.innerHeight }; //仅用于背景色的图层 让backgroundLayer=新Konva.Layer; 让backgroundColor=新Konva.Image{ 宽度:window.innerWidth, 高度:window.innerHeight, 填充:“RGB242233226” } backgroundLayer.addbackgroundColor; stage.addbackgroundLayer; backgroundLayer.draw; //用于自由绘制的图层 设drawLayer=新Konva.Layer; stage.adddrawLayer; /*-模式转换功能--*/ 常用函数{ //使舞台拖拉 stage.draggabletrue; //使舞台可缩放 //***代码是从中复制和粘贴的 // *** https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.htmlhttps://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.html 设scaleBy=1.3; 舞台。在“轮子”上,evt=>{ evt.evt.preventDefault; 设oldScale=stage.scaleX; 让mousepointo={ x:stage.getPointerPosition.x/oldScale-stage.x/oldScale, y:stage.getPointerPosition.y/oldScale-stage.y/oldScale }; 让newScale=evt.evt.deltaY>0?oldScale*scaleBy:oldScale/scaleBy; stage.scale{x:newScale,y:newScale}; 设newPos={ x:-mousepointo.x-stage.getPointerPosition.x/newScale*newScale, y:-mousepointo.y-stage.getPointerPosition.y/newScale*newScale }; stage.positionnewPos; 第二阶段:抽签; }; } 功能结束{ stage.draggablefalse; 舞台。脱离“轮子”; } 函数GetRelativePositionNode{ //函数将返回指针相对于所传递节点的位置 var transform=node.getAbsoluteTransform.copy; //为了检测相对位置,我们需要反转变换 变换。反转; //让指针说出鼠标或触摸位置 var pos=node.getStage.getPointerPosition; //现在我们找到相对点 返回transform.pointpos; } 函数usePen{ 让isDrawing=false; 让电流线; 舞台。在“mousedown”上,evt=>{ //开始绘图 isDrawing=true; //创建新线对象 设pos=GetRelativePositionStage; currentLine=新的Konva.Line{ 笔画:“黑色”, 冲程宽度:3, 点数:[位置x,位置y] }; drawLayer.addcurrentLine; }; stage.on'mousemove',evt=>{ 如果!正在绘制{ 回来 } //如果是图形,请向当前直线对象添加新点 设pos=GetRelativePositionStage; 设newPoints=currentLine.points.concat[pos.x,pos.y]; currentLine.points新点; drawLayer.batchDraw; }; 舞台上的“鼠标”,evt=>{ //端部拉深 isDrawing=false; }; } 函数结束笔{ 舞台。离开“鼠标镇; 舞台。离“老鼠洞”远点; 舞台。离“鼠标”远点; } /*-初始化-*/ 二手货; 纸张 手 笔 -> stage.getPointerPosition返回画布容器左上角指针相关的绝对位置 在变换、移动和缩放舞台时,需要找到相对位置,以便将其用于线条 演示如何执行此操作: 函数GetRelativePositionNode{ //函数将返回指针相对于所传递节点的位置 var transform=node.getAbsoluteTransform.copy; //为了检测相对位置,我们需要反转变换 变换。反转; //让指针说出鼠标或触摸位置 var pos=node.getStage.getPointerPosition; //现在我们找到一个相对点 返回transform.pointpos; } /*-模式管理-*/ 让modeSelector=document.getElementById'mode-selector'; let mode=modeSelector.value; modeSelector.addEventListener'change',=>{ //旧模式使用的Discead事件处理程序 开关模式{ 案例“手”:{ 尾端; 打破 } “笔”一案:{ endPen; 打破 } } //为新模式设置事件处理程序 mode=modeSelector.value; 开关模式{ 案例“手”:{ 二手货; 打破 } “笔”一案:{ usePen; 打破 } } }; /*-Konva对象-*/ 让舞台=新康瓦舞台{ 容器:'容器', 宽度:window.innerWidth, 高度:window.innerHeight }; //仅用于背景色的图层 让backgroundLayer=新Konva.Layer; 让backgroundColor=新Konva.Image{ 宽度:window.innerWidth, 高度:window.innerHeight, 填充:“RGB242233226” } backgroundLayer.addbackgroundColor; stage.addbackgroundLayer; backgroundLayer.draw; //用于自由绘制的图层 设drawLayer=新Konva.Layer; stage.adddrawLayer; /*-模式转换功能--*/ 常用函数{ //使舞台拖拉 stage.draggabletrue; //使舞台可缩放 //***代码是从中复制和粘贴的 // *** https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.htmlhttps://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.html 设scaleBy=1.3; 阶段 .在“方向盘”上,evt=>{ evt.evt.preventDefault; 设oldScale=stage.scaleX; 让mousepointo={ x:stage.getPointerPosition.x/oldScale-stage.x/oldScale, y:stage.getPointerPosition.y/oldScale-stage.y/oldScale }; 让newScale=evt.evt.deltaY>0?oldScale*scaleBy:oldScale/scaleBy; stage.scale{x:newScale,y:newScale}; 设newPos={ x:-mousepointo.x-stage.getPointerPosition.x/newScale*newScale, y:-mousepointo.y-stage.getPointerPosition.y/newScale*newScale }; stage.positionnewPos; 第二阶段:抽签; }; } 功能结束{ stage.draggablefalse; 舞台。脱离“轮子”; } 函数GetRelativePositionNode{ //函数将返回指针相对于所传递节点的位置 var transform=node.getAbsoluteTransform.copy; //为了检测相对位置,我们需要反转变换 变换。反转; //让指针说出鼠标或触摸位置 var pos=node.getStage.getPointerPosition; //现在我们找到相对点 返回transform.pointpos; } 函数usePen{ 让isDrawing=false; 让电流线; 舞台。在“mousedown”上,evt=>{ //开始绘图 isDrawing=true; //创建新线对象 设pos=GetRelativePositionStage; currentLine=新的Konva.Line{ 笔画:“黑色”, 冲程宽度:3, 点数:[位置x,位置y] }; drawLayer.addcurrentLine; }; stage.on'mousemove',evt=>{ 如果!正在绘制{ 回来 } //如果是图形,请向当前直线对象添加新点 设pos=GetRelativePositionStage; 设newPoints=currentLine.points.concat[pos.x,pos.y]; currentLine.points新点; drawLayer.batchDraw; }; 舞台上的“鼠标”,evt=>{ //端部拉深 isDrawing=false; }; } 函数结束笔{ 舞台。离开“鼠标镇; 舞台。离“老鼠洞”远点; 舞台。离“鼠标”远点; } /*-初始化-*/ 二手货; 纸张 手 笔 ->Javascript Konva.js:[自由绘制&拖动&缩放]在拖动或缩放后无法使用指针正确绘制,javascript,konvajs,Javascript,Konvajs,欢迎任何讨论。谢谢你的阅读 我想做什么 我正在尝试使用Konva.js实现简单的paperwhiteboard 到目前为止,我已经实现了在纸上拖动、缩放和自由绘图 我提到 用于缩放 免费绘画 我只想在米色背景的区域上绘制,并且我想在指针下精确绘制,即使它被缩放或拖动 但是,自由绘图和拖动和缩放功能不能很好地协同工作 缺陷 拖动或缩放后无法正确绘制 我认为错误的事情正在发生,但无法修复 我认为下面两部分有问题 缩放的实现 如何在绘图实现中使用stage.getPointerPosition 或者这
谢谢!此解决方案解决了指针位置问题!但目前,似乎有可能在米色区域之外绘制。我如何缩放舞台的宽度和高度,以便在缩放时舞台的大小与米色区域的大小完全相等?我希望只能在米色区域上绘图。因为米色区域是模拟纸张的区域。我们不能在纸的外面画画。最好有两层:一层是书桌层,另一层是纸层。纸层在桌子层上。然后,我们可以通过拖动桌面层上的任意位置来移动纸张层,也可以通过鼠标滚轮在桌面层上的任意位置缩放纸张层。而且,任何时候我们只能在纸层上画画。嘿,我自己解决了这个问题。我选择使用组而不是图层进行绘图。通过将背景图像设置为组,我可以检测鼠标指针是否位于组上,并且使用您告诉我的函数计算指针相对于组的相对位置,从而可以在组上正确绘制!谢谢谢谢!此解决方案解决了指针位置问题!但目前,似乎有可能在米色区域之外绘制。我如何缩放舞台的宽度和高度,以便在缩放时舞台的大小与米色区域的大小完全相等?我希望只能在米色区域上绘图。因为米色区域是模拟纸张的区域。我们不能在纸的外面画画。最好有两层:一层是书桌层,另一层是纸层。纸层在桌子层上。然后,我们可以通过拖动桌面层上的任意位置来移动纸张层,也可以通过鼠标滚轮在桌面层上的任意位置缩放纸张层。而且,任何时候我们只能在纸层上画画。嘿,我自己解决了这个问题。我选择使用组而不是图层进行绘图。通过将背景图像设置为组,我可以检测鼠标指针是否位于组上,并且使用您告诉我的函数计算指针相对于组的相对位置,从而可以在组上正确绘制!谢谢