Angular中Blockly外部拖拽方块至工作区的坐标转换问题求助
解决Blockly外部拖拽方块坐标转换问题
你的问题出在坐标转换的手动计算逻辑和方块移动方式上,以下是具体修正方案:
核心问题分析
- 手动计算工作区坐标时,错误处理了SVG坐标与工作区滚动、偏移的关系,Blockly已提供封装好的坐标转换工具,无需自行计算。
- 新创建的方块初始位置并非固定(0,0),使用
moveBy会基于初始位置叠加偏移,导致落点偏差。
修正后的代码
addSelectedFunctionBlockInWorkspace(event: any, blockConfig: any) { const dynamicBlock = this.blocklyWorkSpace.newBlock('fn_' + blockConfig.functionId + '_1'); dynamicBlock.initSvg(); this.moveDynamicBlock(event, dynamicBlock); dynamicBlock.render(); } moveDynamicBlock(event: any, dynamicBlock: any) { // 提取CDK拖拽事件的客户端坐标 const clientX = event.dropPoint.x; const clientY = event.dropPoint.y; // 用Blockly内置工具直接转换为工作区坐标 const workspaceCoords = Blockly.utils.svgCoordinates.clientToWorkspace( clientX, clientY, this.blocklyWorkSpace ); let targetX = workspaceCoords.x; let targetY = workspaceCoords.y; // 保留你的位置占用检查逻辑 const allBlocks = this.blocklyWorkSpace.getAllBlocks(); while (!this.isPositionEmpty(targetX, targetY, allBlocks)) { targetX += 10; targetY += 20; } // 用moveTo直接定位到目标坐标,替代moveBy的相对移动 dynamicBlock.moveTo(targetX, targetY); }
关键修正点
- 使用
Blockly.utils.svgCoordinates.clientToWorkspace:该方法自动处理SVG到工作区的坐标转换,涵盖滚动偏移、缩放等场景,避免手动计算出错。 - 替换
moveBy为moveTo:moveBy是相对当前位置移动,新方块初始位置不确定;moveTo直接将方块定位到目标工作区坐标,结果更准确。 - 确认坐标有效性:确保CDK的
event.dropPoint是浏览器客户端坐标(相对于视口的坐标),若不是需先转换为客户端坐标再传入工具方法。
如果你的Blockly版本较旧,没有Blockly.utils.svgCoordinates,可以用以下手动转换方案替代:
const svgPoint = this.blocklyWorkSpace.getParentSvg().createSVGPoint(); svgPoint.x = clientX; svgPoint.y = clientY; // 将客户端坐标转换为SVG坐标 const svgCoords = svgPoint.matrixTransform(this.blocklyWorkSpace.getParentSvg().getScreenCTM().inverse()); // 转换为工作区坐标 const workspaceX = svgCoords.x - this.blocklyWorkSpace.getMetrics().viewLeft - this.blocklyWorkSpace.scrollX; const workspaceY = svgCoords.y - this.blocklyWorkSpace.getMetrics().viewTop - this.blocklyWorkSpace.scrollY;
内容的提问来源于stack exchange,提问作者ARULSARAVANAN B
相关产品推荐
相关产品推荐

