如何修复变换后div中DOM元素点击位置偏移问题
解决点击位置与添加符号偏移的问题
问题出在点击事件里的坐标计算逻辑,没有正确对应#node-container的缩放和平移变换,导致符号位置偏移。下面是修正方案:
核心修改思路
把鼠标的屏幕坐标转换为node-container的本地坐标系坐标:
- 先算出鼠标相对于
canvas内部的坐标 - 结合当前的缩放比例和平移量,反向计算出符号在
node-container里的绝对定位位置
修正后的代码
let canvas = document.getElementById('canvas'); let nodeContainer = document.getElementById('node-container'); let pz = { offset: { x: 0.0, y: 0.0 }, zoom: 1 }; let isDragging = false; let c = 0; // pan and zoom const updateDom = () => { let x = pz.offset.x * pz.zoom +'px'; let y = pz.offset.y * pz.zoom +'px'; let z = pz.zoom; nodeContainer.style.transform = `translate(${x}, ${y}) scale(${z})` } const handleMouseDown = () => { isDragging = true; }; const handleMouseUp = () => { isDragging = false; }; const handleMouseMove = (e) => { if (!isDragging) { return; } if (e.buttons !== 1) { isDragging = false; return; } pz.offset = { x: pz.offset.x + e.movementX / pz.zoom, y: pz.offset.y + e.movementY / pz.zoom }; updateDom(); }; const handleWheel = (e) => { e.preventDefault(); e.stopPropagation(); if (e.ctrlKey) { const speedFactor = (e.deltaMode === 1 ? 0.05 : e.deltaMode ? 1 : 0.002) * 10; const pinchDelta = -e.deltaY * speedFactor; pz.zoom = Math.min( 1.3, Math.max(0.1, pz.zoom * Math.pow(2, pinchDelta)) ) } updateDom(); } canvas.onwheel = handleWheel; canvas.onmousedown = handleMouseDown; canvas.onmouseup = handleMouseUp; canvas.onmousemove = handleMouseMove; // 修正后的点击事件逻辑 canvas.addEventListener('click', (e) => { // 获取canvas的屏幕位置 const canvasRect = canvas.getBoundingClientRect(); // 计算鼠标相对于canvas内部的坐标 const mouseXInCanvas = e.clientX - canvasRect.left; const mouseYInCanvas = e.clientY - canvasRect.top; // 转换为node-container本地坐标系的坐标 const localX = (mouseXInCanvas - pz.offset.x * pz.zoom) / pz.zoom; const localY = (mouseYInCanvas - pz.offset.y * pz.zoom) / pz.zoom; let marker = document.createElement('span'); marker.innerText = '+' marker.style.fontSize = '19pt'; marker.style.position = 'absolute'; marker.style.left = `${localX}px`; marker.style.top = `${localY}px`; nodeContainer.appendChild(marker); });
<script src="https://cdn.tailwindcss.com"></script> <div class="grid grid-cols-2 divide-x"> <div id="canvas" class="relative h-screen bg-gray-100"> <div id="container" class="absolute origin-top-left w-0 h-0 overflow-visible"> <div id="node-container" class="absolute w-0 h-0 overflow-visible"></div> <!-- end of #node-container --> </div> <!-- end of #container --> </div> <!-- end of canvas & left col --> <div> </div> <!-- end of right col --> </div>
内容的提问来源于stack exchange,提问作者codeX
相关产品推荐
相关产品推荐

